为什么对于几乎相同的代码,矢量化的行为会有所不同

Why does vectorization behave differently for almost the same code?

本文关键字:矢量化 有所不同 代码 于几乎 为什么      更新时间:2023-10-16

以下是自由函数,但在第一种情况下,循环不是矢量化的,而是在其他情况下。为什么是?

#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:homedimatrwstrw_s-v1.3trwstestvector.cpp(7) : info C5002: loop not vectorized due to reason '1200'
1>  c:homedimatrwstrw_s-v1.3trwstestvector.cpp(13) : info C5001: loop vectorized
1>  c:homedimatrwstrw_s-v1.3trwstestvector.cpp(19) : info C5001: loop vectorized

来自@tony的评论

原因1200:"循环包含循环的数据依赖性,以防止 矢量化。环路的不同迭代干扰每个 其他使矢量化循环会产生错误的答案,并且 自动矢量化器无法向自己证明没有这样的数据 依赖。"源

我想这是一些内部编译器实现问题,例如在哪个阶段自动向量器"启动",当时代码内部表示的状态是什么。当我在MSVC2017上尝试时,它与人们期望的更加一致。它自动化了 update()update3(),但不是 update2(),其中14行给出了501的原因,该行为记录为:

感应变量不是局部的;或上限不是循环不变。