我用CUDA, c++, c#, Java做了一些基准测试,并使用MATLAB进行验证和矩阵生成。当我用MATLAB执行矩阵乘法时,2048x2048甚至更大的矩阵几乎立即被相乘。

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

只有CUDA是有竞争力的,但我认为至少c++会有点接近,而不是慢60倍。我也不知道如何看待c#的结果。算法与c++和Java一样,但从1024年到2048年有了巨大的飞跃。

MATLAB是如何如此快速地执行矩阵乘法的?

c++代码:

float temp = 0;
timer.start();
for(int j = 0; j < rozmer; j++)
{
    for (int k = 0; k < rozmer; k++)
    {
        temp = 0;
        for (int m = 0; m < rozmer; m++)
        {
            temp = temp + matice1[j][m] * matice2[m][k];
        }
        matice3[j][k] = temp;
    }
}
timer.stop();

当前回答

答案是LAPACK和BLAS库使MATLAB在矩阵运算方面速度惊人,而不是MATLAB的任何专有代码。

在你的c++代码中使用LAPACK和/或BLAS库来进行矩阵运算,你会得到与MATLAB相似的性能。这些库在任何现代系统上都应该是免费的,其中一部分是学术界在几十年里开发出来的。注意,有多种实现,包括一些封闭源代码,如Intel MKL。

这里有关于BLAS如何获得高性能的讨论。


顺便说一句,在我的经验中,直接从c调用LAPACK库是一种严重的痛苦(但值得)。你需要非常精确地阅读文档。

其他回答

Matlab在一段时间前集成了LAPACK,所以我假设他们的矩阵乘法至少用了这么快的速度。LAPACK源代码和文档是现成的。

你也可以看看Goto和Van De Geijn的论文“高性能矩阵的解剖” 乘法”在http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.1785&rep=rep1&type=pdf

这就是原因。MATLAB不像在c++代码中那样,通过遍历每一个元素来执行简单的矩阵乘法。

当然,我假设你只是用C=A*B而不是自己写一个乘法函数。

对于“为什么matlab在做xxx时比其他程序快”的一般答案是,matlab有很多内建的优化函数。

使用的其他程序通常没有这些功能,因此人们应用自己的创造性解决方案,这比专业优化的代码慢得多。

这有两种解释:

1)常见的/理论的方法:Matlab并没有明显更快,你只是做错了基准测试

2)现实的方法:对于这些东西,Matlab在实践中更快,因为像c++这样的语言太容易以无效的方式使用。

它在c++中很慢,因为你没有使用多线程。本质上,如果A = B C,其中它们都是矩阵,则A的第一行可以独立于第二行计算,等等。如果A、B和C都是n × n矩阵,您可以将乘法运算速度提高一个因子n^2,如

A_ {i,j} = sum_{k} b_{i,k} c_{k,j}

如果您使用Eigen [http://eigen.tuxfamily.org/dox/GettingStarted.html],多线程是内置的,线程的数量是可调的。

答案是LAPACK和BLAS库使MATLAB在矩阵运算方面速度惊人,而不是MATLAB的任何专有代码。

在你的c++代码中使用LAPACK和/或BLAS库来进行矩阵运算,你会得到与MATLAB相似的性能。这些库在任何现代系统上都应该是免费的,其中一部分是学术界在几十年里开发出来的。注意,有多种实现,包括一些封闭源代码,如Intel MKL。

这里有关于BLAS如何获得高性能的讨论。


顺便说一句,在我的经验中,直接从c调用LAPACK库是一种严重的痛苦(但值得)。你需要非常精确地阅读文档。