for 문에서 OpenMP에서 동적으로 할당된 배열을 Private으로 잡고자 할 때,
그냥
#pragma omp parallel for private(i, j, d, c) shared(a, b)
이런식으로 잡았다가는 동적으로 할당된 배열 (여기에서는 c 가 배열입니다)
을 제대로 접근하지 못하고 이상한 쓰레기값을 자꾸 참조하더군요
그래서 뭐가 문제인가 싶어서 찾아봤습니다.
해답은 여기~
http://stackoverflow.com/questions/2352895/how-to-ensure-a-dynamically-allocated-array-is-private-in-openmp
방법은 parallel 구문 내에서 해당 변수를 동적으로 할당하고
사용하면 된다는 내용입니다.
간단한 소스를 첨부합니다.
(소스의 구조나 기능은 보지 마시고, 그냥 대충 봐주세요^^; 제가 쓰던 소스의 일부를 떼어다 붙이느라 상태가 엉망진창입니다)
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "time.h"
#include <math.h>
#include <afx.h>
#include <omp.h>
#define NUM 5
int main()
{
double *a, *b , *c;
a = new double[NUM];
b = new double[NUM];
double d = 0;
int i, j;
unsigned long elapsed_time = GetTickCount();
for(i = 0 ; i < NUM; i++)
{
a[i] = i+1;
b[i] = (i+1)*2;
}
#pragma omp parallel private(i, j, d, c) shared(a, b)
{
c = new double[NUM]; <---- 여기에서 동적으로 메모리를 할당합니다.
#pragma omp for <------ 그 다음에 for문에 대한 병렬화를 수행합니다.
for(i=0; i< NUM; i++)
{
c[i] = 2 * i + omp_get_thread_num(); <------- 제private 으로 정상작동하는지 테스트를 해보기 위해 thread 번호를 계산에 넣어봤습니다.
for(j = 0; j < NUM; j++)
{
b[i] = (a[i] + a[j]) / 2.0;
d = i * 2 + j * 3 ;
printf("Thread %d, i = %d , j = %d, d = %lf, c[%d] = %lf, output = %lf\n", omp_get_thread_num(), i, j, d , i, c[i], b[i]);
}
}
delete[] c;
}
elapsed_time = GetTickCount() - elapsed_time;
printf("-------Total simulation time : %d seconds = %d mil sec \n", (int)(elapsed_time / 1000), elapsed_time);
getch();
delete[] a;
delete[] b;
return 0;
}
출력해보면 c 에 각각 다른 값이 들어가서 출력되는 것을 확인할 수 있습니다.
대신 c의 메모리 해제 역시 omp 루프 안에서 이루어 져야 합니다.