0

我已启用自动矢量化。当我编译的代码,我收到以下警告:C++矩阵乘法自动矢量化

info C5002: loop not vectorized due to reason '1203' 

MSDN指定该

环体包括非连续存取到一个数组。

我已经看过这些链接,1,2,寻求帮助,但没有运气。

这里是我的源代码:

for (int row = 0; row < size; ++row) { 
    for (int col = 0; col < size; ++col) { 
     float tmp = 0; 
     for (int i = 0; i < size; ++i) { // This loop generates the warning above 
      tmp += matrixA[row][i] * matrixB[i][col]; 
     } 
     matrixResult[row][col] = tmp; 
    } 
} 

任何帮助是值得欢迎的。

+5

C++二维数组作为一维数组row1,row2等排列在内存中。此表达式'matrixB [i] [col]'使索引在数组中跳转。这个表达式'matrixA [row] [i]'没有。 –

+1

你的矩阵是如何定义/分配的?如果他们是'double **',那么由于缓存局部性问题,您的性能也会变差。 – NoseKnowsAll

+2

首先转置B(并交换索引),以便获得连续的访问权限。 –

回答

1

如果矩阵AB具有相同的存储顺序(例如行主),则无论如何您都无法对其进行矢量化。这使得警告似乎合理。

这里只是一个建议:如果你想认真的高性能计算,那么你应该在二维数组放弃。缓存的增益比矢量化的速度要快。

2

二维数组存储为存储器的单个连续块,所以一个3x2的元件2D阵列实际上是布置端到端6层的元件。

的[]索引运营商简单地计算其元件访问。

所以这里发生了什么是矩阵matrixA被从元件1通过对元件6依次(即A1,A2,A3,B1,B2,B3)进行访问。

matrixB然而,正在访问“随机”,A1,B1,A2,B2等,这映射到实际存储作为存取元件1,则4然后2然后5.

不能改变顺序你访问了matrixB的元素,但是你可以对它进行转置,以便元素按正确的顺序依次访问。显然,如果你只进行一次这种乘法运算,可能不值得重新计算matrixBs排序,但如果你反复执行这个计算,那么这个努力将是非常值得的。

0

的一种方式,达到连续访问:您可以交换内部的两个循环。而不是for row, for col, for i你有for row, for i, for col。看到下面的结果代码。现在matrixResultmatrixB的访问沿着col,因此它是连续的。

for (int row = 0; row < size; ++row) { 
    for (int i = 0; i < size; ++i) { 
     int a_row_i = matrixA[row][i]; 
     for (int col = 0; col < size; ++col) { 
      matrixResult[row][col] += a_row_i * matrixB[i][col]; 
     } 
    } 
}