2013-03-08 71 views
48

我看了官方定義,但我仍然很困惑。在OpenMP中,firstprivate和lastprivate與private子句有何不同?

firstprivate:指定每個線程都應該有自己的變量的實例,該變量應與變量的值進行初始化,因爲它的並行構造之前就存在。

對我來說,這聽起來很像私人。我查找了一些例子,但我似乎不明白它的特殊性或如何使用。

lastprivate:指定封閉上下文的變量的版本設置等於兩者的線程執行的最後一次迭代(for循環結構),或最後一節的函數(#pragma段)專用版本。

我覺得我理解這一個好一點,因爲下面的例子:

#pragma omp parallel 
{ 
    #pragma omp for lastprivate(i) 
     for (i=0; i<n-1; i++) 
     a[i] = b[i] + b[i+1]; 
} 
a[i]=b[i]; 

所以,在這個例子中,我瞭解到,lastprivate允許i的環路以外的地方返回最後的價值。

我剛開始學習OpenMP今天。

回答

103

private變量未初始化,即它們像任何其他本地自動變量一樣以隨機值開始(並且它們通常使用每個線程的堆棧上的自動變量實現)。藉此簡單的程序作爲一個例子:

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

int main (void) 
{ 
    int i = 10; 

    #pragma omp parallel private(i) 
    { 
     printf("thread %d: i = %d\n", omp_get_thread_num(), i); 
     i = 1000 + omp_get_thread_num(); 
    } 

    printf("i = %d\n", i); 

    return 0; 
} 

四個線程它輸出類似:

thread 0: i = 0 
thread 3: i = 32717 
thread 1: i = 32717 
thread 2: i = 1 
i = 10 

(another run of the same program) 

thread 2: i = 1 
thread 1: i = 1 
thread 0: i = 0 
thread 3: i = 32657 
i = 10 

這清楚地證明的i的值是隨機的(未初始化)並行區域內,並且對平行區域後的任何修改都不可見(即變量在進入區域之前保留其值)。

i如果由firstprivate,那麼它被初始化與它平行的區域之前的數值:

thread 2: i = 10 
thread 0: i = 10 
thread 3: i = 10 
thread 1: i = 10 
i = 10 

仍然修改的i並行區域內的值不是後可見。

您已經知道lastprivate(並且它不適用於簡單演示程序,因爲它缺少工作共享結構)。因此,和lastprivate只是private的特例。第一個結果是將來自外部上下文的值引入並行區域,而第二個將來自並行區域的值傳送到外部上下文。這些數據共享類背後的基本原理是在並行區域內,所有私有變量都會影響外部環境中的私有變量,即無法使用賦值操作來修改並行區域內的外部值i

+1

這是一個很好的答案!非常感謝你! – SaiyanGirl 2013-03-11 16:29:43

+0

好吧,我會說rater,'firstprivate'和'lastprivate'是'private'的非常特殊情況。您通常甚至不需要使用'private'(只需在並行塊中定義變量),可能會影響外部範圍。有趣的是將C++對象用作自動'firstprivate'變量 - 它們將通過copy-construction初始化一次,並在塊之後被銷燬,並且不需要事先知道線程數量 - 根據需要創建。 – 2014-09-18 07:26:17

+0

這樣一個很好的例子!最喜歡它。感謝Hristo。 – Fusionmate 2015-03-02 07:55:57

1

firstprivatelastprivate只是private的特殊情況。

第一個將外部上下文中的值引入並行區域,第二個將值從並行區域傳遞到外部上下文。

+0

可否提供任何有關它的參考? – 2017-01-20 10:41:43

相關問題