【问题标题】:Matlab matrix multiplication speedMatlab矩阵乘法速度
【发布时间】:2012-09-25 04:09:19
【问题描述】:

我想知道 matlab 怎么能这么快地将两个矩阵相乘。将两个 NxN 矩阵相乘时,执行 N^3 次乘法。即使使用Strassen Algorithm,它也需要 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 次操作。

这怎么可能??

【问题讨论】:

  • 其实,Matlab 中的“Ma”代表魔法。
  • 你怎么知道没有线程发生?
  • 你确定它是在 CPU 上计算的吗? mathworks.com/discovery/matlab-gpu.html
  • Matlab 肯定是多线程的。我现在正在我的机器上测试它,它使用 4 个核心。
  • Matlab 肯定是做多线程的,至少 R2011b 是用默认设置做的,不受操作系统的干扰。

标签: performance matlab matrix time-complexity matrix-multiplication


【解决方案1】:

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

maxNumCompThreads(n)

这会将要使用的内核数设置为 n。现在我有一个 Core i7-2620M,它的最大频率为 2.7GHz,它也有一个turbo mode with 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 的能力,以获得准确的性能估计。

【讨论】:

    【解决方案2】:

    这是几件事的结合:

    • 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 吞吐量的效率。

    我没有看到任何异常。

    【讨论】:

    • 组合中的另一个“东西”(你太客气了,不能提):许多程序员不知道现代 CPU 有多么复杂,也不知道设计人员做了什么来使它们变得糟糕。
    • matrix 矩阵乘法也执行加法,而不仅仅是 muls。我认为你的性能估计应该包括通过 SSE 的 4 次 FLOP/周期,但操作数是两倍。我对么?您的 MATLAB 是否没有使用支持 AVX 的 BLAS?
    • @angainor 实际上每个周期一个add 和一个mul。每一个都可以是SSE。但是,add 和 muls 是独立的执行单元,所以如果你不使用另一个,你就不能“加倍”。
    • 没错。只是为了进行分析,应包括添加。结果是一样的,只是你做了一个不平凡的捷径。对于不知道您在评论中写了什么的人来说可能很难理解。
    • OP 只计算乘法。我也不想将他与添加混淆(即使它们完全一样)。
    猜你喜欢
    • 1970-01-01
    • 2011-11-30
    • 2014-07-14
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多