2013-10-12 45 views
0

我有以下代碼:OpenMP實施屏障同步不能循環內的工作與if條件

#pragma omp parallel shared(a,n) private(i,j,k,x,pid,rows,mymin,mymax) 
{ 
    // nprocs=1; 
#ifdef _OPENMP 
    nprocs=omp_get_num_threads(); 
#endif 

#ifdef _OPENMP 
    pid=omp_get_thread_num(); 
#endif 

    rows=n/nprocs; 
    mymin=pid * rows; 
    mymax=mymin + rows - 1; 

    for(k=0;k<n;k++){ 
     if(k>=mymin && k<=mymax){ 
#pragma omp for schedule(static,rows) 
      for(x=k+1;x<n;x++){ 
       a[k][x]= a[k][x]/a[k][k]; 
      } 
#pragma omp barrier 
     } 
    } 
} 

在這裏,我選擇哪個線程將根據if條件更新矩陣的哪一行。例如,如果有兩個線程,線程1將更新矩陣'a'的前兩行,而線程2將更新另外兩個線程。

而我選擇後,我通過並行線程1和2之間的內部循環(其中我開始for(x=k+1,x<n;x++))將該行的列迭代分開。我也在內循環之後放置一個屏障,以便在更新單行的每個列值後,將其同步。

但問題是我沒有得到正確的同步值。在最終矩陣中,線程0更新的一些值在一些行中顯示,而一些由其他線程顯示,但不是全部。

回答

1

使用omp barrier這裏沒有用處,因爲除非指定了nowait子句,否則omp for構造的末尾存在隱式屏障。

另一方面,您不需要手動指定如何將工作分解爲線程,並且分解方式不正確。

你正在嘗試做的事實上可以寫成如下。

#pragma omp parallel for shared(a,n) private(k,x) 
for(k=0;k<n;k++){ 
    for(x=k+1;x<n;x++){ 
     a[k][x]= a[k][x]/a[k][k]; 
    } 
} 

由於工作量不跨越不同k平衡的,你可能需要使用schedule(dynamic, ...)條款爲好。有關更多信息,請參閱omp文檔。

http://msdn.microsoft.com/en-us/library/b5b5b6eb.aspx