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)
4

1 回答 1

2

我认为他们想到的那种并行化是在现代 CPU 下利用 SIMD 指令。在这种情况下,OMP 式并行化的问题有两个:

  • G32 任务太“小”或“短”,因此在不同线程中启动任务和加入任务的开销相比之下太大了。
  • 错误共享:任务中读取和修改的内存位置靠得太近。他们可能共享一个缓存行。这很糟糕,因为这需要特殊的同步并使来自不同线程的读/写非常慢。
于 2013-01-10T15:53:41.777 回答