OpenMP 4.0引入了SIMD结构,以利用cpu的SIMD指令.根据规范http://www.openmp.org/mp-documents/OpenMP4.0.0.pdf,有两种构造使用simd来矢量化循环.一个是"#pragma omp simd",另一个是"#pragma omp for simd".根据规范,两者都用于向量化循环.我也测试过并没有找到它们的区别.任何人都知道这两种结构之间是否存在差异?
#pragma omp simd (SIMD构造)指示OpenMP编译器在没有工作共享的情况下向后传递循环,即不在多个线程(如果有)之间分配循环迭代.
#pragma omp for(循环结构)指示编译器在当前团队的线程之间分配工作时执行以下循环.因此,循环结构仅在放置在并行区域的词法或动态范围内时才有用,例如
#pragma omp parallel
{
...
#pragma omp for
for (i = 0; i < 100; i++) { ... }
...
}
Run Code Online (Sandbox Code Playgroud)
#pragma omp for simd(也称为循环SIMD construt)结合了上面的两个构造,即它既在团队中的线程之间分配迭代空间,又进一步向量化每个线程执行的部分循环.如果未在并行区域的范围内使用,则for simd构造等同于simd构造.
可以将循环SIMD构造与parallel构造组合:
#pragma omp parallel for simd
for (i = 0; i < 100; i++) { ... }
Run Code Online (Sandbox Code Playgroud)
这个组合构造创建一个并行区域,在线程之间分配循环的迭代,并向量化部分循环.
注意,有时矢量化和多线程在性能方面不正交.例如,如果循环受内存限制,那么单独的矢量化和多线程都可能导致可用内存带宽的耗尽,并且组合它们将不会带来任何进一步的加速.
此外,在比较加速#pragma omp simd和使用时#pragma omp [parallel] for simd,请记住,单独的多线程通常比相同数量的"多重性"提供比矢量化更好的加速,即四向SIMD-ised循环可能(并且大多数情况下)执行比执行时更慢使用标量指令计算相同的循环,但在四个线程中分割.