c++ - Visual Studio 2012 Express 中 std::vector 的自动矢量化没有发生

标签 c++ visual-studio-2012 stdvector sse2 auto-vectorization

我有一个简单的程序,其中有 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> --- 分析函数:main 2> d:\test\ssetestonvectors\main.cpp(12) : 信息 C5002: 由于“1200”原因循环未矢量化 2> d:\test\ssetestonvectors\main.cpp(18) : 信息 C5002: 由于“1200”原因循环未矢量化

当我在 msdn 页面上看到错误代码 1200 时: https://msdn.microsoft.com/en-us/library/jj658585.aspx 它指定错误代码 1200 是由于“Loop contains loop carried data dependency”

我无法理解这个循环是如何包含它的。我有一些代码需要优化,以便它可以使用 Visual Studio 的自动矢量化功能,从而可以针对 SSE2 进行优化。此代码包含 vector 运算。所以我无法这样做,因为每次 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 已阐明,将对 operator[] 的调用替换为对 at 的调用会产生不同的失败消息(尽管 operator[] em>可能是因为 at 更复杂)。

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

关于c++ - Visual Studio 2012 Express 中 std::vector 的自动矢量化没有发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40079786/

相关文章:

c++ - 通用初始化 - vector 的填充构造函数

c++ - OStringStream 和命名空间问题 C++

c++ - 如何编写一个以仿函数为参数的函数

visual-studio-2010 - ClickOnce 先决条件 : Error: published installer may be corrupt

c++ - 在 VC++ 中查找函数体时出错

c++ - 清空 vector 的特定元素

c++ - C++类中无法重载+运算符

c++ - SSH 在 QProcess 中不起作用,但它在控制台中起作用

c# - 如何在 Web Api 中发布自定义命名方法?

c++ - 创建一个类来访问和指定 vector 类型,并构建一个获取位置并为其分配区域的类