【问题标题】:Matlab + CUDA slow in solving matrix-vector equation A*x=BMatlab + CUDA 求解矩阵向量方程 A*x=B 很慢
【发布时间】:2013-02-01 01:52:04
【问题描述】:

我正在计算一个方程 A*x=B,其中 A 是矩阵,B 是向量,x 是答案(未知)向量。

硬件规格: 英特尔 i7 3630QM(4 核), nVidia GeForce GT 640M(384 CUDA 核心)

这是一个例子:

>> A=rand(5000);

>> B=rand(5000,1);

>> Agpu=gpuArray(A);

>> Bgpu=gpuArray(B);

>> tic;A\B;toc;

Elapsed time is 1.382281 seconds.

>> tic;Agpu\Bgpu;toc;

Elapsed time is 4.775395 seconds.

不知何故,GPU 速度要慢得多……为什么? FFT、INV、LU计算也比较慢,应该和矩阵除法有关。

但是,GPU 在矩阵乘法(相同的数据)方面要快得多:

>> tic;A*B;toc;

Elapsed time is 0.014700 seconds.

>> tic;Agpu*Bgpu;toc;

Elapsed time is 0.000505 seconds.

主要问题是为什么 GPU A\B (mldivide) 比 CPU 慢?

更新

以下是 A、B(在 CPU 上)、AA、BB(在 GPU 上)为 rand(5000) 时的更多结果:

>> tic;fft(A);toc;
Elapsed time is *0.117189 *seconds.
>> tic;fft(AA);toc;
Elapsed time is 1.062969 seconds.
>> tic;fft(AA);toc;
Elapsed time is 0.542242 seconds.
>> tic;fft(AA);toc;
Elapsed time is *0.229773* seconds.
>> tic;fft(AA);toc;

粗体时间是稳定的时间。但是 GPU 几乎慢了两倍。顺便说一句,为什么 GPU 在前两次尝试时更慢?是先编译两次吗?

另外:

>> tic;sin(A);toc;
Elapsed time is *0.121008* seconds.
>> tic;sin(AA);toc;
Elapsed time is 0.020448 seconds.
>> tic;sin(AA);toc;
Elapsed time is 0.157209 seconds.
>> tic;sin(AA);toc;
Elapsed time is *0.000419 *seconds

经过两次计算,GPU 在 sin 计算中的速度非常快。

那么,为什么 GPU 在矩阵除法、fft 和类似计算中如此缓慢,而在矩阵乘法和三角函数中却如此之快?这个问题实际上不应该是这样的...... GPU 在所有这些计算中应该更快,因为 Matlab 已经为 GPU 发布了重叠函数(mldivide,fft)。

有人可以帮我解决这些问题吗? :)

【问题讨论】:

  • 虽然这不是确切的情况,因为您使用的是直接求解器而不是 krylov 子空间方法,但 vienacl 网站上有一些有趣的信息在基准测试中。如果你看看这个:viennacl.sourceforge.net/viennacl-benchmarks.html 你会注意到在几乎所有情况下,对于较小的矩阵,cpu 都比 gpu 快,这部分是由于迭代求解器的性质,但也正如他们所说的结果“由于 PCI-Express 延迟而不可避免的 GPU 内核启动开销”可能对您产生类似的影响。
  • @johnish 我不确定在这种情况下,由于 PCI-Express 延迟,较长的时间应该归因于 GPU 内核启动开销。对于相同大小的矩阵,GPU 上的矩阵乘法需要 0.000505s,所以我会得出这样的结论:这样的开销小于 0.000505s,而 mldivide 需要 4.775395s。我会得出结论,在这种情况下,延迟完全被处理时间所掩盖,正如您所观察到的,处理时间可能比“小”矩阵的 CPU 更长。直到最近,Accelereyes Jacket 在此类任务上做得很好,但现在它似乎已被合并到 Matlab 中。

标签: performance matlab matrix cuda linear-algebra


【解决方案1】:

请阅读 Matlab 如何计算解。它将帮助您了解 GPU 速度较慢的原因。

我会试着用几句话说出来。

A*x=b 变成 L*(U*x=y)=b, L*U=A

  1. 所以Matlab把A变成L*U(这个过程不能完全并行 据我所知,一些步骤可以并行完成,因为 它们的性质)
  2. 然后,Matlab 求解 L*y=B 并找到 y。 (此过程无法完成 并行,因为每个步骤都需要前一个步骤的数据)
  3. 然后 Matlab 求解 U*x=y 并找到 x。 (此过程无法完成 并行,因为每个步骤都需要前一个步骤的数据)

所以它的 GPU 时钟比 CPU 慢,并且由于进程不能并行完成,所以 CPU 更快。不,除非你想出更好的方法(祝你好运!),否则 GPU 总是会变慢,除非在某些非常特殊的情况下。

【讨论】:

【解决方案2】:

解释的第 1 部分在 user2230360 的回答中,但你的问题是双重的,所以我将添加一些关于乘法的内容。

如前所述,LU 分解不是很容易并行化,即使某些步骤可以并行化。然而,矩阵乘法是非常可并行化的。如果您正在使用这些东西,您应该能够手动进行矩阵乘法,然后您就会知道可以按照您想要的任何顺序来计算矩阵 C 中的元素 A*B=C - 因此有可能用于并行计算。这可能就是为什么您会看到如此快速的乘法,但线性系统的求解速度却很慢。一个不能“和另一个一样多”并行化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2014-04-05
    • 2013-04-01
    • 2018-10-28
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多