[OpenMP] 이해가 않되는 스레드 흐름

#include "stdafx.h"
#include 
#include 

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 1;
#pragma omp parallel
    {
#pragma omp sections firstprivate(a) lastprivate(a)
        {
#pragma omp section
            {
                Sleep(1000);
                printf("section 1: a 초기값 = %d\n", a);
                a = 2;
                printf("section 1: a 수정값 = %d\n", a);
            }
#pragma omp section
            {
                printf("section 2: a 초기값 = %d\n", a);
                a = 3;
                printf("section 2: a 수정값 = %d\n", a);
            }
        }
    }

    printf("a 최종값 = %d\n", a);

    return 0;
}

이 코드는 스레드를 2개 사용하고 있습니다. 즉 section 지시어를 통해 13~18번 코드를 실행하는 스레드 하나와 20~24번 코드를 실행하는 스레드 하나입니다. 10번 코드에서 lastprivate(a)라는 보조 지시어를 통해 2개의 스레드에서 연산한 결과 a가 복사됩니다. 14번 코드에 Sleep 함수를 호출함으로써 두개의 스레드 중 a에 2를 할당한 스레드가 가장 마지막에 끝나도록 했습니다. a에 2를 할당한 스레드가 마지막에 종료되니.. 이 2개의 스레드가 끝나면 a 값은 항상 2가 될거라 예상됩니다.

사용자 삽입 이미지
근데.. 보는 바와 같이 a의 최종값이 3이라고 합니다.. ㅡOㅡ;; 실행 흐름을 봐도 가장 먼저 a 수정값으로 3을 할당하고 다음 실행으로 a 수정값으로 2를 할당하는 순서입니다. 실행 순서는 예상과 같은데.. 결과는 반대입니다.. ㅡOㅡ;; 아직 OpenMP를 학습하는 단계인지라.. 이해가 떨어져서 그런 것인지.. 아니면 OpenMP의 BUG인지… 모를 일입니다.. 누구 아시는 분 코칭 부탁드립니다.

“[OpenMP] 이해가 않되는 스레드 흐름”에 대한 5개의 댓글

    1. 네, section은 스레드를 만들어 수행하라는 지시어인데.. section 다음의 {에서 시작해서 }로 끝나는 코드 부분을 별도의 스레드로 빼내어 수행하라는 의미입니다.

  1. printf(“a 최종값 = %d\n”, a);
    코드를 #pragma omp parallel의 대괄호 안에 넣고
    #pragma omp sections firstprivate(a) lastprivate(a) nowait로 수정해서
    테스트해봤습니다.
    업데이트가 마지막으로 종료되는 section에서 일어나는 것이 아니라 마지막으로 시작되는 section에서 일어나는것 같습니다.. openMP에 대한 지식이 없어서 추측만 해봅니다.;;

  2. [14번 코드에 Sleep 함수를 호출함으로써 두개의 스레드 중 a에 2를 할당한 스레드가 가장 마지막에 끝나도록 했습니다.] 이 부분을 다시 생각하셔야 할 것 같습니다.
    Sleep으로 ‘이 스레드가 앞에/뒤에 실행될 것이다’ 라는 판단을 하면 안 됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다