본문 바로가기

Programming

OpenMP에서 동적할당된 메모리를 private 형식으로 잡기


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 루프 안에서 이루어 져야 합니다.