본문 바로가기

Robotics/Software Tech.

멀티코어 프로그래밍을 하기위해 어떻게 해야하는가..

이제 더이상 싱글코어는 사용자에게 잊혀지고 있다.
듀얼코어는 기본, 쿼드코어.. 더 나아가서는 옥토코어가 곧 등장할거라고 한다.

그런데.. 실제로 사용해보니 싱글코어랑 듀얼코어랑 큰 차이를 못느끼겠다.
왜냐.. 바로 대부분의 프로그램이 싱글코어 기준의 프로그램이기 때문이다.
듀얼코어를 효과적으로 사용하려면 멀티코어 기준으로 프로그램이 되어있어야 하겠다.
즉, 코어가 여러개이기때문에 병렬처리를 해야 진정한 멀티코어에 맞는 프로그램이라 할 수 있겠다.

그럼, 멀티코어 프로그래밍을 하기위해서 어떻게 해야하는가..
아래 동영상을 보자.

[Flash] http://dory.mncast.com/mncHMovie.swf?movieID=10042747720071204182245&skinNum=1


프로그램 내에 병렬처리를 가능케 하기 위해 어떻게 해야 하는가?

병렬 처리의 도입을 처음 고려할 때 가장 피해야 할 것은, 병렬 처리에 있어서 가장 낮은 단계의 프로그래밍 모델을 찾고 Open MP를 살펴보라

<내용>
안녕하세요 제임스 랜더스 입니다. 사람들이 저에게 가장 흔히 묻는 질문 중 하나는 바로 “프로그램 내에 병렬처리를 가능케 하기 위해서는 어떻게 해야 하는지? 그리고 어떤 것을 살펴보아야 하는지?”에 대한 것입니다. 그리 복잡한 질문은 아니죠. 이번 시간에는 이에 대한 간단한 답을 알아보는 시간을 마련하도록 하겠습니다. 병렬처리를 위해 살펴보아야 하는 3가지 요소들에 대해서 알아보도록 하죠.

병렬 처리의 도입을 처음 고려할 때 가장 피해야 할 것은, 병렬 처리에 있어서 가장 낮은 단계의 프로그래밍 모델을 찾는 것입니다. 즉, P스레드 또는 윈도우 스레드와 같은 가공되지 않은 스레드로부터 시작해서는 안 된다는 것입니다. 우리는 우리의 애플리케이션의 병렬처리에 대한 방법이 어느 정도 확정된, 그래서 저 레벨의 세부사항들은 자동으로 해결되는 그런 단계에서부터 시작되기를 바래야 합니다. 전 가장 먼저 살펴봐야 할 것이 라이브러리라고 생각합니다. 물론 여기에는 어느 정도 제약 사항이 존재할 수 있겠지만, 프로그램 상에 병렬처리를 구현하고자 하고, 또 해당 프로그램의 라이브러리 중에 병렬 처리 방식을 도입하거나 이미 도입되어 있는 라이브러리가 있다면, 이는 병렬 처리를 구현하는데 있어 가장 먼저 살펴보아야 할 부분이라고 할 수 있습니다. 그러므로 지금 애플리케이션으로 통해 구현하고 있는 것은 무엇이고, 또 라이브러리 콜을 할 필요성은 없는지 다시 한 번 살펴보며, 만약 그럴 필요성이 있다면 병렬 처리 방식을 이용하고 있는 라이브러리들은 없는 지 찾아보는 것이 좋습니다. 만약 그러한 라이브러리가 없더라 하더라도 라이브러리들을 활용하여 이를 병렬 처리 방식으로 운용하는데 초점을 맞추어 보는 것도 괜찮은 방법입니다. 간단한 예로는 인텔은 수학적 계산을 위한 라이브러리 MKL를 제공하고 있고, 이러한 라이브러리들은 상당히 흔합니다. IMSL 또한 병렬 처리 방식을 이용한 라이브러리들을 제공하고 있죠. 멀티미디어 쪽을 살펴보더라도, 코덱, JPEG, MPEG 인코딩 및 디코딩 작업을 실행할 수 있는 라이브러리들을 찾을 수 있을 겁니다. 가장 흔한 예시들이라 할 수 있죠. 그래픽 부문에서도 많이 볼 수 있습니다. 애플 플랫폼에서는 핵심 애니메이션 라이브러리가 병렬 처리 방식을 활용하고 있습니다. 그러므로 라이브러리를 항상 먼저 염두에 두세요. 매우 쉬우면서도 오늘날 사용자들의 프로그램 사용에 유용한 그런 방법이라고 할 수 있습니다.

