为什么矢量化对于几乎相同的代码表现不同?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么矢量化对于几乎相同的代码表现不同?相关的知识,希望对你有一定的参考价值。

以下是执行相同操作的自由函数,但在第一种情况下,循环不是矢量化的,但在其他情况下它是。这是为什么?

#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:“循环包含阻止向量化的循环携带数据依赖性。循环的不同迭代相互干扰,因此向量化循环会产生错误的答案,并且自动向量化器无法证明自己没有这样的数据依赖性“。 source

答案

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

归纳变量不是本地的;或上限不是循环不变的。

以上是关于为什么矢量化对于几乎相同的代码表现不同?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 GCC 会为几乎相同的 C 代码生成如此完全不同的程序集?

为啥这两个相同的表会根据浏览器宽度的不同而表现不同?

不同量化电平数对信号有啥影响

为什么这两个相同的表根据浏览器宽度表现不同?

ARCGIS矢量数据批量合库为啥会失败

我正在尝试通过引用发送 2d 矢量,但似乎它不适用于几乎相同的方法