質問はそれをすべて言います。ベクトル化は、恥ずかしいほど並列な問題と非常に密接に関連しているように思えます。言い換えれば、すべてのベクトル化可能なプログラムは、途方もない並列プログラムでなければなりません。これは正しいです?
3 に答える
恥ずかしいほどの並列処理の簡単な要約:
特にデータの依存関係を処理することなくコードを並列化できる場合、コードは驚異的並列です。恥ずかしいほど並列処理とは、コードが手間をかけずに安全に並列化されることを意味するだけであることに注意してください。最適なパフォーマンスを保証するものではありません。
簡単な例は、2つのベクトルの合計です。
// A, B, and C are all distinct arrays.
for (int i = 0; i < N; ++i)
C[i] = A[i] + B[i];
にデータ依存性がないため、このコードは驚異的並列ですC
。このコードは、たとえばOpenMPを使用して、単純に並列化できます。
#pragma omp parallel for
for (int i = 0; i < N; ++i)
C[i] = A[i] + B[i];
ベクトル化は、並列処理を実現する方法の特定の形式です。特に、ベクトル化は主に、x86 SSE/AVXやARMNEONなどの特殊な命令を使用するプロセッサで専用のSIMD実行ハードウェアユニットを使用します。コンパイラはコードを自動的にベクトル化する場合があります。または、組み込み関数と直接アセンブリコードを使用して手動でベクトル化することもできます。
ベクトル化は、ベクトル化されるコードが驚異的並列でなければならないことを必ずしも意味するとは思いません。しかし、実際には、ほとんどすべてのSIMD命令がそれを想定しているため、ほとんどのベクトル化可能なコードは驚異的並列です。データ依存の操作を可能にするSIMD命令が見つかりません。その意味で、そうです、ベクトル化可能なプログラムは驚異的並列である必要があると言えます。
ただし、広い意味では、ベクトル化には、NvidiaのCUDAやIntelのMICアーキテクチャなどのGPGPUスタイルのSIMDプログラミングを含めることができます。データに依存する操作とブランチを処理することにより、より柔軟なSIMD操作を可能にします。
要約すると、ベクトル化の狭い定義、つまり従来のCPUのSIMD操作のベクトル化では、ベクトル化可能なプログラムは驚異的並列である必要があると思います。ただし、高度な形式のSIMD /ベクトル化により、データに依存する操作と任意の分岐が可能になります。
恥ずかしいことに並列問題とは、並列形式で書く努力を必要としないタスクです。ベクトル化は、従来の手順を並列化するプロセスです。
したがって、これはあるものが別の論理的なサブタイプであるというケースではなく、傾向です。問題が非常に並列に近づくほど、必要なベクトル化は少なくなります。
Parallelism is to use our computing devices as much as possible, so we try to schedule tasks in such a way so that their execution is almost independent of each other.
Now, Vectorization, in parallel computing, is a special case of parallelization, in which software programs that by default perform one operation at a time on a single thread are modified to perform multiple operations simultaneously.
Vectorization is the more limited process of converting a computer program from a scalar implementation, which processes a single pair of operands at a time, to a vector implementation which processes one operation on multiple pairs of operands at once.
lets take a simple example of addition of two arrays:
in normal mode, we need a loop to add the two arrays. We can make it parallel in many ways, like we can make two threads and divide the arrays in two equal parts and assign to threads respectively. Now, maximum no. of threads that can increase performance is equal to the no. of nodes of array or length of array. And if we apply parallelism then it should not need to loop all the array to add it. it should launch only one command and both the array will be added. To do this, we need to make the array addition program parallel in such a way so that it doesnot need any loop. for this we will divide arrays into portions equal to length of array and assign each portion to a new thread and launch all of them simultaneously so that all additions occur under a single instruction without looping at a same time.
FOr a rutine to be completely vectorized, it must be embarassingly parallel like in the above example. But it depends on the given scenerio. for two rutines having interdependencies, they can be individualy vectorized, etc.