OpenMP 4.0 中 "simd" 构造和 "for simd" 构造之间的区别

The difference between "simd" construct and "for simd" construct in OpenMP 4.0

OpenMP 4.0 引入了 SIMD 构造以利用 cpu 的 SIMD 指令。根据规范 http://www.openmp.org/mp-documents/OpenMP4.0.0.pdf,有两种结构可以使用 simd 对循环进行矢量化。一个是 "#pragma omp simd",另一个是 "#pragma omp for simd"。根据规范,两者都用于向量化 for 循环。我也测试了,没有发现他们的区别。任何人都知道这两种构造之间是否有区别?

#pragma omp simd(SIMD 构造)指示 OpenMP 编译器在没有工作共享的情况下矢量化后面的循环,即不在多个线程(如果有)之间分配循环迭代。

#pragma omp for(循环构造)指示编译器执行以下循环,同时在当前组的线程之间分配工作。因此,循环构造仅在放置在并行区域的词法或动态范围内时才有用,例如

#pragma omp parallel
{
   ...
   #pragma omp for
   for (i = 0; i < 100; i++) { ... }
   ...
}

#pragma omp for simd(也称为循环 SIMD 构造)结合了上述两种构造,即它既将迭代 space 分配给团队中的线程,又进一步向量化了每个线程执行的部分循环.如果不在并行区域的范围内使用,for simd 结构等同于 simd 结构。

可以将循环 SIMD 构造与 parallel 构造结合起来:

#pragma omp parallel for simd
for (i = 0; i < 100; i++) { ... }

这个组合构造创建一个并行区域,在线程之间分配循环的迭代,并对部分循环进行向量化。

请注意,有时向量化和多线程在性能方面并不正交。例如,如果循环受内存限制,那么单独使用矢量化和多线程可能会导致可用内存带宽耗尽,将它们组合起来不会带来任何进一步的加速。

此外,在比较 #pragma omp simd#pragma omp [parallel] for simd 的加速比时,请记住,对于相同数量的 "multiplicity",单独使用多线程通常比矢量化提供更好的加速比,即四路 SIMD 化循环可能(而且很可能会)比使用标量指令计算相同循环但分为四个线程时执行得更慢。