为什么循环没有被矢量化?

时间:2015-07-22 15:03:42

标签: c++ optimization vector vectorization

我知道只有在被访问的对象在内存中是连续的时才能进行矢量化。我创建了一个具有指针的结构,然后我创建了这个结构的向量,并确保对象向量内的指针指向连续的数据块,我将它们设置为指向具有相同大小的double向量中的元素。

#include <iostream>
#include <vector>

struct Vec {
   Vec() {}
   double* a;
};

int main(int argc, char* argv[]) {
   std::vector<double> vec_double(10000000, 1.0);
   std::vector<Vec> vec_vec(10000000);
   for (unsigned i = 0; i < 10000000; ++i)
      vec_vec[i].a = &(vec_double[i]);

   // Why is this loop not vectorized
   for (unsigned i = 0; i < 10000000; ++i)
      vec_double[i] += *(vec_vec[i].a);

   double sum = 0.0;
   for (unsigned i = 0; i < 10000000; ++i)
      sum += vec_double[i];
   std::cout << sum << std::endl;

   return 0;
}

然而,即使使用O3优化,第16行的循环也没有进行矢量化。有人可以解释为什么会发生这种情况吗?

2 个答案:

答案 0 :(得分:3)

这里只是猜测,但是当看到这个特定的循环时,编译器不知道vec_vec[i].a指向vec_vec[i+1].a旁边的内存位置。因此,如果不单独解除引用每个.a成员,则无法进行计算。

当看到上面的循环时,它可以知道。但如果它会这样做,它也可以查看下面的循环,计算最终结果并打印出来。

答案 1 :(得分:0)

您应该首先从迭代器获取原始指针。与此vec_vec.begin()_Ptrvec_double.begin()._Ptr一样。使用遗留的那些指针。最后声明它没有别名的方法。像这样__declspec(noalias)。它应该在Windows上使用msvc完成这个技巧。我不认为GCC有noalias属性。