OpenMP 를 간단히 표현하면 굉장히 단순한 작업으로 손쉽게 멀티스레드 프로그램으로 만들어주는 라이브러리 라는 말로 요약할 수 있습니다. 

여기서 단순한 작업이라는 의미는 간단한 코드를 소스에 삽입함으로써 싱글스레드 프로그램을 멀티스레드 프로그램으로 만들어 준다는 뜻 입니다. 이는 멀티코어 시스템에서 코어 개수만큼의 CPU자원을 최대한 얻어서 쓸 기회가 생긴다는 얘기이기도 하지요.

여기서 잠깐 짚고 넘어가야 할 게 있죠. 바로..


멀티스레드(Multi-Thread) 프로그래밍의 의미와 중요성


멀티 스레드도 간단하게 표현 해 보면 바로 "한 프로그램에서 여러가지 작업을 동시에 할 수 있게 한다" 라고 요약할 수 있는데요, 사실 지금은 당연시 되는 기법이라 다들 알고 계실 거라고 믿습니다. 
멀티 쓰레드를 지원하지 않는 OS는 찾기도 힘든 시대죠. 심지어는 핸드폰이나 TV에 탑재되는 OS들도 다 지원합니다.
( 아, TV는 OS라고 하기엔 좀 그런가요? .. )

그렇다면 OS상에서 실행중인 수 많은 쓰레드 중에서 어떤 쓰레드에게 CPU자원을 나눠줄 것인가?

이 문제는 OS의 스케쥴러가 나름의 판단 원칙을 갖고 각각의 쓰레드에게 CPU자원을 배분할 계획을 세웁니다.
여기서 멀티 쓰레드를 논하면서 또 빠뜨릴 수 없는 개념인 컨텍스트 스위칭(Context-Switching)이 나오죠.

A쓰레드의 자원을 다른 쓰레드로 넘기는 과정을 뜻하는데, 언제 어떤 쓰레드에게 넘기는지는 전적으로 OS가 알아서 판단합니다.
( 물론 프로그래머에게 쓰레드의 우선순위를 결정할 권한은 주지만요..^^; )

CPU 한 개는 동시에 하나의 작업만 할 수 있기 때문에 이전까지의 멀티 스레드를 이용한 병렬처리는 Context-Switching이 매우 빠르게 일어난다는 장점을 이용한 일종의 트릭이었습니다.

그런데 기술이 빠르게 발전하면서 지금에 와서는 대부분의 PC에 멀티코어 CPU가 박혀있습니다.
이는 곧 쓰레드 입장에서 자신에게 CPU자원이 돌아올 기회가 훨씬 더 많아졌다는 뜻이며(단순 산술적으로는 X 코어수), 프로세스 입장에서는 갖고있는 쓰레드들이 여러개의 CPU를 동시에 이용할 기회가 생겼다는 뜻이기도 합니다.


그렇습니다. 프로그램이 여러개의 CPU를 이용하면서 동시에 여러가지 작업을 할 수 있다! 
현재 멀티스레드의 가장 큰 장점이라고 할 수 있지 않나 싶습니다. ^^;


다시 OpenMP 얘기로 돌아와서...


1997년에 처음 소개된 OpenMP는 C/C++/Fortran에서 멀티스레드 프로그래밍을 위한 API 표준입니다. 
즉, Spec만 정의 하고 구현은 컴파일러같은 다른 도구에 맡긴다는 의미인데요.

재미있는 건 현존하는 대부분의 컴파일러에서 OpenMP를 지원 하고 있다는 사실이고 더 재미있는 건 그러한 컴파일러를 사용중인 사람들의 대부분이 이 사실을 모르고 있다는 것이죠. ( VS2005, GCC, 인텔, 썬, HP등에서 제공하는 컴파일러가 별도의 라이브러리 형태로 제공하고 컴파일 시 특별한 옵션을 줘서 기능을 사용할 수 있게 해 줍니다. )

위에서도 얘기했지만 OpenMP가 소개된 시점이 1997년이라는 것에서도 알 수 있듯이 멀티코어에 특화된
병렬처리용 API가 아니라 단순히 멀티스레드를 만드는 API입니다.

