728x90

중첩 스레드

- 루프 안에 루프가 나오는경우를 -> 중첩 루프문이라 함

- 스레드 안에 스레드가 생성되는 경우

 => 병렬 구문 안에 다시 병렬 구문 쓰기

 

중첩 스레드문 작성

- 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);
}

300x250

+ Recent posts