원본기사 : http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=38540
흠.. 오랫만에 보는 병렬프로그래밍 관련 기사군요. 뭐... 잘 작성하셨지만.. 몇가지만 딴지를 걸어보고.. 많은 분들이 오해할 수 있는 부분을 지적해 보겠습니다.
1. 병렬프로그래밍을 하면 속도가 CPU갯수만큼 빨라진다?
답은 '아니오'다. 프로그램 코드의 모든 부분을 전부 병렬화 할 수는 없습니다. 병렬처리가 되려면.. 병렬처리할 구간의 data는 독립적이어야합니다. 병렬화를 시키는 곳은 주로 loop안에서 일어납니다. (사실.. loop 구간에 대해서 병렬화를 시킵니다.)
가령 다음과 같은 두개의 코드가 있다고 해 봅시다.
for( int i = 0 ; i < 10000 ; i++) { res = res + i; } |
for( int i = 0 ; i < 10000 ; i++) { printf( "%d", i); } |
오른쪽의 코드의 경우 data i는 이전 loop와는 별도로 돌아갈 수 있습니다.
그러나 왼쪽의 코드의 경우 res = res + i라는 구문을 보면.. res는 이전 loop를 수행한 결과를 담고 있습니다. 즉, 다시 말해서.. i == 10일때.. res값은 i가 9일때까지의 결과를 담고 있습니다. 즉, loop가 10번째 실행되었을 때, 9번째 loop의 수행 결과를 가지고 있어야 한다는 것입니다. 이걸 데이터 의존이라 하는데요. 데이터 의존도가 큰 구간에 대해서는 애석하게도 병렬화를 시킬 수 없습니다.
그리고 쿼드코어 CPU라 하여도, 각 Core들이 병렬로 나누어진 구간에 대해서.. 완벽히 100% 동일한 수행시간을 가진다고 볼 수 없습니다. 그러면.. 병렬화 구간이 끝나는 시점에서는 모든 코어들이 다 작업을 마칠때까지 대기하는 시간도 필요합니다. (물론 그 차이는 크지 않습니다. 특히 멀티코어 CPU에서 동작하는 OpenMP의 경우에는 더욱 크지 않고요. 다만 클러스터에서 유용한 MPI의 경우 각 노드의 성능에 따라.. 이 대기시간은 조금 생길 수 있습니다. 물론 작업 배분을 잘 하면.. 이 차이는 줄어들 것입니다.)
이러한 이유들로.. 코어 두개를 다 쓴다 하여도.. 40%정도 성능향상이 이루어지면.. 높은 성능 향상을 이룬 것이랍니다. :D 어떤 프로그램이냐에 따라 그 차이는 크겠지만.. 일반적인 프로그램은 40%만 향상되도 꽤 높은 성능 향상입니다.
2. 병렬프로그래밍은 어렵다?
답은 '아니오'다. OpenMP나 MPI나.. 둘 다 매우 개발자가 사용하기 편하도록 되어 있습니다. OpenMP의 경우 #pragma 키워드를 이용해서 특정 키워드만 넣어주면 알아서 해당 구간을 병렬화 시켜줍니다. 절대 어렵지 않죠. MPI의 경우 MPI의 API를 호출해주면 됩니다. 다만.. MPI의 경우 각 노드들에게 처리할 데이터를 어떻게 나누어주느냐.. 이것은 고민을 해야하겠죠. 1GHz CPU를 가진 노드에 500MB의 데이터를 주고 처리하라고 하고.. 2GHz CPU를 가진 노드에도 500MB의 데이터를 주고 처리하라고 하면.. 별로 효율적일 순 없겠죠?
그리고.. 병렬프로그래밍이 어렵다면.. 어느 구간을 병렬화 시킬 것인가! << 사실 요걸 결정하는게 어렵습니다. 병렬화 시키는 구간에는 오버헤드가 존재합니다. 병렬화 시킬 필요가 없는 구간에도 무작정 병렬화를 시키는 것은 좋을 수 없겠지요.
3. CUDA나 OpenCL의 경우 병렲프로그래밍일수도 있으나.. GPU를 이용한 프로그래밍이라 하는것이 좀 더 맞을것 같긴 합니다. (요건 개인적 생각)
CUDA나 OpenCL에 대해서 간략하게 설명드리겠습니다. 둘다 GPU를 활용한 고성능 컴퓨팅의 기법입니다. 요즘 GPU는 예전처럼 단순히 그래픽만 보여주는 영역을 벗어났습니다. 3D작업을 처리하기 위한 특성상 실수의 사칙연산등 간단한 연산에 있어서는 엄청나게 빠른 처리능력을 보여주고 있습니다. (그러나 CPU처럼 모든 명령을 다 처리하는 녀석은 아닙니다. 다만 GPU가 하는 연산들에 있어서는 무시무시한 속도를 자랑합니다.) 이러한 GPU가 이제는 Co-Processor로써 매우 유용하게 되었습니다. 이러한 GPU를 사용하여 단순 연산이 많은 구간에 대해서 GPU로 작업을 던져서 빠른 처리를 하도록 해주는 라이브러리가 CUDA입니다. (ATI진영에서는 OpenCL을 지원하기위해 ATI Stream SDK인가를 제공하고 있고요. nVidia의 CUDA에서는 OpenCL에 맞게 지원하고 있습니다.) 이것 역시 사용법은 어렵지 않습니다. GPU를 사용할 구간을 정하고, 처리할 데이터들을 몇개의 블럭으로 나눌지(각 블럭당 얼마만큼의 Data를 처리하도록 할지..) 만 결정해서 함수를 호출해주면.. 알아서 다 처리해 줍니다. 이 기법은 실수 연산이 많은 프로그램에 하면 매우 높은 성능을 낼 수 있습니다. (실제로.. 테스트용으로 double형 행렬 곱셈을 해봤는데요. 3000*3000정도 크기로요.. 블럭 크기에 따라서 잘 맞추면 10배~20배에서.. 최고 140배정도까지 나왔던 적도 있습니다. nVidia CUDA day에 갔을때는.. 보니까.. 270배도 터지고 그렇더군요. 물론 최적화를 좀 시키셨겠지만..)
OpenCL이나 OpenMP, MPI 모두.. 고성능 컴퓨팅을 위해 유용한 기법인 것은 확실합니다. 하지만 각각의 사용 목적에 맞게 잘 나누어서 쓰는것이 좋겠지요.
요즘들어 병렬 프로그래밍 관련된 것이 많이 보이니까 다행입니다. (열심히 공부해서 논문쓴건데.. 사장되면 슬프니까요 ㅋㅋㅋ) 그러나 아직 실무에서 사용되기까진 갈길이 멀다는 것이 좀 아쉬울뿐입니다. 하지만 병렬프로그래밍은 이제 앞으로 대세가 될 것으로 예상됩니다. (멀티코어 CPU가 대세가 될터이니...) 너무 어렵게 생각하지 마세요. 정말.. 레퍼런스도 많고.. OpenMP나 MPI등은 개발자가 정말 개발하기 편하게 만들어져 있답니다.
반응형
댓글