2013-06-25 57 views
0

我想運行以下代碼來了解OpenMP lastprivate構造的功能。根據lastprivate的定義,如果我聲明變量lastprivate,則它對每個線程都是私有的,並且按順序執行並行循環的最後一次迭代的線程的值被複制到該區域之外的變量。 下面是代碼:爲什麼OpenMP lastprivate產生錯誤的結果?

int main(void) 
{ 
    omp_set_num_threads(5); 
    int i; 
    int k =3; 
    #pragma omp parallel private(i) 
    { 
     #pragma omp for lastprivate(k) 
     for(i=0; i< 5; i++) 
     { 
      int iam = omp_get_thread_num(); 
      k = iam; 
      printf("k=%d, iam=%d\t",k, iam); 
     } 
    } 

    printf("\n k = %d", k); 
} 

它產生的輸出是這樣的:

k=0, iam=0 k=4, iam=4 k=3, iam=3 k=2, iam=2 k=1, iam=1 
k = 4 

當我們有一個團隊在「for」的工作線程,我們確實不能保證哪個線程執行最後一次。所以,相應地,最後一個線程的值應該反映在全局'k'中。然而,無論我運行多少次代碼,全局值(即並行段結束之後)'k'的值仍然爲4.

從打印值中也可以看出最後執行的線程1。即使我們認爲印刷品不可靠以獲得線程的確切運行順序,但看起來很不明顯,線程4總是最後運行,從而將其值'k'反映出來。

我將不勝感激關於這個問題的幫助。謝謝。

回答

1

可以肯定的是哪個線程執行最後,你應該打印迭代索引值(而不是複製線程id):

#include<stdio.h> 
#include<omp.h> 

int main() { 
    int kk; 
#pragma omp parallel 
    { 
#pragma omp for schedule(runtime) lastprivate(kk) 
    for(int ii=0; ii < 1000; ii++) { 
     kk = omp_get_thread_num(); 
     printf("ii = %d, kk = %d\n",ii,kk); 
    } 
    } 
    printf("kk = %d\n", kk); 
    return 0; 
} 

如果運行這個程序,你會發現線程來執行迭代999設置值爲kk

關於這句話(重點煤礦):

當我們有一個團隊在「for」,我們確實不能保證工作線程的線程執行最後

你說的是大致如此,但有一個例外(2.5節的OpenMP 3.1標準。):

不同與相同時段和迭代次數環路地區, 即使它們出現在相同的並行區域,可以不同地分配線程間的迭代。 唯一的例外是 靜態時間表 ...現在

,因爲你沒有指定任何時間表,以下規則成立:

如果循環指令沒有時間表條款,則DEF-SCHED-VAR目前 值ICV確定時間表

如果def-sched-var確定schedule(static)(因爲我已經經歷了很多倍的情況下),那麼你的程序的最終打印將總是k = 4

+0

謝謝,這特別回答我的疑問。 – Shrik

0

你混淆了兩個不同的「最後」的想法。

的標準說「當一個LASTPRIVATE子句出現在標識工作分享結構,每一個新的列表項的從連續的值相關聯的循環的最後一次迭代的指令」

這隻字未提順序哪些東西在執行,而你假設「last」意味着要執行的時間上最後一個線程。所以如果你有靜態循環調度來保證最高編號的線程將執行最後一個循環迭代,因此保存的值將始終是來自最高編號線程的值,並且它與特定的(隨機的)線程發生執行的順序。

相關問題