0

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

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

欢迎任何帮助。

4

3 回答 3

2

2D 数组存储为单个连续的内存块,因此 3x2 元素的 2D 数组实际上是首尾相连的 6 个元素。

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

所以这里发生的情况是,matrixA 被顺序地从元素 1 访问到元素 6(即 A1、A2、A3、B1、B2、B3)。

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

您无法更改访问 matrixB 元素的顺序,但您可以转置它,以便元素以正确的顺序依次访问。显然,如果您只进行一次乘法运算,可能不值得重新计算矩阵 B 的顺序,但如果您重复执行此计算,那么付出的努力将是非常值得的。

于 2017-04-20T08:06:17.840 回答
1

如果矩阵AB具有相同的存储顺序(例如行主要),那么您无论如何都不能对其进行矢量化。所以这使得警告是合理的。

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

于 2017-04-20T07:47:44.553 回答
0

实现连续访问的一种方法:您可以交换内部的两个循环。而不是for row, for col, for i你有for row, for i, for col. 请参阅下面的结果代码。现在两者matrixResult和的访问matrixB是沿着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];
        }
    }
}
于 2017-04-20T08:59:46.033 回答