2010-02-28 418 views
9

我正在C中使用openMP在linux機器上使用gcc。在openmp並行for循環中,我可以聲明靜態分配的數組爲private。考慮代碼片段:如何確保動態分配的數組在openmp中是私有的

int a[10]; 
#pragma omp parallel for shared(none) firstprivate(a) 
for(i=0;i<4;i++){ 

而且一切都按預期工作。但是,如果代替我分配一個動態,

int * a = (int *) malloc(10*sizeof(int)); 
#pragma omp parallel for shared(none) firstprivate(a) 

所述的值的(至少一個[1 ... 9])沒有被保護,但是充當如果它們共享。這是可以理解的,因爲編譯指令中的任何內容似乎都沒有告訴omp數組需要是多大才是私有的。我怎樣才能將這些信息傳遞給openmp?我如何將整個動態分配的數組聲明爲私有?

回答

12

我不認爲你這樣做 - 我所做的解決這個問題的方法是使用並行區域#pragma omp parallel shared(...) private(...)並在並行區域內動態分配數組。試試這個:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test2 -fopenmp test2.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 
    int* c; 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel shared(a,b) private(c,i) 
    { 
     c = (int*) calloc(3, sizeof(int)); 

     #pragma omp for 
     for (i = 0; i < size; i++) 
     { 
      c[0] = 5*a[i]; 
      c[1] = 2*b[i]; 
      c[2] = -2*i; 
      a[i] = c[0]+c[1]+c[2]; 

      c[0] = 4*a[i]; 
      c[1] = -1*b[i]; 
      c[2] = i; 
      b[i] = c[0]+c[1]+c[2]; 
     } 

     free(c); 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

這對我產生了相同的結果,我剛纔的實驗計劃:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test1 -fopenmp test1.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel for shared(a,b) private(i) 
    for (i = 0; i < size; i++) 
    { 
     a[i] = 5*a[i]+2*b[i]-2*i; 
     b[i] = 4*a[i]-b[i]+i; 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

在猜測我會說,因爲OpenMP的不能推導出數組的大小它可以不是私有的 - 只有編譯時數組可以這樣完成。當我試圖私有一個動態分配的數組時,我得到了segfaults,可能是因爲訪問衝突。在每個線程上分配數組就好像您使用pthreads編寫這個數組是合理的並解決了這個問題。

+0

謝謝,分開openmp聲明和parallel聲明似乎完美地工作。 – cboettig 2010-03-01 01:13:12

+0

@Ninefingers:我知道這個帖子很舊,但我有一個快速的問題。你甚至需要'#pragma omp for'語句嗎?不管它是否並行執行該循環? – Amit 2012-06-08 18:39:38

+1

@Amit nope,你需要告訴編譯器突破線程,否則它不會。 – 2012-06-09 16:23:40

6

您告訴OpenMP指針指針a是私有的,即在每個線程中複製。你的數組只是一些任意的數據,並且OpenMP不會複製它(可能是因爲這會導致需要分配和釋放複製的數組)。