그렇다면 OpenMP가 기존의 멀티스레드 프로그래밍( POSIX-pthread 혹은 윈도우 쓰레드 )방식과 비교했을 때 어떤 장점이 있을까요?

첫 째로 가장 먼저 알 수 있는 건 바로 플랫폼에 독립적이라는 사실입니다. 대부분의 컴파일러에서 지원하므로 그런 컴파일러를 사용할 수 있는 시스템이라면 같은 코드로 멀티스레드 프로그램을 만들 수 있습니다. 
pthread를 사용했다면 윈도우에서 실행하기 힘들 것이고, 윈도우 쓰레드 API를 사용했다면 *nix를 비롯한 다른 시스템에서 실행할 수 없을 것입니다.

두 번째는 적용이 매우 간단하다는 것입니다. 기존에 싱글스레드 기반으로 작성된 프로그램이 있다면 간단한 몇 줄의 코드를 추가함으로써 부분적으로 병렬처리가 되도록 변경할 수 있습니다. 

예제를 한 번 보시죠. 행렬의 곱셈을 최대한 간단하게 구현한 소스의 일부입니다.


첫 번째 줄에 #pragma 한 줄을 추가함으로써 위 코드는 병렬처리가 되게 만들었습니다. 다른 포스트에서 소개 해 드리겠지만 
500 x 500 행렬끼리의 곱셈 연산에서 위 코드를 제거하면 1초가량 걸리는데 반해 코드가 존재하면 0.6초 걸립니다.
위는 제 듀얼코어(E6320)에서의 결과이지만 아는 분의 쿼드코어(Q9550)에서는 0.54초 -> 0.14초로 단축됐다고 합니다.

참 간단하면서도 강력하죠?

세 번째는 수많은 지시자와 함수들을 지원하기 때문에 세밀하게 제어할 수 있습니다.


이 외에도 장점이 많겠지만 이쯤 하도록 하구요.. OpenMP가 마냥 좋은것만은 아닌 것이 단점도 만만찮게 있습니다.

첫 번째 단점은 두 번째 장점과 상반되는 것인데요. 이미 다른 API를 사용하여 멀티스레드 프로그램으로 작성되어 있다면 부분적으로 OpenMP를 추가하면서 이득을 얻기는 불가능해 보인다는 점입니다. 이건 제가 잘 몰라서 그러는 것일수도 있는데 MS에서는 OpenMP를 사용하여 생성된 쓰레드도 윈도우 쓰레드이지만 서로 독립적이고 간섭이 불가능하다고 경고하고 있지요. 즉, 데이터 동기화도 안 된다는 뜻이며 이는 매우 치명적입니다. 다른 플랫폼의 경우는 아직 잘 모르겠습니다.

두 번째 단점은 OpenMP가 많은 양의 데이터를 처리하는 곳(Loop를 크게 많이 돌 때)에 한하여 강력하다는 점입니다. 작업(Task)기반으로 스레드를 나눌 때에는 적합하지 않을 수도 있다는 이야기 입니다.


여기까지 OpenMP에 대한 간단한 소개와 함께 멀티 스레드에 대한 기본 개념도 살짝 소개 해 드렸는데요,
다음 포스트 부터는 본격적으로 OpenMP를 어떻게 써먹어야 하는 지 대충 보여드리는 글을 써 볼 계획입니다.

제가 지식이 매우 얕은 관계로 강좌는 아닐 것 같구요. 아마도 "전 이렇게 사용해 봤습니다" 하는 식으로 소개만 하지 않을까 싶네요. ^^;
2008/10/01 23:49 2008/10/01 23:49
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://sabjilstar.com/tt/rss/response/41

트랙백 주소 :: http://sabjilstar.com/tt/trackback/41

트랙백 RSS :: http://sabjilstar.com/tt/rss/trackback/41

댓글을 달아 주세요

댓글 RSS 주소 : http://sabjilstar.com/tt/rss/comment/41
[로그인][오픈아이디란?]