중첩 스레드
- 루프 안에 루프가 나오는경우를 -> 중첩 루프문이라 함
- 스레드 안에 스레드가 생성되는 경우
=> 병렬 구문 안에 다시 병렬 구문 쓰기
중첩 스레드문 작성
- omp_set_nested(1); 중첩 스레드 기능 on
* 런타임 라이브러리 말고, 환경변수로도 지정가능 OMP_NESTED=TRUE(or 1)
- 중첩 스레드 기능 확인하기 : get_nested() -> 0은 꺼짐, 1은 켜짐
#include <stdio.h>
#include <omp.h>
int main()
{
int tid;
omp_set_nested(1);
omp_set_num_threads(2);
#pragma omp parallel private(tid)
{
tid = omp_get_thread_num();
printf("thread id = %d\n", tid );
if( tid == 1) {
#pragma omp parallel private(tid)
{
tid = omp_get_thread_num();
printf("\t thread id = %d\n", tid );
}
}
} // end #pragma omp parallel
}
중첩 스레드문 실행 결과
- 스레드 갯수 2개 설정하여 처음 2개 생성
- tid == 1인 경우 스레드 다시 생성 -> 1번 스레드 내부에서 2개 또 생성
- tid == 1 조건이 없는 경우 -> 1번 스레드, 2번 스래드 둘다 내부에서 2개 생성
더 많은 중첩 스레드
- 스레드 4개 생성, tid와 level private 처리
- tid가 2번인 경우 중첩 스레드 생성
- 중첩 스래드 내부 tid다시 private
- 이 중첩 스래드들의 조상은 2번 스레드(tid == 2 조건에 의해)
#include <stdio.h>
#include <omp.h>
int main()
{
int tid, level;
omp_set_nested(1);
omp_set_num_threads(4);
#pragma omp parallel private(tid, level)
{
tid = omp_get_thread_num();
level = omp_get_level();
printf("tid = %d level = %d\n", tid, level);
if( tid == 2) {
#pragma omp parallel private(tid) num_threads(tid+2)
{
tid = omp_get_thread_num();
printf("\ttid = %d ancestor_thread_num(%d)=%d\n", tid, level, omp_get_ancestor_thread_num(level) );
}
}
} // end #pragma omp parallel
}
중첩 스레드문 데이터 범위
1. 스래드 갯수
- 바깥 스레드에서 y, tid만 private, 스래드 갯수는 4개
- 내부 스레드에서 x, tid가 private, 내부 스레드 갯수는 2개
2. 중첩 스래드 영역 x, y, z(shared)
- 중첩 스레드 영역 x = 10
- 중첩 스레드 tid = 0일때, 상위에서 y = 12 -> y++ -> y = 13이됨.
- 중첩 스레드 tid = 1일때, y = 13 -> y++ -> y= 14가 됨
- 중첩 스레드 상위에서 z = 22 -> 4개의 스레드가 중첩 스래드 2개씩 생성 총 8개
=> 22 ~ 30까지 z가 상승
3. 중첩 스레드 밖, 스래드 안
- z는 shared이므로 30으로 고정
- x = 1 -> x++을 스래드 4개 반복 -> x = 5가 출력
- y = 12 -> 중첩 스레드에서 2번 y++ -> y = 14로 출력
- tid = 0 ~3 까지 x = 5, y = 14, z = 30
4. 스래드 밖
- z는 shared로 30
- x는 4번 ++했으므로 5
- y는 스레드 구문에서 private이므로, 초기화 10 그대로
=> x = 5, y = 10, z = 30
#include <stdio.h>
#include <omp.h>
int main()
{
int x=1, y=10, z=20, tid;
omp_set_nested(1);
omp_set_num_threads(4);
#pragma omp parallel private(y, tid)
{
tid = omp_get_thread_num();
x++;
y = 12;
z = 22;
#pragma omp parallel num_threads(2) private(x,tid)
{
tid = omp_get_thread_num();
x = 10;
y++;
z++;
printf("\t tid=%d x=%d y=%d z=%d\n", tid, x, y, z);
}
printf("tid=%d x=%d y=%d z=%d\n", tid, x, y, z);
} // end #pragma omp parallel
printf("x=%d y=%d z=%d\n", x, y, z);
}
'컴퓨터과학 > 기타' 카테고리의 다른 글
openmp - 21. nowait (0) | 2020.07.30 |
---|---|
openmp - 20. 작업 분할 지시어들 (0) | 2020.07.30 |
openmp - 18. 병렬 블록, 포크 조인, 동기화 문제 (0) | 2020.07.30 |
openmp - 17. pi계산에서의 병렬화를 통한 성능 개선 (0) | 2020.07.29 |
openmp - 16. reduction과 factorial (0) | 2020.07.29 |