OpenMP 4.0 引入了一个名为“omp simd”的新构造。相比旧的“parallel for”,使用此构造的好处是什么?在哪些情况下各自都更好地选择使用?
编辑: 这里有一份与SIMD指令相关的 论文。
OpenMP 4.0 引入了一个名为“omp simd”的新构造。相比旧的“parallel for”,使用此构造的好处是什么?在哪些情况下各自都更好地选择使用?
编辑: 这里有一份与SIMD指令相关的 论文。
parallel for
和其他线程库来利用TLP。那么,SIMD呢?Intrinsics是一种使用它们的方式(以及编译器的自动向量化)。OpenMP的simd
是一种使用SIMD的新方法。for (int i = 0; i < N; ++i)
A[i] = B[i] + C[i];
A[]
上没有(循环承载)数据依赖性。这个循环是令人尴尬地并行的。parallel for
结构并行化此循环。每个线程将在多个核心上执行N/#thread
次迭代。for (int i = 0; i < N/8; ++i)
VECTOR_ADD(A + i, B + i, C + i);
VECTOR_ADD
)是256位或8路(8 * 32位);和(2)N
是8的倍数。parallel for
进一步并行化。simd
构造允许您使用 SIMD 指令,进而可以利用更多的并行性和线程级并行性。然而,我认为实际的实现是很重要的。链接的标准相对清晰(p 13,第19和20行)
当任何线程遇到 simd 构造时,与构造相关联的循环迭代可以由线程可用的 SIMD lane 执行。
SIMD
是一个子线程的东西。为了更具体,您可以想象在 CPU 上使用 simd
指令来特别请求同一 线程 中单个循环迭代块的向量化。它以一种平台无关的方式展示了单个多核处理器中存在的多层并行性。例如我们可以参考这篇英特尔博客文章中的讨论(连同加速器部分)。
所以基本上,您需要使用 omp parallel
来将工作分配到不同的线程中,然后可以迁移到多个内核; 并且您需要在其中的紧密循环周围使用 omp simd
来利用每个内核中的向量管道(例如)。通常情况下,omp parallel
会放在“外面”,处理更粗粒度的并行分配工作,omp simd
则在其中的紧密循环周围使用以利用细粒度并行性。
parallel for
)是将线程/分布分配到核心中,SIMD(OMP >= 4.0,simd
)是向量/AVX/分配在一个核心中。这仅作为未来读者的参考。 - Flamefire