在GCC和MSVC中存在“simd reduction(:)”?

时间:2013-07-11 19:56:29

标签: visual-c++ gcc vectorization simd icc

simd pragma可以与icc编译器一起使用来执行简化运算符:

#pragma simd
#pragma simd reduction(+:acc)
#pragma ivdep
for(int i( 0 ); i < N; ++i )
{
  acc += x[i];
}

在msvc或/和gcc中是否有任何等效的解决方案?

参考(第28页):http://d3f8ykwhia686p.cloudfront.net/1live/intel/CompilerAutovectorizationGuide.pdf

3 个答案:

答案 0 :(得分:3)

对于Visual Studio 2012: 使用选项/O1 /O2/GL,报告矢量化使用/Qvec-report:(1/2)

int s = 0; 
for ( int i = 0; i < 1000; ++i ) 
{ 
s += A[i]; // vectorizable 
}

如果减少“float”或“double”类型,矢量化则需要抛出/fp:fast开关。这是因为矢量化还原操作取决于“浮点重新关联”。只有在抛出/fp:fast

时才允许重新关联
  

参考(相关文档;第12页)http://blogs.msdn.com/b/nativeconcurrency/archive/2012/07/10/auto-vectorizer-in-visual-studio-11-cookbook.aspx

答案 1 :(得分:2)

GCC绝对可以矢量化。假设你有文件reduc.c,内容为:

int foo(int *x, int N)
  {
    int acc, i;

    for( i = 0; i < N; ++i )
      {
        acc += x[i];
      }

    return acc;
  }

使用命令行编译它(我使用gcc 4.7.2):

$ gcc -O3 -S reduc.c -ftree-vectorize -msse2

现在你可以在汇编程序中看到矢量化循环。

你也可以用

打开详细的矢量化器输出
$ gcc -O3 -S reduc.c -ftree-vectorize -msse2 -ftree-vectorizer-verbose=1

现在您将获得控制台报告:

Analyzing loop at reduc.c:5
Vectorizing loop at reduc.c:5
5: LOOP VECTORIZED.
reduc.c:1: note: vectorized 1 loops in function.

Look at the official docs更好地了解GCC可以和不能进行矢量化的情况。

答案 2 :(得分:1)

gcc需要-ffast-math来启用此优化(如上面给出的参考中所述),无论使用#pragma omp simd reduction。 对于这种优化,icc变得越来越不依赖于pragma(除了在没有pragma的情况下需要/ fp:fast),但原始帖子中额外的ivdep和simd编译指示是不可取的。当给出一个不包含所有相关减少,firstprivate和lastprivate子句的pragma simd时,icc可能会做坏事(并且gcc可能会破坏-ffast-math,特别是与-march或-mavx结合使用)。 msvc 2012/2013在自动矢量化方面非常有限。没有simd减少,OpenMP并行区域内没有矢量化,没有条件的矢量化,并且在矢量化中没有__restrict的优势(有一些运行时检查,以便在没有__restrict的情况下更低效地进行矢量化)。

相关问题