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
答案 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的情况下更低效地进行矢量化)。