2013-01-10 21 views
1

我有很大的問題需要使用OMP並行化BLAKE。他們在規範中提出可以並行化「列步驟」和「對角步驟」。我嘗試這樣做,但結果與我預期的相反(比單線程慢10倍)。我需要從OMP的有經驗的用戶一點幫助,因爲現在我不知道如何並行這個循環:(並行化BLAKE

更新:

我知道,布雷克作者發表BLAKE2,這是改善(快)版本的BLAKE,但它與BLAKE有不同的實現(樹形哈希),這對我來說很難理解。我的任務是使用OMP比較單線程和多線程實現,所以我嘗試這樣做在我明白的實現上,我不是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) 
+2

你的OMP是什麼樣的? –

+1

該聲明是關於SIMD並行化的。如果你想使用多線程,可以考慮Blake2 * p,它允許並行壓縮函數調用,這對線程來說效果更好。 – CodesInChaos

+0

BLAKE2 * p變體非常簡單。將消息分成塊,然後在4個線程之間分配這些塊,最後再對這4個部分哈希的輸出進行哈希以得到最終的哈希值。 – CodesInChaos

回答

2

我認爲並行的,他們心目中的那種是根據現代的CPU利用SIMD instrctions。在這種情況下,OMP風格的並行化的問題有兩方面:

  • 的G32的任務是太「小」或「短」,使得相對於的開銷開始在不同的線程任務,並參加過比較好。
  • 虛假共享:在任務中讀取和修改的內存位置太靠近。他們可能共享一個緩存行。這很糟糕,因爲這需要特殊的同步,並且使得來自不同線程的讀取/寫入非常慢。