OpenMP Basic I - 소개

GraGrass·2024년 1월 8일
0

Chapter 2

OpenMP의 개념

1. Open specifications for Multi Processing

API

  • 공유 메모리 환경에서 다중 스레드 병렬 프로그램 작성을 위한 Application Programming Interface
    ex. PC (Multiple Core가 메모리 공유)
  • Language(Fortan, C/C++) Extensions
  • 공유 메모리 프로그래밍 모델의 표준

구성

  • 컴파일러 지시어: omp parallel
  • 런타임 라이브러리(함수): omp_set_num_threads(n)
  • 환경 변수: OMP_NUM_THREADS=n

2. OpenMP의 장단점 (vs MPI)

장점

  • MPI에 비해 코딩, 디버깅 용이
  • MPI에 비해 DATA 분할의 부담 적음
  • 각 Loop을 하나씩 병렬화하여 점진적 병렬화 가능
    ex. 한 code 내에서 첫번째 loop를 병렬 처리 했을 때 결과 잘나옴 -> 순차적으로 다음 loop 병렬 처리
  • 하나의 code를 병렬, 순차 code로 각각 compile 가능
  • 상대적으로 code 크기가 작음

단점

  • 공유 메모리 환경의 다중 프로세서 아키텍처에서만 실행 가능
  • 아키텍처(프로세서 수, 메모리)의 한계로 원하는 성능을 얻기 어려움
    ex. 노드에 코어가 68개 -> 68개 초과 코어 사용 불가
  • OpenMP를 지원하는 compiler가 반드시 필요

OpenMP의 구성요소

1. 구성 요소

Compiler Directive (Fortan)

!$OMP PARALLEL DO 
  • 스레드 사이의 작업 분담, 통신, 동기화 담당
  • 좁은 의미의 OpenMP

Runtime Library

함수기능
omp_set_num_threads(n)생성될 스레드 개수 set
omp_get_num_threads() 생성된 스레드 개수 return
omp_get_thread_num()스레드 ID return
omp_get_max_threads()사용 가능한 최대 스레드개수 return
  • 병렬 매개변수(참여 스레드 개수, 스레드 ID) 설정 및 조회
  • omp_set_num_threads(n) 으로 스레드 생성 시, master thread 1개 + 추가 생성된 n-1개의 스레드로 구성됨

Environmental Variables

export OMP_NUM_THREADS=8
  • 실행 시스템의 병렬 매개변수(스레드 개수 등) 정의

2. Example

C code

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

int main()
{
#pragma omp parallel //Compiler Directive
{
	// Runtime Library
	printf("Hello World! %d\n", omp_get_thread_num());
} // end #pragma omp parallel 
}

Compile 및 실행 (C / C++)

$ gcc -fopenmp -o omp_comp.x omp_comp.c 
$ export OMP_NUM_THREADS = 4
$ ./omp_comp.x
  • GCC 환경에서의 compile

Result

Hello World! 0
Hello World! 1
Hello World! 3
Hello World! 2
  • $ export OMP_NUM_THREADS = 4에 의해 4줄 출력
  • 병렬 처리 -> 순차적 출력 X
  • 각 번호는 thread number

조건부 컴파일

C code

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

int main()
{
#ifdef_OPENMP
	#pragma omp parallel //Compiler Directive
	{
		// Runtime Library
		printf("Hello World! %d\n", omp_get_thread_num());
	} // end #pragma omp parallel 
#else
	printf("Hello World 0\n")
#endif
}

Compile 및 실행 (C / C++)

$ gcc conditional.c
$ gcc -fopenmp conditional.c
$ export OMP_NUM_THREADS = 4
$ ./a.out
  • GCC 환경에서의 compile

Result

  • $ gcc conditional.c: Serial
Hello World! 0
  • $ gcc -fopenmp conditional.c: Parallel
Hello World! 0
Hello World! 3
Hello World! 2
Hello World! 1

해석

  • #ifdef_OPENMP 로 분기 처리 시, serial 조건으로도 parallel 조건으로도 컴파일이 가능함
  • 만약 #else 이후가 주석처리 된다면, serial 컴파일 불가
    omp_get_thread_num 함수를 찾을 수 없다는 에러 출력

스레드 생성법

1. Example

C code

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

int main()
{
#pragma omp parallel
{
	printf("Hello World! %d\n", omp_get_thread_num());
}
	printf("\n");
    omp_set_num_threads(4);
#pragma omp parallel
{
	printf("Hello World! %d\n", omp_get_thread_num());
}
	printf("\n");
#pragma omp parallel num_threads(2)
{
	printf("Hello World! %d\n", omp_get_thread_num());
}
}

Compile 및 실행 (C / C++)

$ gcc -fopenmp -o create_thread.x create_thread.c
$ export OMP_NUM_THREADS = 8
$ ./create_thread.x

Result

Hello World! 0
Hello World! 4
Hello World! 3
Hello World! 5
Hello World! 7
Hello World! 2
Hello World! 1
Hello World! 6

Hello World! 0
Hello World! 3
Hello World! 2
Hello World! 1

Hello World! 1
Hello World! 0
  • OMP_NUM_THREADS = 8 로 시작 -> 8번 출력
  • omp_set_num_threads(4); -> 4번 출력
  • #pragma omp parallel num_threads(2) -> 2번 출력
  • 우선순위: omp parallel 지시어 > Runtime Library > Environmental Variables

2. OpenMP Programming Model

Thread-Based

Fork-Join Model

  • Master Thread는 병렬 영역의 끝에서 합쳐지는 스레드 팀 생성
  • 동일 팀에 속한 스레드들이 공동 작업

컴파일러

  • 컴파일러가 지시어를 참고하여 다중 스레드 코드 생성
  • OpenMP를 지원하는 컴파일러 필요
profile
올해는 진짜 갓생 산다

0개의 댓글