我们可以通过多种方式进行矩阵乘法。 A和B是两个矩阵,大小为1000 * 1000。
A*B
结果是
*
运营商非常快。大约需要1秒钟。 任何人都可以解释以下内容。为什么*
如此之快以及为什么C循环比在matlab中编写循环更有效。
我使用另一种软件而不是matlab来进行计算。但我认为类似的推理应该适用。
答案 0 :(得分:3)
因为矩阵乘法在Matlab中高度优化,所以使用LAPACK库。
你会发现很难击败这些图书馆的表现。当然,简单的嵌套循环不会考虑cache effects,因此会表现出糟糕的性能。
答案 1 :(得分: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算法,它不仅具有更好的渐近速度,而且因为它的偶数乘法的子矩阵很小,所以它也具有更好的缓存利用率。
答案 2 :(得分:1)
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);
表示
使用这些库并提高速度也许是个不错的选择。