【问题标题】:Comparision of Speed of matrix multiplication in matlab and Cmatlab和C中矩阵乘法速度的比较
【发布时间】:2014-07-14 13:43:30
【问题描述】:

我们可以通过多种方式进行矩阵乘法。 A 和 B 是两个矩阵,大小为 1000 * 1000。

  1. 使用 matlab 内置矩阵运算符。 A*B
  2. 显式编写两个嵌套。
  3. 明确写三个嵌套。
  4. 动态链接 C 代码以执行三个嵌套。

结果是

  1. * 运算符非常快。大约需要 1 秒钟。
  2. 嵌套非常慢,尤其是三个嵌套,500 秒。
  3. C 循环比 matlab 嵌套要快得多,只需 10 秒。

谁能解释下。为什么* 这么快,为什么 C 循环比在 matlab 中编写循环更有效。

我使用另一个软件而不是 matlab 来进行计算。但我认为应该适用类似的推理。

【问题讨论】:

标签: c performance matlab matrix matrix-multiplication


【解决方案1】:

因为矩阵乘法在 Matlab 中进行了高度优化,在底层使用 LAPACK 库。

您会发现很难超越这些库的性能。当然,简单的嵌套循环不会考虑cache effects,因此会表现出糟糕的性能。

【讨论】:

  • 我明白你的意思了。您能否解释一下为什么使用 c 循环比在 matlab 中编写循环要快。我查了c源代码,和我用matlab写的一样,一个三嵌套。
【解决方案2】:

matlab 是解释型语言,C 是编译型的。因此 C 循环比 matlab 循环快得多。这就解释了 2 和 3 之间的区别。

同样,matlab 的 A*B 也是一个编译后的代码。那为什么它仍然比 C 代码快一个数量级呢?毕竟,如果它只是一个非常简单的嵌套代码,并且编译器可以对其进行优化,使其与您在汇编中编写它一样快。嗯,答案很可能不仅仅是嵌套循环。简单的嵌套循环算法在 O(n^3) 时间内运行,但是如果你递归地分解矩阵,那么你可以相对容易地得到 O(n^2.8) Strassen 算法(http://en.wikipedia.org/wiki/Strassen_algorithm),它在实践中表现良好;或者您甚至可以使用不太实用的 O(n^2.37) Coppersmith-Winograd 算法 (http://en.wikipedia.org/wiki/Coppersmith%E2%80%93Winograd_algorithm)。

我敢打赌,matlab 使用某种形式的 Strassen 算法,它不仅具有更好的渐近速度,而且由于它最终相乘的子矩阵很小,因此它的缓存利用率也更高。

【讨论】:

  • Matlab 使用 LAPACK;我推测 LAPACK 使用简单的 N^3 算法,但具有非常好的阻塞、矢量化和可能的多线程。
  • 很高兴知道。谢谢!
  • 换句话说,没有使用 Strassen 算法……可能是由于数值稳定性问题。
【解决方案3】:

There is a webpage 描述 C 中的矩阵乘法速度 使用朴素代码和 Blas 代码:

朴素的代码

for (i = 0; i < n; i++)
    for (j = 0; j < n; j++) {
        C[i + j*n] = 0;
        for (k = 0; k < n; k++)
            C[i + j*n] += A[i + k*n]*B[k + n*j];
    }

BLAS 代码

dgemm_(&charN, &charN, &n, &n, &n, &one_d, A, &n, B, &n, &zero_d, C, &n);

显示

也许是使用这些库并提高速度的好选择。

【讨论】:

    猜你喜欢
    • 2012-09-25
    • 1970-01-01
    • 2011-11-30
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多