2016-01-23 53 views
0

我想并行化一块C++代码与OpenMp,但我面临一些问题。事实上,我的并行代码并不比串行代码快。 我想我已经理解了这个原因,但我无法解决它。在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保密,因为在其他迭代中不会看到更新... 我该如何改进它?

回答

0

当您在使用多个线程访问同一个数组时遇到问题时,这称为“假分享”。除非你的数组很小,否则它不应该成为瓶颈,因为pragma omp parallel for在默认实现中使用静态调度(至少使用gcc),因此每个线程都应该访问大部分数组,除非你的“...涉及调用我作为参数vec2传入的函数.....“真正访问数组中的很多元素。

案例1:你不访问大多数元素的数组中的代码

  • ,这部分是M大到足以使并行有用吗?
  • 你可以在外环上移动平行度吗? (有一个循环只有VEC 1,另一个用于VEC 2只)
  • 尝试移动并行区域代码:

    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:你访问的每个元素与每个线程

我会说你不能这样做,如果你执行更新,否则,你可能有并发性问题,因为你必须在循环顺序的依存关系。