티스토리 뷰

728x90

1. 개요

  

  OpenMP의 기본 명령어에 대한 설명과 예제이며 아래 코드들은 Linux 기반으로 Intel Compiler로 하여 디버딩을 하였다.

 


2. Sample01 - set_num_threads(int)

  

 아래 코드는 쓰레드 갯수를 정하는 커맨드가 여러개라는 것을 보여주는 코드이다.

 

 코드내에서는 omp_set_num_threads(4);#pragma omp parallel num_threads(2)가 쓰레드 갯수를 조절한다. 코드내에서 뿐만 아니라 Linux환경에서 export OMP_NUM_THREADS=8 커맨드로 defult 쓰레드 갯수를 설정할 수 있다.

 

위 결과를 보시면 처음 것은 8개, 2번째 것은 4개, 3번째 것은 2개로 출력이 된다. 또한 여기서 우리는 알 수 있듯이 쓰레드의 번호에 따라 출력이 되는 것이 아니라 끝나는 순서되로 출력이 되는 것을 알 수 있다.

 

 

3. Sample02 - omp_get_thread_num()

  

 2번째 코드는 omp_get_thread_num()이라는 쓰레드 넘버를 반환해 주는 함수를 확인하는 코드이다.

 


 이번 코드는 위의 예상 출력과 다르게 아래와 같이 결과가 출력된다. 이는 쓰레드 처리속도가 빨라 CPU 기본 처리 단위로 복수개가 처리된 것이라고 생각한다. 허나 위 예상 진행도를 보면 코드에서는 main()에 선언된 변수 tid가 모든 쓰레드에게 공유되어 사용되는 것을 알 수 있다. 그렇기 때문에 코드 작성시 주의해야하는 부분이다.

 

 

 가장 쉽게 해결할 수 있는 방법은 병렬화 된 내부에서 새로 변수를 선언하는 것이다. 또 다른 방법은 4. Sample03 - private에서 설명 하겠다.




4. Sample03 - private

  

 3번째 코드는 main의 변수를 복사하여 쓰레드의 지역변수로 만드는 함수를 보는 코드이다.

 

코드를 보면 #pragma omp parallel 옆에 private(tid)firstprivate(i)가 추가되었다. private는 쓰레드에 지역변수만 생성하며 firstprivat는 생성뿐만 아니라 main함수에 있는 변수의 값도 복사한다. 아래 사진은 변수가 변경되는 모습을 나타낸 것이다.

 

위에 있는 코드의 결과 값이다.

 

 

 

 

5. Sample04 - shared

  

 기본적으로 하나의 변수, 즉 메모리에 동시에 접근하여 데이터를 처리할 수 없다. 실질적으로 배열은 각각의 인덱스 마다의 다른 주소값을 가져 변수에 shared를 하지 않아도 상관이 없다. 그러나 배열이 고차원으로 갈 수록 주소관계가 복잡해지기 때문에 해주어야 한다고 한다. 아래 사진중 첫번째는 private로 배열 a를 지정한 것이고 두번째는 share로 배열 a를 지정한 것이다.




 


6. Sample05 - #pragma omp for

  

 우선 코드를 보자


 코드 중 for문 위에 #pragma omp for가 선언되어 있는 것을 볼 수 있다. 해당 커맨드를 선언하는 것 만으로 for문은 자동으로 쓰레드에게 분할되어 병렬로 처리된다. 아래 사진은 #pragma omp for 커맨드가 없을 떄와 있을 때의 코드 진행 과정을 나타낸다.



 #pragma omp for 사용할 때는 주의할 것이 몇가지 있다. 코드에도 주석처리 되어 있지만 여기서 변수 i는 private(i)처럼 각각의 쓰레드에게 복사된다. 그리고 각각의 쓰레드에서 for문이 실행 될때 i의 초기화 값이 다르게 선언된다. 

  우리는 여기에서 #pragma omp for가 선언된 for문의 인자로 사용된 것들은 지역 변수로 생성되는 것을 알아야 한다.




7. Sample06_0 - serial

  

 Sample06_0은 pi(3.14)값을 구하는 코드로 Sample06_1 ~ 4는 해당 코드를 가지고 위에서 설명한 병렬 방법과 새로운 방법들을 적용해 볼 것이다.




8. Sample06_1 - add_private

  




9. Sample06_2 - add_pragma omp for 

  

 Sample06_1과 2는 tid값으로 수동으로 for문을 병렬화 하느냐 아니면 #pragma omp for로 자동으로 for문을 병렬화를 하느냐의 차이로 속도 차이가 거의 없다.



9. Sample06_3 - add_critical

  

  critical이란 말그대로 critical section에 속하는 변수에 접근할 때 사용한다. 해당 변수에 대한 접근은 하나의 쓰레드만 접근할 수 있다. 따라서 critical 수가 늘어나면 소모 시간도 늘어난다.


 


9. Sample06_4 - add_reduction

  

  reduction은 critical을 보안하는 기능이라고 생각한다. critical section을 발생시키지 않기 위해 sum 변수를 각각 쓰레드의 지역변수로 선언하고 쓰레드가 끝날 때, main의 sum에 하나씩 접근하여 더한다.



아래는 C언어의 OpenMP의 reduction이 제공하는 Operator들이다.



4. 출처

  

  • 2015 부산대 슈퍼컴퓨팅 교육자료

  • 2016 부산대 슈퍼컴퓨팅 교육자료


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함