Parallel processing 矢量化和令人尴尬的平行之间的关系是什么?

Parallel processing 矢量化和令人尴尬的平行之间的关系是什么?,parallel-processing,Parallel Processing,问题说明了一切。在我看来,矢量化与令人尴尬的并行问题密切相关。换句话说,所有可矢量化的程序都必须是令人尴尬的并行程序。这是正确的吗?令人尴尬的并行问题是不需要努力以并行形式编写的任务矢量化是一个常规程序并行化的过程 所以,这不是一种情况,一种是另一种的逻辑子类型,而是一种趋势。问题越接近令人尴尬的并行,所需的矢量化就越少。并行是尽可能多地使用我们的计算设备,因此我们尝试以这样一种方式安排任务,使它们的执行几乎彼此独立 现在,并行计算中的矢量化是并行化的一种特殊情况,在这种情况下,默认情况下在单个

问题说明了一切。在我看来,矢量化与令人尴尬的并行问题密切相关。换句话说,所有可矢量化的程序都必须是令人尴尬的并行程序。这是正确的吗?

令人尴尬的并行问题是不需要努力以并行形式编写的任务矢量化是一个常规程序并行化的过程


所以,这不是一种情况,一种是另一种的逻辑子类型,而是一种趋势。问题越接近令人尴尬的并行,所需的矢量化就越少。

并行是尽可能多地使用我们的计算设备,因此我们尝试以这样一种方式安排任务,使它们的执行几乎彼此独立

现在,并行计算中的矢量化是并行化的一种特殊情况,在这种情况下,默认情况下在单个线程上一次执行一个操作的软件程序被修改为同时执行多个操作

向量化是将计算机程序从一次处理一对操作数的标量实现转换为一次处理多对操作数的一个操作的向量实现的更有限的过程

让我们举一个添加两个数组的简单示例:

在正常模式下,我们需要一个循环来添加两个数组。我们可以用很多方法使它并行,就像我们可以制作两个线程,将数组分成两个相等的部分,然后分别分配给线程。现在,可以提高性能的最大线程数等于数组的节点数或数组的长度。 如果我们应用并行性,那么它不需要循环所有数组来添加它。它应该只启动一个命令,并且两个阵列都将被添加。要做到这一点,我们需要以这样一种方式使数组加法程序并行,以便它不需要任何循环。为此,我们将数组划分为与数组长度相等的部分,并将每个部分分配给一个新线程,同时启动所有线程,以便所有添加都在单个指令下进行,而不会同时循环


要使芦丁完全矢量化,它必须像上面的例子那样令人尴尬地平行。但这取决于给定的场景。对于具有相互依赖性的两种芸香碱,它们可以单独矢量化,等等。

对于令人尴尬的并行性的快速总结:

如果代码不需要任何努力就可以并行化,特别是处理数据依赖性,那么代码的并行性就令人尴尬。请注意,令人尴尬的并行性只意味着代码将被安全地并行化,而无需付出任何努力;它不能保证任何最佳性能

一个简单的例子是两个向量的求和

// A, B, and C are all distinct arrays.    
for (int i = 0; i < N; ++i)
  C[i] = A[i] + B[i];

矢量化是实现并行性的一种特殊形式。特别是,矢量化主要使用处理器中的专用SIMD执行硬件单元,这些处理器使用专用指令,如x86 SSE/AVX和ARM NEON。编译器可以自动矢量化代码,也可以使用内部函数和直接汇编代码手动矢量化代码

我不认为矢量化必然意味着要矢量化的代码必须是令人尴尬的并行代码。但是,在实践中,大多数可矢量化的代码都是令人尴尬的并行代码,因为几乎所有SIMD指令都假定这一点。我找不到任何允许数据相关操作的SIMD指令。从这个意义上说,是的,你可以说矢量化的程序需要令人尴尬的并行

然而,从广义上讲,矢量化可以包含GPGPU风格的SIMD编程,如Nvidia的CUDA和Intel的MIC架构。通过处理与数据相关的操作和分支,它们允许更灵活的SIMD操作



总而言之,在矢量化的狭义定义中,即常规CPU的SIMD操作的矢量化,我认为可矢量化的程序应该是令人尴尬的并行。但是,高级形式的SIMD/矢量化可以支持依赖数据的操作和任意分支。

谢谢。但我恐怕它不能告诉我太多。一个或另一个术语的形式化太少。此外,如果你说更令人尴尬(我不知道它到底是什么意思,因为一个问题是(或不是)令人尴尬的平行问题,例如在NC复杂度类中)向量化越少,从定义上讲,这是一种关系。这个答案不再忽略所有令人尴尬的平行关系,但我仍然不相信它告诉了读者很多关于表达式的含义或它与矢量化的关系。谢谢。让它变得更好。出于教学和完整性的目的,有一个不是令人尴尬的并行的矢量化代码的例子是很有趣的。依赖于控制的计算/加载/存储可以通过掩码实现。但是,我仍然无法找到一个在向量指令中观察到依赖性的好例子。你也可以参考维基百科的矢量化页面。
#pragma omp parallel for 
for (int i = 0; i < N; ++i)
  C[i] = A[i] + B[i];