Visual Studio 2012中基于std::vector的自动矢量化没有发生

Auto-Vectorization in Visual Studio 2012 express on std::vector is not happening

本文关键字:矢量化 vector 2012 Studio std Visual      更新时间:2023-10-16

我有一个简单的程序,其中我有3 std::vector并在for循环中使用它们。在启用编译标志ON之后,我正在测试这些循环是否得到了优化。但是visual studio显示,由于1200的原因,循环没有矢量化。我的示例代码如下:

#include <iostream>
#include <vector>
#include <time.h>
int main(char *argv[], int argc)
{
    clock_t t=clock();
    int tempSize=100;
    std::vector<double> tempVec(tempSize);
    std::vector<double> tempVec1(tempSize);
    std::vector<double> tempVec2(tempSize);
    for(int i=0;i<tempSize;i++)
    {
        tempVec1[i] = 20;
        tempVec2[i] = 30;
    }
    for(int i=0,imax=tempSize;i<imax;i++)
        tempVec[i] = tempVec1[i] + tempVec2[i];
    t =clock()-t;          // stop the clock
    std::cout <<"Time in millisecs = " <<  t/double(CLOCKS_PER_SEC) <<      std::endl;
    return 0;
}

下面是在启用选项"/Qvec-report:2"的情况下编译代码的输出。

2>——分析功能:main2> d:testssetestonvectorsmain.cpp(12): info C5002:由于原因"1200",循环未矢量化2> d:testssetestonvectorsmain.cpp(18): info C5002:由于原因'1200',循环未矢量化

当我读到msdn页面上的错误代码1200时:https://msdn.microsoft.com/en-us/library/jj658585.aspx它指定错误码1200是由于"循环包含循环携带的数据依赖"

我无法理解这个循环是如何包含那个的。我有一些代码,我需要优化,使它可以使用Visual studio的自动向量化功能,使它可以优化SSE2。这个代码包含向量操作。所以我无法做到这一点,因为每次visual studio显示一些错误代码像这样

我想你的问题是:

    for(int i=0,imax=tempSize;i<imax;i++)
        tempVec[i] = tempVec1[i] + tempVec2[i];

    for(int i=0,imax=tempSize;i<imax;i++)
        tempVec.operator[](i) = tempVec1.operator[](i) + tempVec2.operator[](i);

…矢量化器无法查看函数调用的内部。第一个修复是:

    const double* t1 = &tempVec1.front();
    const double* t2 = &tempVec2.front();
    double *t = &tempVec.front();
    for(int i=0,imax=tempSize;i<imax;i++)
        t[i] = t1[i] + t2[i];

这里的问题是矢量看不到t t1和t2不重叠。你必须向编译器保证它们不会这样做:

    const double* __restrict t1 = &tempVec1.front();
    const double* __restrict t2 = &tempVec2.front();
    double * __restrict t = &tempVec.front();
    for(int i=0,imax=tempSize;i<imax;i++)
        t[i] = t1[i] + t2[i];

显然(我希望)使用__restrict关键字(这不是标准c++的一部分)意味着此代码将无法移植到其他c++编译器。

编辑: OP已经澄清,用at调用替换对operator[]的调用会产生不同的失败消息(尽管可能是因为at更复杂)。

如果问题不是函数调用,我的下一个假设是operator []归结为类似return this.__begin[i];的东西,矢量器不知道不同的std::vector具有非重叠的内存。如果是,最后的代码块仍然是解决方案。

自动向量化是MSVC的一个相当新的特性,您使用的是旧版本的MSVC。所以它远非完美。微软知道这一点,所以他们决定只在绝对安全的情况下对代码进行矢量化。

特定的错误消息有点简洁。实际上,它应该说"循环可能包含循环携带的数据依赖"。由于MSVC不能证明它们不存在,所以它不进行矢量化。