C ++矩阵乘法自动矢量化

时间:2017-04-20 07:25:07

标签: c++ matrix-multiplication visual-studio-2017 simd auto-vectorization

我启用了自动矢量化。编译代码时,收到以下警告:

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

MSDN指定

  

循环体包括对数组的非连续访问。

我已查看这些链接,12,寻求帮助,但没有运气。

这是我的源代码:

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;
    }
}

欢迎任何帮助。

3 个答案:

答案 0 :(得分:2)

2D数组存储为单个连续的内存块,因此3x2元素2D数组实际上是端对端布局的6个元素。

[]索引操作符只是计算要访问的元素。

所以这里发生的是矩阵A从元素1到元素6顺序访问(即A1,A2,A3,B1,B2,B3)。

matrixB然而,正在被“随机”访问,A1,B1,A2,B2等映射到实际存储上作为访问元素1然后4然后2然后5。

您无法更改访问matrixB元素的顺序,但您可以对其进行转置,以便按顺序顺序访问元素。显然,如果你只进行一次这样的乘法,那么重新计算matrixBs排序可能不值得,但如果你反复执行这个计算,那么努力就非常值得。

答案 1 :(得分:1)

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

这里只是一个建议:如果你想要严肃的高性能计算,那么你应该放弃2D数组。缓存的增益远大于矢量化速度。

答案 2 :(得分: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];
        }
    }
}