2010-02-28 409 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不会复制它(可能是因为这会导致需要分配和释放复制的数组)。