OMP を使用してBLAKEを並列化するには大きな問題があります。「コラムステップ」と「ダイアゴナルステップ」を並列化できることを仕様書で示唆した。これを実行しようとしましたが、結果は予想とは逆です (1 スレッドよりも 10 倍遅くなります)。このループを並列化する方法がわからないため、OMP の経験豊富なユーザーから少し助けが必要です :(
アップデート:
BLAKE の作者が BLAKE の改良 (高速) バージョンである BLAKE2 を公開したことは知っていますが、BLAKE とは実装 (ツリーハッシュ) が異なり、これを理解するのは非常に困難です。私の仕事は、OMP を使用して 1 スレッドとマルチスレッドの実装を比較することです。だから私は理解している実装でこれをやろうとします。私は OMP の専門家ではありません。可能な限り簡単な方法で BLAKE をマルチスレッド化したいと考えています。パフォーマンスが良くなくても、OMP で適切な実装を行う必要があります。(私の英語で申し訳ありませんが、あなたが私を理解してくれることを願っています)これは私のコードの一部です:
#pragma omp parallel shared(n)
{
for(round=0; round<n; ++round)
{
/* column step, I want to run this 4 G32 functions in parallel, but don't know,
that is proper approach to this problem */
#pragma omp critical
G32( 0, 4, 8,12, 0);
#pragma omp critical
G32( 1, 5, 9,13, 1);
#pragma omp critical
G32( 2, 6,10,14, 2);
#pragma omp critical
G32( 3, 7,11,15, 3);
/* diagonal step, and same here */
#pragma omp critical
G32( 0, 5,10,15, 4);
#pragma omp critical
G32( 1, 6,11,12, 5);
#pragma omp critical
G32( 2, 7, 8,13, 6);
#pragma omp critical
G32( 3, 4, 9,14, 7);
}
}
そして、これは G32 関数です:
#define G32(a,b,c,d,i)\
do { \
v[a] = ADD32(v[a],v[b])+XOR32(m[sigma[round][2*i]], c32[sigma[round][2*i+1]]);\
v[d] = ROT32(XOR32(v[d],v[a]),16);\
v[c] = ADD32(v[c],v[d]);\
v[b] = ROT32(XOR32(v[b],v[c]),12);\
v[a] = ADD32(v[a],v[b])+XOR32(m[sigma[round][2*i+1]], c32[sigma[round][2*i]]);\
v[d] = ROT32(XOR32(v[d],v[a]), 8);\
v[c] = ADD32(v[c],v[d]);\
v[b] = ROT32(XOR32(v[b],v[c]), 7);\
} while (0)