13

以下是执行相同功能的免费函数,但在第一种情况下,循环不是矢量化的,但在其他情况下是矢量化的。这是为什么?

#include <vector>

typedef std::vector<double> Vec;

void update(Vec& a, const Vec& b, double gamma) {
    const size_t K = a.size();
    for (size_t i = 0; i < K; ++i) { // not vectorized
        a[i] = b[i] * gamma - a[i];
    }
}

void update2(Vec& a, const Vec& b, double gamma) {
    for (size_t i = 0; i < a.size(); ++i) { // vectorized
        a[i] = b[i] * gamma - a[i];
    }
}

void update3(Vec& a, size_t K, const Vec& b, double gamma) {
    for (size_t i = 0; i < K; ++i) { // vectorized
        a[i] = b[i] * gamma - a[i];
    }
}

int main(int argc, const char* argv[]) {
    Vec a(argc), b;
    update(a, b, 0.5);
    update2(a, b, 0.5);
    update3(a, a.size(), b, 0.5);
    return 0;
}

来自编译器的相关消息(VS2013):

1>  c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(7) : info C5002: loop not vectorized due to reason '1200'
1>  c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(13) : info C5001: loop vectorized
1>  c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(19) : info C5001: loop vectorized

来自@tony 的评论

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

4

1 回答 1

2

我猜这是一些内部编译器实现问题,比如自动矢量化器在什么阶段“开始”以及当时代码的内部表示状态是什么。当我尝试使用 MSVC2017 时,它的效果更符合人们的预期。它自动矢量化update()and update3(),但不是 update2(),原因是第 14 行给出了 501,记录为:

归纳变量不是局部的;或上限不是循环不变的。

于 2018-03-02T16:15:48.493 回答