Der*_*unk 4 parallel-processing
问题说明了一切。在我看来,矢量化与令人尴尬的并行问题密切相关。换句话说,所有可矢量化的程序都必须是令人尴尬的并行程序。这样对吗?
令人尴尬的并行性的快速总结:
如果代码可以毫不费力地并行化,尤其是处理数据依赖性,那么代码就会令人尴尬地并行化。请注意,令人尴尬的并行性仅意味着代码将毫不费力地安全地并行化;它不保证任何最佳性能。
一个简单的例子是两个向量的求和。
// A, B, and C are all distinct arrays.
for (int i = 0; i < N; ++i)
C[i] = A[i] + B[i];
Run Code Online (Sandbox Code Playgroud)
这段代码非常并行,因为没有数据依赖于C. 这段代码可以简单地并行化,例如,通过使用 OpenMP:
#pragma omp parallel for
for (int i = 0; i < N; ++i)
C[i] = A[i] + B[i];
Run Code Online (Sandbox Code Playgroud)
矢量化是实现并行性的一种特殊形式。特别是,向量化主要在使用 x86 SSE/AVX 和 ARM NEON 等专用指令的处理器中使用专用的 SIMD 执行硬件单元。编译器可能会自动矢量化您的代码,或者您可以使用内在函数和直接汇编代码手动矢量化。
我认为矢量化不一定意味着要矢量化的代码必须非常并行。但是,在实践中,大多数可矢量化的代码都是令人尴尬的并行,因为几乎所有的 SIMD 指令都假设了这一点。我找不到任何允许数据相关操作的 SIMD 指令。从这个意义上说,是的,您可以说可向量化程序需要非常并行。
但是,从广义上讲,矢量化可以包含 GPGPU 风格的 SIMD 编程,例如 Nvidia 的 CUDA 和 Intel 的 MIC 架构。它们通过处理依赖于数据的操作和分支允许更灵活的 SIMD 操作。
总而言之,在矢量化的狭义定义中,即传统 CPU 的 SIMD 操作的矢量化,我认为可矢量化程序应该是令人尴尬的并行。但是,高级形式的 SIMD/矢量化可以实现依赖于数据的操作和任意分支。
令人尴尬的并行问题是不需要努力以并行形式编写的任务。矢量化是传统过程变得并行的过程。
因此,这并不是一种逻辑子类型是另一种类型的情况,而是一种趋势。问题越接近令人尴尬的并行,需要的向量化就越少。