2014-04-08 42 views
1

共享我有一個結構如果指針(和指針的指針......)在OpenMP的

typedef struct mystruct { 
int* a; 
float** b; 
} mystruct; 


mystruct* s = (mystruct*) calloc(1, sizeof(mystruct)); 
s->a = (int*) calloc(100, sizeof(int)); 
s->b = (float**) calloc(100, sizeof(float*)); 

for (int i=0; i<100; i++) 
s->b[i] = (float*) calloc(100, sizeof(float)); 

如果我聲明s在OpenMP的共享作爲什麼將被分享:

#pragma omp parallel for shared(s) schedule(auto) 

將全部在存儲器中的以下變量的所有線程共享:

  • 指針a

  • 陣列指向a,即a[i], i=0,...,99

  • 指針b

  • 陣列通過b指向,即b[i], i=0,...,99

  • 陣列指向b[i], i=0,...,99,即b[i][j], j=0,...,99

如果在OpenMP中共享指針(以及指向...的指針),將共享什麼

謝謝!

+0

然後它中的所有內容都被共享。如果它被宣佈爲私有,我會更感興趣知道會發生什麼。 – Medinoc

+0

@Medinoc,你可以在這裏找到你的答案http://stackoverflow.com/questions/22204495/local-pointers-in-openmp/22221504#22221504。查看動態數組和私有部分。 –

回答

2

指針是變量,其值是給定內存單元的地址(或一組單元的開始)。共享指針共享變量本身,即存儲地址的指定內存位置。

由指針指向的堆內存始終共享,因爲沒有任何東西阻止您通過現有的有效指針從其他線程訪問堆內存。

以下情況是可能的:

  • shared(a)意味着指示器被所有線程共享。如果任何線程修改a,例如,執行a++或爲其分配一個新值,該指針也會在所有其他線程中更改。由於指針的值在所有線程中都是相同的,它們都可以訪問它指向的內存,即內存是共享的;

  • private(a)表示指針對每個線程都是私有的。每個線程都獲得自己的未初始化的指針變量。如果一個線程分配給a,則更改在其他線程中不可見。由於私有副本沒有被初始化,所以在並行區域之外的a所指向的內存在線程中是不可見的,除非有另一個指向它的指針或者除非另一個機制獲得指向內存的指針;

  • firstprivate(a)意味着指針對每個線程都是私有的,但最初所有私有副本在並行區域之前設置爲值a。在這種情況下,每個線程都可以修改a的值,這些修改將不會被其他線程看到。只要a的所有副本指向內存中原始值爲a指向的某處,則通過本地副本a所做的修改對所有線程均可見,因此內存塊將被共享。

private(a)這種情況沒什麼意義,建議使用塊本地變量。這意味着,代替

int *p; 

#pragma omp parallel private(p) 
{ 
    ... 
} 

一個建議(爲了清楚起見)使用

#pragma omp parallel 
{ 
    int *p; 
    ... 
} 

數據共享子句隻影響指針變量和它指向的存儲器。例如,private(a)分配堆存儲器的專用副本最初指向a

int *a = malloc(10 * sizeof(int)); 

#pragma omp parallel private(a) 
{ 
    a[1] = ... // <--- WRONG - no memory allocated automatically by OpenMP 
} 

一種有用的使用情況是一個其中每個線程分配其專用堆存儲器:

#pragma omp parallel 
{ 
    int *a = malloc(10 * sizeof(int)); 
    ... 
    free(a); 
} 

堆內存保持對每個線程都是私有的,除非它的地址在使用共享指針的線程之間共享。

這同樣適用於指向指針的指針。