OpenMP中的共享数组

时间:2016-01-23 21:53:33

标签: parallel-processing openmp

我试图将一段C ++代码与OpenMp并行化,但我遇到了一些问题。 实际上,我的并行化代码并不比串行代码快。 我想我已经理解了这个原因,但是我无法解决它。

我的代码结构如下:

int vec1 [M];
int vec2 [N];

...initialization of vec1 and vec2...

for (int it=0; it < tot_iterations; it++) {

if ( (it+1)%2 != 0 ) {

   #pragma omp parallel for

   for (int j=0 ; j < N ; j++) {

  ....code involving a call to a function to which I'm passing as a parameter vec1.....

if (something) { vec2[j]=vec2[j]-1;}

}
}
else {
   # pragma omp parallel for

   for (int i=0 ; i < M ; i++) {

  ....code involving a call to a function to which I'm passing as a parameter vec2.....

 if (something) { vec1[i]=vec1[i]-1;}

 }
 }

 }

我认为可能我的并行化代码速度较慢,因为多个线程想要访问同一个共享阵列,而且必须等到另一个完成,但我不确定事情是怎么回事。但我无法将vec1和vec2设为私有,因为在其他迭代中无法看到更新... 我怎样才能改进它?

1 个答案:

答案 0 :(得分:0)

当您在使用多个线程访问同一阵列时谈到问题时,这称为“假共享”。除非您的数组很小,否则它不应该是瓶颈,因为pragma omp parallel for在默认实现中使用静态调度(至少使用gcc)所以每个线程应该访问大部分数组而不是可靠性,除非你的“..涉及调用函数的代码,我将其作为参数传递给vec2 ......“真的可以访问数组中的很多元素。

案例1:您不会在代码的这一部分访问数组中的大多数元素

  • M足以使并行性有用吗?
  • 你能在外环上移动并行吗? (仅有一个循环用于vec1,另一个用于vec2)
  • 尝试移动并行区域代码:

    int vec1 [M];
    int vec2 [N];
    
    ...initialization of vec1 and vec2...
    #pragma omp parallel
    for (int it=0; it < tot_iterations; it++) {
    
        if ( (it+1)%2 != 0 ) {
            #pragma omp for
            for (int j=0 ; j < N ; j++) {
            ....code involving a call to a function to which I'm passing as a parameter vec1.....
    
                if (something) { vec2[j]=vec2[j]-1;}
    
            }
        }
    else {
        # pragma omp for
        for (int i=0 ; i < M ; i++) {
        ....code involving a call to a function to which I'm passing as a parameter vec2.....
    
            if (something) { vec1[i]=vec1[i]-1;}
    
        }
    }
    

这不应该有太大变化,但某些实现会产生代价高昂的并行区域。

案例2:您可以使用每个线程访问每个元素

我会说如果你执行更新就不能这样做,否则,你可能会遇到一致性问题,因为你在循环中有顺序依赖。