C语言 如何确保动态分配的数组在 openmp 中是私有的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2352895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to ensure a dynamically allocated array is private in openmp
提问by cboettig
I'm working in C with openMP using gcc on a linux machine. In an openmp parallel for loop, I can declare a statically allocated array as private. Consider the code fragment:
我在 Linux 机器上使用 gcc 使用 openMP 在 C 中工作。在 openmp 并行 for 循环中,我可以将静态分配的数组声明为私有数组。考虑代码片段:
int a[10];
#pragma omp parallel for shared(none) firstprivate(a)
for(i=0;i<4;i++){
And everything works as expected. But if instead I allocate a dynamically,
一切都按预期进行。但是如果我动态分配一个,
int * a = (int *) malloc(10*sizeof(int));
#pragma omp parallel for shared(none) firstprivate(a)
the values of a (at least a[1...9]) are not protected but act as if they are shared. This is understandable as nothing in the pragma command seems to tell omp how big the array a is that needs to be private. How can I pass this information to openmp? How do I declare the entire the dynamically allocated array as private?
a(至少 a[1...9])的值不受保护,但就像它们是共享的一样。这是可以理解的,因为 pragma 命令中似乎没有任何内容告诉 omp 需要私有的数组 a 有多大。如何将这些信息传递给 openmp?如何将整个动态分配的数组声明为私有?
回答by
I don't think you do - what I did to solve this problem was used a parallel region #pragma omp parallel shared(...) private(...)and allocated the array dynamically inside the parallel region. Try this:
我不认为你这样做 - 我为解决这个问题所做的是使用并行区域#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]);
}
}
That to me produced the same results as my earlier experiment program:
对我来说,这产生了与我之前的实验程序相同的结果:
#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]);
}
}
At a guess I'd say because OpenMP can't deduce the size of the array it can't be private - only compile-time arrays can be done this way. I get segfaults when I try to private a dynamically allocated array, presumably because of access violations. Allocating the array on each thread as if you'd written this using pthreads makes sense and solves the issue.
我猜测是因为 OpenMP 无法推断数组的大小,所以它不能是私有的 - 只有编译时数组可以通过这种方式完成。当我尝试私有一个动态分配的数组时,我得到了段错误,大概是因为访问冲突。在每个线程上分配数组就好像您使用 pthreads 编写的一样有意义并解决了问题。
回答by Riko Jacob
You told OpenMP that the pointerais private, i.e. replicated in each thread. Your array is just some arbitrary data apoints to, and OpenMP will not replicate it (perhaps because this would make it necessary to allocate and deallocate the replicated arrays).
您告诉 OpenMP 该指针a是私有的,即在每个线程中复制。您的数组只是一些任意数据a点,OpenMP 不会复制它(可能是因为这需要分配和取消分配复制的数组)。

