openmpopenmp 시작하기


비고

OpenMP (Open MultiProcessing)는 컴파일러 지시문을 기반으로하는 병렬 프로그래밍 모델로, 응용 프로그램 개발자가 응용 프로그램 코드에 점진적으로 병렬 처리를 추가 할 수 있도록합니다.

병렬 프로그래밍을위한 OpenMP API 사양은 대부분의 플랫폼에서 C, C ++ 및 Fortran의 다중 플랫폼 공유 메모리 다중 처리 프로그래밍을 지원하는 API (Application Programming Interface)를 제공합니다. 이것은 런타임 작동에 영향을주는 컴파일러 지시문, 라이브러리 루틴 및 환경 변수로 구성됩니다.

OpenMP는 노드 내의 병렬 처리 (공유 메모리 다중 처리)에 중점을두기 때문에 MPI와 같은 메시지 전달 프로그래밍 모델과 결합하여 여러 노드에서 실행할 수 있습니다.

버전

번역 언어 출시일
4.5 C / C ++ / 포트란 2015-11-01
4.0 C / C ++ / 포트란 2013-07-01
3.1 C / C ++ / 포트란 2011 년 7 월 1 일
3.0 C / C ++ / 포트란 2008-05-01
2.5 C / C ++ / 포트란 2005-05-01
2.0c C / C ++ 2002-03-01
2.0f 포트란 2000-11-01
1.0c C / C ++ 1998-10-01
1.0f 포트란 1997-10-01

편집

OpenMP 사양의 다른 버전을 지원하는 많은 컴파일러가 있습니다. OpenMP는 목록을 유지 여기 를 지원하는 컴파일러와 지원 버전. 일반적으로 OpenMP 지원으로 응용 프로그램을 컴파일 (및 링크)하려면 컴파일 플래그 만 추가하면되며 OpenMP API를 사용하는 경우에는 OpenMP 헤더 (omp.h)를 포함해야합니다. 헤더 파일의 이름은 고정되어 있지만 컴파일 플래그는 컴파일러에 따라 다릅니다. 다음은 OpenMP를 사용할 수있는 컴파일러 및 플래그의 전체 목록입니다.

  • GCC (gcc, g ++ 및 gfortran 포함) : -fopenmp
  • LLVM : -fopenmp
  • 인텔 컴파일러 제품군 (icc, icpc 및 ifort 포함) : -qopenmp (GCC / LLVM과의 호환성을 위해 -fopenmp )
  • IBM XL 컴파일러 - 스위트 (xlc, xlC 및 xlf 포함) : -xlsmp=omp
  • PGI 컴파일러 - 스위트 (pgcc pgc ++ pgfortran 포함) : '-mp'

OpenMP를 사용한 병렬 안녕 세상

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

int main (int argc, char *argv[])
{
   #pragma omp parallel
   {
     printf ("Hello world! I'm thread %d out of %d threads.\n",
             omp_get_thread_num(), omp_get_num_threads());
   }
   return 0;
}
 

이 코드는 단순히 환경 변수 OMP_NUM_THREADS 에 따라 스레드 그룹을 만들고 정의되지 않은 경우 시스템의 논리 코어 당 하나씩 만들며 각 스레드는 일반적인 Hello World 메시지 인쇄 외에 자체를 식별합니다.

감축의 예

#include <omp.h>
void main ()
{     
    int i;       
    double ZZ, func(), res=0.0;

    #pragma omp parallel for reduction(+:res) private(ZZ) 
    for (i=0; i< 1000; i++){
        ZZ = func(I);
        res = res + ZZ; 
    }
}
 

마지막 줄에는 실제로 개인 사본에 추가 된 다음 루프 이후에 결합됩니다. 컴파일러가 세부 사항을 처리합니다.

작업 공유 구성 - For 루프의 예

double  res[MAX];  int i;
#pragma omp parallel 
{    
    #pragma omp for
    for (i=0;i< MAX; i++) {
        res[i] = huge();
    } 
}    
 

for 루프는 병렬로 실행됩니다. huge ()는 실행하기에 너무 오래 걸릴 수있는 메소드입니다. OpenMP는 위의 코드를 다음과 같이 작성하는 단축키를 지원합니다.

double  res[MAX];  int i;
#pragma omp parallel for
for (i=0;i< MAX; i++) {
    res[i] = huge();
} 
 

루프 반복이 스레드에 매핑되는 방법에 영향을주는 schedule 절을 사용할 수도 있습니다. 예 :

#pragma omp parallel
#pragma omp for schedule(static)
for(i=0;I<N;i++) {
    a[i] = a[i] + b[i];
}
 

스케줄링의 다른 스타일은 다음과 같습니다.

일정 (정적 [, 청크])
각 스레드에 크기 "반복 (chunk)"을 반복하는 블록을 처리합니다.
지정되지 않은 경우 : 사용 가능한 스레드에 가능한 한 균등하게 할당하십시오

일정 (동적 [, 청크])
각 스레드는 모든 반복이 처리 될 때까지 대기열에서 "청크"반복을 가져옵니다.

일정 (가이드 [, 덩어리])
스레드는 동적으로 반복 블록을 가져옵니다. 블록의 크기는 커지기 시작하고 계산이 진행됨에 따라 "청크"크기로 축소됩니다.

일정 (런타임)
OMP_SCHEDULE 환경 변수에서 가져온 일정 및 청크 크기