API:OPENMP

구차니의 잡동사니 위키
이동: 둘러보기, 찾기

openMP는 Multi Processing 의 약자로, 다양한 플랫폼에서의 다중 프로세서를 지원한다.

openMP는 컴파일러의 지원을 받아야만 쓸 수 있다.

Visual Studio 2008 이후 버전부터(Express는 미지원) OpenMP 2.0을 지원하며

OpenMP 3.0은 Intel 컴파일러를 사용해야 한다.


목차

공식 홈페이지


GOMP(GNU OpenMP)

OpenMP의 GCC 구현을 GOMP(GNU OpenMP)라고 표기하기도 한다.

  • GCC 4.2 OpenMP 2.5 specification
  • GCC 4.4 OpenMP 3.0 specification
  • GCC 4.7 OpenMP 3.1 specification
  • GCC 4.9 OpenMP 4.0 for C/C++
  • GCC 4.9.1 also for Fortran
  • GCC 5 adds support for Offloading


빌드 설정

GCC

소스

#include <omp.h>

빌드

gcc -fopenmp

-fopenmp면 자동으로 -lgomp를 포함한다. -fopenmp 없이 -lgomp만 하면 openMP가 활성화 되지 않는다.

Visual Studio

프로젝트 - 속성 - 구성 - C/C++ - 언어 - OpenMP 지원 속성을 수정


문법

pragma omp로 컴파일러에게 openmp 확장임을 알려준다.

#pramga omp [directive] [clause]


#pragma omp parallel num_thread
#pragma omp parallel defaults
#pragma omp parallel private
#pragma omp parallel firstprivate
#pragma omp parallel shared
#pragma omp parallel copyin
#pragma omp parallel reduction

#pragma omp for private
#pragma omp for firstprivate
#pragma omp for lastprivate
#pragma omp for reduction
#pragma omp for schedule
#pragma omp for collapse
#pragma omp for ordered
#pragma omp for nowait

#pragma omp sections private
#pragma omp sections firstprivate
#pragma omp sections lastprivate
#pragma omp sections reduction
#pragma omp sections schedule
#pragma omp sections collapse
#pragma omp sections ordered
#pragma omp sections nowait

#pragma omp task if
#pragma omp task untied
#pragma omp task default
#pragma omp task private
#pragma omp task firstprivate
#pragma omp task shared

지시어(directive)

  • parallel - 분산처리 영역의 시작을 알림
  • master - 분산처리 중 마스터 쓰레드에서 실행하도록 함
  • single - 분산처리 중 하나의 쓰레드에서만 실행하도록 함
  • sections - 하나의 일을 분산처리 하는게 아닌 여러가지 일을 분산처리 하도록 함


  • for - for 문에 대하여 분산처리를 지원


  • atomic - 사칙 연산 정도의 보호 기능을 지원
  • critical - 함수 연산 까지 '블럭단위' 보호 기능을 지원


  • barrier - nowait 절(clause)를 사용시 명시적으로 동기화를 하도록 함
  • flush - 변수들에 대한 동기화를 지원


  • ordered


  • threadprivate

절(clause)

  • copyin
  • copyprivate
  • firstprivate
  • lastprivate
  • if
  • num_threads
  • ordered


  • reduction
  • schedule


  • nowait


  • default
  • shared
  • private


multi process 활성화

#pragma omp parallel
{
   // ...
}


병렬처리 구간에서의 변수 동기화

#pragma omp parallel
default(shared|none)
private
firstprivate
lastprivate 


단순하게 for문 나눠서 돌릴때

#pragma omp parallel
{
  #pragma omp for
  {
    // ...
  }
}

혹은

#pragma omp parallel for 


쓰레드 순서대로 실행해야 할 경우의 보조 지시어

(그런데 이렇게 하면 병렬처리를 안하고 single로 순서대로 하는거 아닌가?)

#pragma omp parallel for ordered
#pragma omp ordered 


보조지시어 schedule을 이용한 for문의 분배방식

#pragma omp parallel for schedule(static)
#pragma omp parallel for schedule(dynamic)
#pragma omp parallel for schedule(guided)
#pragma omp parallel for schedule(runtime) 


parallel 구문에서 마스터 쓰레드만 돌릴경우

single을 사용함(물론 실행도 1번만)

#pragma omp parallel 
#pragma omp single 


멀티 쓰레드로 여러개의 작업(함수단위) 돌릴경우

sections 안에 함수별로 section을 사용함

#pragma omp parallel 
{
 #pragma omp sections
 {
  #pragma omp section
  {
  }
  #pragma omp section
  {
  }
 }
}


쓰레드 외부의 변수들을 복제하여 사용

private 보조 지시어(쓰레드 별로 복제되어 사용됨)

#pragma omp parallel private(variable)


atomic 연산

atomic은 단순하게 변수에 값 할당 하는 정도의 단순한 lock 방법을 위한 아토믹 연산을 지원하며 critical은 critical section(OS 용어)을 지원하기 위해 함수나 비교, 할당등을 할 수 있는 확장된 지시어.

#pragma omp atomic
#pragma omp critical 


실행중인 쓰레드의 번호확인(런타임)

runtime 함수로 현재 실행중인 쓰레드의 번호(만약 쓰레드가 4개라면 0~3번 사이의)를 알려준다.

omp_get_thread_num()

예제

$ cat test.c
#include <stdio.h>
#include <omp.h>

int main(int argc, const char *argv[])
{
    #pragma omp parallel
    printf("hell world\n");

    return 0;
}
$ gcc -fopenmp test.c
$ ./a.out
hell world
hell world
hell world
hell world
$ cat test.c
#include <stdio.h>
#include <omp.h>

int main(int argc, const char *argv[])
{
    int idx = 0;
    #pragma omp parallel for
    for(idx = 0; idx < 16; idx++)
         printf("%d\n",idx);

    return 0;
}
$ gcc -fopenmp test.c
$ ./a.out
0
1
2
3
12
13
14
15
4
5
6
7
8
9
10
11
개인 도구
이름공간

변수
행위
둘러보기
도구모음