如何避免矩阵乘法等运算中的“代码优化”?

时间:2016-05-01 05:41:30

标签: matlab

我需要比较两种算法Alg_x,Alg_y的运行时间。然而,Alg_x包含许多矩阵乘法,Alg_y包含许多逐元素的运算(例如,每两个数/向量的求和和多次运算)。从理论上讲,Alg_x和Alg_y具有相同的运行时间。然而,实际上,Alg_x的运行速度比Alg_y快得多,因为矩阵乘法是在Matlab中专门设计和优化的。

然后,我的问题是,如何关闭这样的'代码优化'以便公平地比较运行时间并反映理论时间复杂度?

%%%%%  X = randn(1000,2000);

Alg_x

tic;
temp = X*X';
toc

Alg_y

[d,n] = size(X);
temp = zeros(d,d);
tic;
for i =1:n
    x = X(:,i);
    temp = temp+x*x';
end
toc

以上两个代码具有相同的输出,而Alg_x运行得更快。此外,删除 x = X(:,i)后,Alg_y的运行速度也会快得多; temp = temp + x * x'; ,所以我猜这是 for iteration 让Alg_y运行缓慢。

我确实想关闭并避免这种oprimizations。 以下是我从 Why is MATLAB so fast in matrix multiplication?

中提取的内容

我正在使用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倍。

所以我的问题是 - 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();

编辑: 我也不知道如何考虑C#的结果。该算法与C ++和Java相同,但是从1024开始有一个巨大的跳跃2048

EDIT2: 更新了MATLAB和4096x4096结果

1 个答案:

答案 0 :(得分:1)

我正在回答你的问题“MATLAB如何快速完成?”。

MATLAB使用Intel MKL进行矩阵乘法 这是高度优化的代码,充分利用了所有内核及其矢量处理单元(SSE / AVX)。 此外,它还针对CPU中的缓存布局进行了手动优化。

你的代码没有这样做,因此在桌面上留下了很多好处。

可能有一种方法可以在MATLAB中禁用MKL 虽然到目前为止我只看到了取代它的方法。