수색…


매개 변수

매개 변수
private 쉼표로 구분 된 개인 변수 목록
firstprivate private 과 같지만 루프에 들어가기 전에 변수의 값으로 초기화됩니다.
lastprivate private 와 마찬가지로 변수는 exit시 루프의 마지막 반복에 해당하는 값을 가져옵니다.
reduction 감소 연산자 : 쉼표로 구분 된 해당 감소 변수 목록
schedule 선택 사항 인 청크 크기가있는 static , dynamic , guided , auto 또는 runtime
collapse 축소 및 병렬 처리 할 완벽하게 중첩 된 루프 수
ordered 루프의 일부분을 순차적으로 보관할 필요가 있음을 알려줍니다 (이 부분은 루프 본문 내에서 ordered 절로 명확하게 식별됩니다)
nowait 루프 구문의 끝 부분에 기본적으로 존재하는 암시 적 장벽 제거

비고

schedule 절의 의미는 다음과 같습니다.

  • static[,chunk] : 라운드 로빈 방식으로 chunk 크기의 일괄 처리 된 루프 반복을 정적으로 (즉, 루프에 들어가기 전에 배포가 이루어진다는 의미로) 배포하십시오. chunk 가 지정되지 않은 경우 chunk 는 가능한 한 균일하고 각 스레드는 최대 하나를 얻습니다.
  • dynamic[,chunk] : 일괄 처리가 남아 있지 않을 때까지 선착순 정책으로 chunk 크기의 일괄 처리로 스레드 사이에 루프 반복을 배포합니다. 지정하지 않으면 chunk 가 1로 설정됩니다.
  • guided[,chunk] : dynamic 것처럼 보이지만 크기가 점점 작아지는 배치를 사용하면 1까지 내려갑니다.
  • auto : 컴파일러 나 런타임 라이브러리가 무엇이 가장 적합한 지 결정하게하십시오.
  • runtime : OMP_SCHEDULE 환경 변수를 사용하여 runtime 에 결정을 OMP_SCHEDULE 하십시오. 런타임에 환경 변수가 정의되어 있지 않으면 기본 스케줄링이 사용됩니다

schedule 의 기본값은 구현 정의 입니다. 많은 환경에서 static 이지만 dynamic 수도 있고 auto 수도 있습니다. 따라서 구현이 명시 적으로 설정하지 않고 암묵적으로 의존하지 않도록주의하십시오.

위의 예제에서 우리는 융합 된 형태를 parallel for 또는 parallel do 사용했습니다. 그러나 루프 구조는 parallel 영역 내에서 #pragma omp for [...] 또는 !$omp do [...] 독립 실행 형 지시문의 #pragma omp for [...] 형태로 parallel 지시문과 함께 사용하지 않고 사용할 수 있습니다.

Fortran 버전의 경우에만 parallized 루프의 루프 인덱스 변수가 기본적으로 항상 private 입니다. 따라서 명시 적으로 private 선언 할 필요는 없습니다 (오류는 발생하지 않음).
C 및 C ++ 버전의 경우 루프 인덱스는 다른 변수와 같습니다. 따라서 범위가 병렬 처리 된 루프 외부로 확장되는 경우 for ( int i = ...) 와 같이 선언되지 않고 for ( int i = ...) 와 같이 선언 된 경우 for ( int i = ...) int i; ... for ( i = ... ) private 로 선언 해야합니다 .

C의 전형적인 예

#include <stdio.h>
#include <math.h>
#include <omp.h>

#define N 1000000

int main() {
    double sum = 0;

    double tbegin = omp_get_wtime();
    #pragma omp parallel for reduction( +: sum )
    for ( int i = 0; i < N; i++ ) {
        sum += cos( i );
    }
    double wtime = omp_get_wtime() - tbegin;

    printf( "Computing %d cosines and summing them with %d threads took %fs\n",
            N, omp_get_max_threads(), wtime );

    return sum;
}

이 예제에서는 100 만 코사인을 계산하고 그 값을 병렬로 합계합니다. 또한 병렬 처리가 성능에 어떤 영향을 주는지 여부를 확인하기 위해 실행을 시간을 잰다. 마지막으로, 우리는 시간을 측정하기 때문에 컴파일러가 수행 한 작업을 최적화하지 않아야하므로 결과를 반환하는 것처럼 가장합니다.

Fortran에서의 동일한 예

program typical_loop
    use omp_lib
    implicit none
    integer, parameter :: N = 1000000, kd = kind( 1.d0 )
    real( kind = kd ) :: sum, tbegin, wtime
    integer :: i

    sum = 0

    tbegin = omp_get_wtime()
    !$omp parallel do reduction( +: sum )
    do i = 1, N
        sum = sum + cos( 1.d0 * i )
    end do
    !$omp end parallel do
    wtime = omp_get_wtime() - tbegin

    print "( 'Computing ', i7, ' cosines and summing them with ', i2, &
        & ' threads took ', f6.4,'s' )", N, omp_get_max_threads(), wtime

    if ( sum > N ) then
        print *, "we only pretend using sum"
    end if
end program typical_loop

다시 여기에서 1 백만 코사인을 계산하고 누적합니다. 우리는 루프를 돌리고 원치 않는 컴파일러 최적화를 피하기 위해 결과를 사용하여 가장합니다.

예제 컴파일 및 실행

GCC 버전 4.4를 사용하는 8 코어 Linux 컴퓨터에서 C 코드는 다음과 같이 컴파일되고 실행될 수 있습니다.

$ gcc -std=c99 -O3 -fopenmp loop.c -o loopc -lm
$ OMP_NUM_THREADS=1 ./loopc
Computing 1000000 cosines and summing them with 1 threads took 0.095832s
$ OMP_NUM_THREADS=2 ./loopc
Computing 1000000 cosines and summing them with 2 threads took 0.047637s
$ OMP_NUM_THREADS=4 ./loopc
Computing 1000000 cosines and summing them with 4 threads took 0.024498s
$ OMP_NUM_THREADS=8 ./loopc
Computing 1000000 cosines and summing them with 8 threads took 0.011785s

Fortran 버전의 경우 다음과 같습니다.

$ gfortran -O3 -fopenmp loop.f90 -o loopf
$ OMP_NUM_THREADS=1 ./loopf
Computing 1000000 cosines and summing them with  1 threads took 0.0915s
$ OMP_NUM_THREADS=2 ./loopf
Computing 1000000 cosines and summing them with  2 threads took 0.0472s
$ OMP_NUM_THREADS=4 ./loopf
Computing 1000000 cosines and summing them with  4 threads took 0.0236s
$ OMP_NUM_THREADS=8 ./loopf
Computing 1000000 cosines and summing them with  8 threads took 0.0118s

구성을 위해 OpenMP 병렬을 사용하는 두 벡터의 추가

void parallelAddition (unsigned N, const double *A, const double *B, double *C)
{
    unsigned i;

    #pragma omp parallel for shared (A,B,C,N) private(i) schedule(static)
    for (i = 0; i < N; ++i)
    {
        C[i] = A[i] + B[i];
    }
}

이 예는 스레드 팀 (예 : OMP_NUM_THREADS 변수로 지정)을 스폰하고 각 스레드에 작업 청크를 할당하여 두 개의 벡터 ( ABC )를 추가합니다 (이 예에서는 schedule(static) 통해 정적으로 할당 됨 schedule(static) 표현).

private(i) 선택 사항과 관련하여 비고 부분을 참조하십시오.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow