본문 바로가기

Programming/OpenMP

OpenMP 작업 분할(Work Sharing) 지시어

  • 작업 분할(Work Sharing) 지시어

 

수행해야 할 작업들을 생성된 스레드 팀에 적절하게 배분하여, 병렬 수행하도록 지정하는 지시어를 작업 분할 지시어라고 한다. for 지시어, sections 지시어, single 지시어, task 지시어가 있다.

 

1. for 지시어

for 지시어는 #pragma omp parallel 영역 안에서 사용되며, #pragma omp for 지시어 다음에 오는 for루프 문을 병렬화 한다.

for 루프 문을 수행할 때 작업을 배분해주는 양이나 방법을 정하는 규칙을 스케줄(schedule)이라고 한다. for 루프 문의 디폴트 스케줄은 static으로 반복 루프 수행할 총 횟수를 스레드에 개수로 나누어 스레드 별로 동일하게 배분해준다.

 

문법

#pragma omp for [보조 지시어 [, 보조지시어]]

for (초기값조건식증감값)

{

구조블럭 //코드작성

}

}


 

사용가능한 보조 지시어

#pragma omp for private(변수명)

#pragma omp for firstprivate(변수명)

#pragma omp for lastprivate(변수명)

#pragma omp for reduction(오퍼레이터:변수명)

#pragma omp for schedule(스케줄타입 [,덩어리사이즈])

#pragma omp for collapse(정수)

#pragma omp for ordered

#pragma omp for nowait


 

병렬의 중첩

2개 이상 for 문이 사용되었을 경우 최외곽 for문에 대해서만 병렬화가 처리되며, 2개 이상의 for 문에 대해서 병렬화하기 위해서는 nest 지시어와 같이 내포 병렬화를 지정해 주어야 한다.

 

 

 

2. sections 지시어

#pragma omp sections 지시어는 루프의 반복작업 없이 여러 스레드에 작업단위로 분배하는 병렬로 처리하는 기능을 한다. 스레드 팀에 있는 각각 스레드를 #pragma omp section 지시어로 작업을 나눈다. 해당 작업은 스레드 팀 중에서 하나의 스레드에 의해 한 번만 실행 된다.

 

문법

#pragma omp sections [보조지시어 [, 보조 지시어...]]

{

#pragma omp section

{

작업1;

]

#pragma omp section

{

작업2;

}

}


 

함께 사용 가능한 보조 지시어

#pragma omp sections private(변수명)

#pragma omp sections firstprivate(변수명)

#pragma omp sections lastprivate(변수명)

#pragma omp sections reduction(오퍼레이터:변수명)

#pragma omp sections schedule(종별 [,체크사이즈])

#pragma omp sections collapse(정수)

#pragma omp sections ordered

#pragma omp sections nowait


 

3. single 지시어

#pragma omp single 지시어는 스레드 팀 중 하나의 스레드만 해당 코드를 실행할 것을 지정한다. 다른 스레드 들은 single 지시어로 지정된 스레드가 실행을 완료할 때까지 #pragma omp single의 구조블록의 마지막 지점에서 암시적 동기로 대기한다.

 

문법

#pragma omp single [보조 지시어 [, 보조지시어...]]

{

구조블럭

} //여기서 다른 스레드들은 완료를 기다린다.


 

사용가능한 보조 지시어

#pragma omp single private(변수명)

#pragma omp single firstprivate(변수명)

#pragma omp single copyprivate(변수명)

#pragma omp single nowait


 

주의사항

1) #pragma omp single 지시어로 지정된 영역은 반드시 마스터 스레드에 의해 실행되는 것은 아니다. 스레드 팀의 맴버 중 어느 스레드에 의해 실행되는지 알 수 없다.

2) single 지시어는 for 구문 안에 기술할 수 없다.

3) single 지시어는 nowait 보조 지시어와 copyprivate 보조 지시어를 동시에 이용할 수 없다.

4) C++에서는 single 지시어 영역 내에서 throw된 예외는 single 지시어 영역 내에서 실행을 재개해야 한다. 그리고 throw된 예외는 동일 스레드에 의해서 catch 되어야 한다.

 

 

4. task 지시어

OpenMP 3.0부터 추가된 #pragma omp task 지시어는 이전에 병렬화가 힘들었던 while 루프, C++ 반복자(iterator), 재귀함수 등을 병렬화하는 기능을 한다. task 지시어는 수행해야 할 코드의 작업을 큐에 넣는 동작을 한다. 이후 task 지시어는 스레드 팀과 작업 큐(Queue)를 연결(binding)하여, 작업 큐에 있는 코드들을 스레드 팀이 실행할 수 있게 한다. 작업 큐에 있는 코드들은 스레드팀 중에서 수행 가능한 스레드가 발생하는 순서대로 작업을 실행한다. 태스크 작업 큐에 넣은 동작을 할 때는, 병렬영역에서 다수의 스레드가 동작하여 동기화 문제가 발생할 수 있기 때문에 통상적으로 “#pragma omp single” 지시어와 사용하여 하나의 스레드로 동작하게 된다.

 

task 지시어는 암묵적 동기화가 지원되지않아 task 지시어의 처리 종료까지 기다리도록 하려면 taskwait 지시어를 사용한다.

 

문법

#pragma omp task

{

구조블록;

}


 

함께 사용가능한 보조 지시어

#pragma omp task if(스칼라식)

#pragma omp task untied

#pragma omp task default(shared 혹은 none)

#pragma omp task private(변수명)

#pragma omp task firstprivate(변수명)

#pragma omp task shared(변수명)


 

제한사항

C/C++에서는 #pragma omp task 영역 내에서 throw된 예외는 같은 task 영역 내에서 실행을 재개해야 한다. 그리고 throw된 예외는 같은 스레드에 의해서 catch 되어야 한다.

반응형
LIST