[Directive] critical

병렬프로그래밍에서 특별한 언급이 없으면, 모든 쓰레드들은 독립적이지 않은 공통변수들을 가지게 됩니다. 그래서 공통변수를 업데이트 시키는 동안에 다른 쓰레드에서 중간에 업데이트 하는 경우도 있습니다. 이러한 상황은 정확화지 않은 결과를 불러오게 됩니다. 그래서 공통변수가 업데이트 되는동안, 변하지 않도록 보호를 해주어야 합니다. atomic과 critical 디렉티브가 이러한 역할을 합니다. atomic 은 간단한 사칙연산이나 논리사칙연산에 대해서 보호해주는 역할을 하며, critical 디렉티브는 이를 포함한 좀더 범용적인 상황에서 보호를 해줍니다. critical 디렉티브 예제를 살펴봅시다.

[Fortran 90]
program Console
    implicit none
    !Variables
    integer i
    real max
    parameter SIZE = 10
    real :: a(SIZE)
   
    do i=1,SIZE
        call RANDOM_NUMBER(a(i))
        write(*,"(E10.5)"), a(i)
    end do
   
    max = a(1)
    !$omp parallel do num_threads(4)
    do i=2, SIZE
        if (a(i) > max) then
            !$omp critical
            ! compare a[i] and max again because max  
            ! could have been changed by another thread after  
            ! the comparison outside the critical section
            if (a(i) > max) then
                max = a(i)
            end if
            !$omp end critical
        end if
    end do
    !$omp end parallel do
   
    write(*,"(A6, F10.5)"), "max = ", max
    end program Console

[Output]
.39209E-06
.25480E-01
.35252E+00
.66691E+00
.96306E+00
.83829E+00
.33536E+00
.91533E+00
.79586E+00
.83269E+00
max =    0.96306


조건문이 두번 들어가는데 조건을 판단하는 동안, max 값이 변할 수 있으므로 critical 로 락을 걸어주고, 다시 한번 조건을 판단해줄 필요가 있습니다. 마지막으로 critical 이 지원하는 clause 는 없습니다.

출처 - https://msdn.microsoft.com/en-us/library/b38674ky.aspx

댓글

이 블로그의 인기 게시물

[Linux, AIX] 사용자 계정 생성 및 설정

[AIX] rpm 설치와 rpm 으로 패키지 설치 및 삭제

Ubuntu 에서 Fortran 시작하기