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结构)将上述两种结构相结合,即将迭代空间分配给团队中的线程,并进一步矢量化每个线程执行的部分循环。如果未在并行区域范围内使用,则for simd
结构等效于simd
结构。
可以将循环SIMD结构与parallel
结构相结合:
#pragma omp parallel for simd
for (i = 0; i < 100; i++) { ... }
这个结构将创建一个并行区域,在线程之间分配循环的迭代,并对部分循环进行矢量化。
请注意,有时候矢量化和多线程在性能上不是正交的。例如,如果循环受到内存限制,则单独使用矢量化和多线程都可能导致可用内存带宽的耗尽,同时将它们组合起来也不会带来进一步的加速。
此外,在比较速度提升方面,使用#pragma omp simd
和#pragma omp [parallel] for simd
时,请记住,仅使用多线程通常比相同数量的"重复计算"的矢量化提供更好的速度提升,即具有四路SIMD的循环(最有可能)比使用标量指令但分裂成四个线程的相同循环执行得更慢。
omp simd
的意义。我的意思是,许多编译器已经通过自动向量化做得很好了。omp simd
有什么优势呢? - Z bosonsimdlen
子句之外,编译器可以自由选择用于循环的SIMD长度。这意味着编译器也可能使用SIMD长度1,即标量代码用于 simd
结构。 - Michael Klemm
pragma omp parallel for simd
吗? - Z boson