Я работаю в C с openMP, использующим gcc на машине Linux. В параллели 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? Как я объявляю все динамично выделенный массив как частное?
Я так не думаю - то, что я сделал для решения этой проблемы, было использовано в параллельной области #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, имеет смысл и решает проблему.