7

我想知道 matlab 怎么能这么快地将两个矩阵相乘。将两个 NxN 矩阵相乘时,执行 N^3 次乘法。即使使用Strassen 算法,它也需要 N^2.8 次乘法,这仍然是一个很大的数字。我正在运行以下测试程序:

a = rand(2160);
b = rand(2160);
tic;a*b;toc

使用 2160 是因为 2160^3=~10^10 ( a*b 应该是大约 10^10 次乘法)

我有:

Elapsed time is 1.164289 seconds.

(我在 2.4Ghz 笔记本上运行并且没有发生线程)这意味着我的计算机在 1 秒多一点的时间内完成了 ~10^10 的操作。

这怎么可能??

4

2 回答 2

13

这是几件事的结合:

  • Matlab 确实是多线程的。
  • 内核使用向量指令进行了高度优化。

这是我机器上的数字:Core i7 920 @ 3.5 GHz(4 核)

>> a = rand(10000);
>> b = rand(10000);
>> tic;a*b;toc
Elapsed time is 52.624931 seconds.

任务管理器显示 4 个核心的 CPU 使用率。

现在进行一些数学运算:

Number of multiplies = 10000^3 = 1,000,000,000,000 = 10^12

Max multiplies in 53 secs =
    (3.5 GHz) * (4 cores) * (2 mul/cycle via SSE) * (52.6 secs) = 1.47 * 10^12

因此,Matlab 正在实现1 / 1.47 = 68%最大可能 CPU 吞吐量的效率。

我没有看到任何不寻常的地方。

于 2012-10-04T07:20:09.020 回答
5

要检查您是否在 MATLAB 中使用多线程,请使用此命令

maxNumCompThreads(n)

这会将要使用的核心数设置为 n。现在我有一个酷睿 i7-2620M,它的最高频率为 2.7GHz,它也有一个3.4GHz 的睿频模式。CPU有两个核心。让我们来看看:

A = rand(5000);
B = rand(5000);
maxNumCompThreads(1);
tic; C=A*B; toc
Elapsed time is 10.167093 seconds.

maxNumCompThreads(2);
tic; C=A*B; toc
Elapsed time is 5.864663 seconds.

于是就有了多线程。

我们来看看单CPU的结果。A*B 执行大约 5000^3 次乘法加法。所以单线程代码的性能是

5000^3*2/10.8 = 23 GFLOP/s

现在是 CPU。3.4 GHz,Sandy Bridge 每个周期最多可以使用 AVX 执行 8 次 FLOP:

3.4 [Ginstructions/second] * 8 [FLOPs/instruction] = 27.2 GFLOP/s peak performance

所以单核性能峰值在 85% 左右,这对于这个问题是可以预料的。

您确实需要深入研究 CPU 的功能以获得准确的性能估计。

于 2012-10-04T07:51:33.540 回答