제가 드리는 두 번째 제안은 바로 Open MP를 살펴보라는 것입니다. 사실 이런 이야기를 제가 하면 사람들은 놀라곤 합니다. Open MP에 대해 잘 모르시는 분들을 위해 설명 드리자면, Open MP는 C, C++, 포트란 등을 확장한 형태로서, 컴파일러들에게 특정 지시들을 내려, 프로그램 절차에 관여할 수 있는 힌트를 제공 함으로써, 이들로 하여금 병렬 처리 형태를 구현할 수 있도록 만드는 것이라 정의할 수 있습니다. Open MP에 대한 언급이 사람들을 놀라게 하는 이유는, 그들이 이것에 대해 들어본 적이 없거나, 거의 모든 컴파일러들이 이것을 지원한다는 사실을 모르기 때문입니다. Open MP는 1996년 처음 소개되었고, 10년이 흐른 2006년부터 시중에 나와 있는 C, C++, 그리고 포트란 컴파일러에서 모두 찾을 수 있습니다. 사용하기도 매우 쉽죠.

C언어의 형태로 For 루프(loop)을 만들어 보겠습니다. For I, For J, For K, 이렇게 일련의 데이터를 만들었습니다. 이는 당연히 병렬 처리 형태로 구현될 수 있습니다. 하지만 일반적인 컴파일러는 이를 병렬 처리 형태로 자동 전환시키지 못합니다. 그럼 그 위에 “Add pragma omp parallel for”라는 코드를 추가로 기입해 주기만 하면 됩니다. 하지만 애플리케이션의 종류에 따라 한가지 지시사항을 더 기입해주어야 하는 경우도 있습니다. 같은 줄에 “private(l,j,k)”라는 코드를 넣어주어야 하는 경우도 있는 것이죠.

이 코드는 컴파일러에게 이들 for 루프들이 각각 쓰레드에 개별 적용된다는 의미를 전달합니다. 이러한 일련의 과정들은 성능 향상에 긍정적인 영향을 미칩니다. 이렇듯 한 줄의 명령만으로도 프로그램 상에서 병렬 처리 방식을 구현할 수 있습니다. 그러나 Open MP의 한계는 그 영향력이 루프에만 한정되어 있다는 점입니다. 이보다 더 복잡한 작업을 병렬 처리 할 때는 Open MP가 제 힘을 쓰지 못합니다. 물론 Open MP도 지속적인 발전을 거듭하고 있고, 수 년 내는 지금보다 더 복잡한 형태의 작업을 병렬 처리 할 수 있겠지만, 지금은 루프에만 한정되어 있는 것이 사실입니다. 이러한 한계에도 불구하고 Open MP는 휴대성이 뛰어나고 사용법도 간단하며, 거의 모든 플랫폼 및 컴파일러에 두루 적용할 수 있기 때문에 충분히 주목할 만 합니다. 병렬 처리 방식을 도입하기에는 Open MP만큼 쉽고 간단한 것이 없죠.

세 번째는 threaded building block 입니다. Threaded building blocks에 대해서는 다들 많이 듣거나 일고 있으실 것이라 생각합니다. 앞으로 더 주목 받을 것으로 예상됩니다. 여기서 잠깐 다른 이야기를 하자면, 저의 목표는 가공되지 않은 스레드에 빠져드는 것을 방지하고, 라이브러리들과 Open MP들을 적절히 활용할 수 있도록 함과 동시에 사용자가 또 어떤 것을 활용할 수 있을지 찾아볼 수 있는 여력을 제공하는 새로운 단계를 구현하는 것입니다. 라이브러리는 분명 그 시야의 한계가 있고, Open MP는 C와 포트란에서는 매우 유용하고 C++ 프로그램들에서도 사용되지만, C++프로그래머들의 입장에서는 Open MP 보다는 threaded building blocks를 더 선호할 수 밖에 없습니다. 데이터 병렬 처리에 한정되어 있는 Open MP보다, 상대적으로 더 복잡한 병렬 처리 작업을 수행할 수 있는 threaded building blocks가 더 유용하기 때문입니다.

자, 총 3가지에 대해 이야기 했습니다. 누구랑 대화를 하든 병렬 처리 관련 문제에 대해서는 항상 이 3가지 조언들을 순서대로 해주곤 합니다. 라이브러리, Open MP, 그리고 threaded building blocks 순으로 말이죠. 물론 가공되지 않은 스레드를 피하라는 이야기도 빠지지 않고 해줍니다. 왜냐하면 당신의 프로그램의 미래는 불확실하고, 점점 수정, 가공하기 힘들어질 정도로 복잡해 질 것이고, 당연히 더 많은 에러 발생 위험에 노출될 것이 뻔하기 때문입니다. 병렬 처리에 대해 고려하고 있다면 더더욱 그렇습니다. Open MP에 대한 더 많은 정보를 원하신다면 OpenMP.org에 들어가 보시고, thread building blocks에 대한 추가 설명이 필요하시면 threadbuildingblocks.org를 참조하십시오. 제가 제안 드린 3가지를 면밀히 살펴보신 후 성공적으로 프로그램을 만들어나가시길 바라겠습니다.