GPU在哪些统计方法上比CPU快?


18

我刚刚在台式机上安装了Nvidia GT660图形卡,经过一番挣扎,我设法将其与R接口。

我一直在玩几个使用GPU的R软件包,尤其是gputools,并且在比较我的GPU和CPU执行一些基本操作所花费的时间:

  • 求逆矩阵(CPU更快)
  • qr分解(CPU更快)
  • 大相关矩阵(CPU速度更快)
  • 矩阵乘法(GPU快得多!)

请注意,我主要是对gputools进行了实验,因此也许其他软件包的性能更好。

概括地说,我的问题是:哪些常规统计操作可能值得在GPU而不是CPU上执行?


1
什么涉及大量矩阵乘法?:) GPU在神经网络社区中非常流行。

您需要提供涉及的矩阵的大小。例如,我最后一次检查(肯定是在2年前),从大型矩阵(2 ^ 9乘以2 ^ 9及以上)开始,GPU上的反转和分解速度才更快
user189035 2013年

1
我使用大约的矩阵进行求逆,qr和矩阵乘法,而对于相关性,我使用了10 ^ 4个大小为100的向量的观测值。对于矩阵求逆,GPU要慢得多,而对于qr分解则要慢得多。速度较慢,但​​与CPU相当。103×103
Jugurtha

2
这是一个很好的问题,但是我认为通过将其迁移到stackoverflow(通过我认为之前已经问过类似的问题),您会得到更好的答案
user189035 2013年

2
GPU与常规CPU相比的优势在于它们可以“大规模”并行化,而不是每个内核速度更快。因此,对于需要大量“内务处理”的工作(例如Cholesky因式分解等),您需要使用块算法等来显着提高速度。这并非微不足道,我认为在GPU接管此类操作之前还需要一段时间。GPU方式肯定是MCMC-ing(和随机数生成)。从后验采样到处都写有“并行化”。他们已经被“阻止”了……
us11r说Reinstate Monic

Answers:


6

GPU是敏感的野兽。尽管从理论上说,英伟达最强大的显卡可以执行您列出的任何操作,而速度最快的CPU却要快100倍,但大约100万种 事情可以阻止这种提速。相关算法以及运行该算法的程序的每个部分都必须进行广泛的调整和优化,以使其接近理论上的最大加速。通常,R并不是一种特别快速的语言,因此,至少在原始性能方面,R的默认GPU实现并不那么出色,这也不足为奇。但是,R GPU功能可能具有优化设置,您可以对其进行调整,以重新获得某些缺少的性能。

如果您正在研究GPU,因为您发现需要运行一些计算将需要数周/数月才能完成,那么从R迁移到性能更友好的语言可能是值得的。使用Python并不比R难得多。NumPy和SciPy软件包具有与R相同的大多数stat函数,并且PyCuda可用于以相当简单的方式实现您自己的基于GPU的函数。

如果您确实想提高函数在GPU上运行的速度,我会考虑结合C ++和CUDA来实现自己的函数。CUBLAS库可用于处理所有与线性代数有关的繁重运算。但是,请记住,编写这样的代码可能需要花费相当长的时间(特别是如果这是您第一次这样做),因此,这种方法只应保留给那些运行时间非常长(几个月)并且/或您将重复数百次。


6

概括地说,在GPU上运行更快的算法就是您在许多不同的数据点上执行相同类型的指令的算法。

一个简单的例子就是矩阵乘法。

假设我们正在做矩阵计算

一种×=C

一个简单的CPU算法可能看起来像

//从C = 0开始

for (int i = 0; i < C_Width; i++)
{
    for (int j = 0; j < C_Height; j++)
    {
        for (int k = 0; k < A_Width; k++)
        {
            for (int l = 0; l < B_Height; l++)
            {
                C[j, i] += A[j, k] * B[l, i];
            }
        }
    }
}

在这里看到的关键是,有很多嵌套的for循环,并且每个步骤必须一个接一个地执行。

看这个图

请注意,C中每个元素的计算均不依赖于其他任何元素。因此,以什么顺序进行计算都没有关系。

因此,在GPU上,这些操作可以同时完成。

用于计算矩阵乘法的GPU内核看起来像

__kernel void Multiply
(
    __global float * A,
    __global float * B,
    __global float * C
)
{
     const int x = get_global_id(0);
     const int y = get_global_id(1);
     for (int k = 0; k < A_Width; k++)
     {
         for (int l = 0; l < B_Height; l++)
         {
             C[x, y] += A[x, k] * B[l, y];
         }
     }
}

该内核只有两个内部的for循环。将作业发送到GPU的程序将告诉GPU为C中的每个数据点执行此内核。GPU将在许多线程上同时执行这些指令。就像俗话说的“便宜”一样,GPU被设计为可以更快地完成相同的事情。

但是,有些算法会降低GPU的速度。有些不适用于GPU。

例如,如果存在数据依赖关系,即:想象C中每个元素的计算都取决于先前的元素。程序员必须在内核中设置一个屏障,以等待每个先前的计算完成。这将是一个严重的放缓。

同样,具有很多分支逻辑的算法即:

__kernel Foo()
{
    if (somecondition)
    {
        do something
    }
    else
    {
        do something completely different
    }
}

由于GPU不再在每个线程中执行相同的操作,因此在GPU上的运行速度往往会变慢。

这是一个简化的解释,因为还有许多其他因素需要考虑。例如,在CPU和GPU之间发送数据也很耗时。有时,即使在CPU上速度更快,也值得在GPU上进行计算,只是为了避免额外的发送时间(反之亦然)。

现在,许多现代CPU以及超线程多核处理器都支持并发。

GPU似乎也不太适合递归,请参见此处,这可能解释了QR算法的一些问题。我相信其中有些具有递归数据依赖性。


2
仅仅说这是一个了不起的答案,对SX进行正式评论是很顽皮的,但是我对老鼠的看法并不陌生:这是一个令人愉悦且内容丰富的答案。SX的最大不公正之一是缺乏对“旧”(在互联网时代)问题给出详尽信息的回答的人的荣誉。(此外,我对(互联网时代的)“旧”答案表示赞同:我知道,对吗?META)。
GT。

一个重要的考虑是是否实际上有一个库来进行计算:例如,据我所知,没有稀疏x密集的矩阵乘法GPU实现,当然不是通过R包实现的。如果您准备好编写GPU C代码,那么祝您好运。
Jack Wasey

4

ñ=210ñ210ķ214

更广泛地说,我怀疑大多数将大部分时间花费在密集线性代数上的统计运算(BLAS,Lapack功能)可以在GPU上有效实现。


0

缺少数据的多种插补方法?就像Alice-II(R)中的那些一样。

我认为这些往往常常令人尴尬地并行,因此适合于GPU架构。从来没有尝试过自己。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.