【问题标题】:C++ Auto-Vectorize Matrix Multiplication loopC++ 自动向量化矩阵乘法循环
【发布时间】:2016-03-02 02:58:55
【问题描述】:

在编译我的源代码时,在启用自动矢量化和自动并行化的情况下执行基本矩阵-矩阵乘法,我在控制台中收到以下警告:

C5002: loop not vectorized due to reason '1200'
C5012: loop not parallelized due to reason'1000'

我已阅读 MSDN 提供的 this 资源,其中指出:

原因代码 1200:循环包含阻止矢量化的循环携带数据依赖项。循环的不同迭代相互干扰,使得循环矢量化会产生错误的答案,并且自动矢量化器无法向自己证明不存在这种数据依赖性。

原因码 1000:编译器检测到循环体中存在数据依赖关系。

我不确定我的循环中是什么导致了问题。这是我的源代码的相关部分。

// int** A, int** B, int** result, const int dimension
for (int i = 0; i < dimension; ++i) {
    for (int j = 0; j < dimension; ++j) {
        for (int k = 0; k < dimension; ++k) {
            result[i][j] = result[i][j] + A[i][k] * B[k][j];
        }   
    }
}

任何见解将不胜感激。

【问题讨论】:

    标签: c++ matrix vector vectorization


    【解决方案1】:

    循环携带依赖于result[i][j]

    解决问题的方法是在汇总结果时使用临时变量,并在最内层循环之外进行更新,如下所示:

    for (int i = 0; i < dimension; ++i) {
        for (int j = 0; j < dimension; ++j) {
            auto tmp = 0;
            for (int k = 0; k < dimension; ++k) {
                tmp += A[i][k] * B[k][j];
            }
            result[i][j] = tmp;
        }
    }
    

    这将消除依赖性(因为result[i][j] 的读写操作更多,应该有助于矢量化器做得更好。

    【讨论】:

    • +1。除了这个很好的答案之外,AB 可能与result“混叠”,即编译器无法证明AB 都不包含与result 的内存重叠。上面的解决方案消除了这种不确定性,总结了tmp中的产品。
    • 确实如此。消除此问题的另一种方法是将ABresult 的指针定义为restricted
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多