Search

'parallel_invoke'에 해당되는 글 2건

  1. 2009.10.20 Parallel Patterns Library(PPL) - parallel_invoke
  2. 2009.08.19 Parallel Patterns Library(PPL) - 병렬 알고리즘

parallel_invoke는 일련의 태스크를 병렬로 실행할 때 사용합니다. 그리고 모든 태스크가 끝날 때까지 대기합니다. 이 알고리즘은 복수의 독립된 태스크를 실행할 때 유용합니다.

 

일련의 태스크를 병렬로 실행할 때 사용이라는 것을 들었을 때 생각나는 것이 없는가요? 지금까지 제가 올렸던 글을 보셨던 분이라면 parallel task라는 말이 나와야 합니다. ^^

parallel_invoke parallel task와 비슷합니다.

 

 

parallel_invoke parallel task의 다른 점

복수 개의 태스크를 병렬로 실행한다는 것은 둘 다 같지만 아래와 같은 차이점이 있습니다.


 

parallel_invoke

parallel task

편이성

작업 함수만 정의하면 된다.

작업 함수를 만든 후 task handle로 관리해야 한다.

태스크 개수

10개 이하만 가능

제한 없음

모든 태스크의 종료 시 대기

무조건 모든 태스크가 끝날 때까지 대기

Wait를 사용하지 않으면 대기 하지 않는다.



parallel_invoke를 사용할 때

병렬로 실행할 태스크의 개수가 10개 이하이고, 모든 태스크가 종료 할 때까지 대기해도 상관 없는 경우에는 간단하게 사용할 수 있는 parallel_invoke를 사용하는 것이 좋습니다. 하지만 반대로 병렬로 실행할 태스크가 10개를 넘고 모든 태스크의 종료를 대기하지 않아야 할 때는 parallel task를 사용해야 합니다.

 

 

parallel_invoke 사용 방법

parallel_invoke는 병렬로 태스크를 두 개만 실행하는 것에서 10개까지 실행하는 9개의 버전이 있으며 파라미터를 두 개만 사용하는 것에서 10개의 파라미터를 사용하는 것으로 오버로드 되어 있습니다.

각 오버로드된 버전의 파라미터에는 태스크를 정의한 작업 함수를 넘겨야 합니다.

 

 

parallel_invoke 사용 예

아래 예제는 아주 간단한 것으로 게임 프로그램이 처음 실행할 때 각종 파일을 로딩하는 것을 아주 간략화 하여 parallel_invoke를 사용한 예입니다.

 

#include <iostream>

#include <ctime>

#include <windows.h>

#include <concrt.h>

#include <concrtrm.h>

using namespace std;

 

#include <ppl.h>

using namespace Concurrency;

 

// UI 이미지 로딩

void LoadUIImage()

{

           Sleep(1000);

           cout << "Load Complete UI Image" << endl;

}

 

// 텍스쳐 로딩

void LoadTexture()

{

           Sleep(1000);

           cout << "Load Complete Texture" << endl;

}

 

// 폰트 파일 로딩

void LoadFont()

{

           Sleep(1000);

           cout << "Load Complete Font" << endl;

}

 

int main()

{

           parallel_invoke( [] { LoadUIImage(); },

                      [] { LoadTexture(); },

                      [] { LoadFont(); }

                    );

          

           getchar();

           return 0;

}

 

< 실행 결과 >



위 예제를 parallel_invoke를 사용하지 않고 전통적인 방법으로 순서대로 실행했다면 각 작업 함수에서 1초씩 소비하므로 3초가 걸리지만 parallel_invoke를 사용하여 1초만에 끝납니다.

 

그리고 이전에 parallel_for에서도 이야기 했듯이 병렬로 실행할 때는 순서가 지켜지지 않는다는 것을 꼭 유의하시기 바랍니다. 위의 예의 경우도 LoadUIImage()을 첫 번째 파라미터로 넘겼지만 실행 결과를 보면 LoadFont()가 먼저 완료 되었습니다.

 


마지막으로 위의 예제코드에서 parallel_invoke와 관계 있는 부분만 추려볼 테니 확실하게 사용 방법을 외우시기를 바랍니다.^^

 

#include <ppl.h>

using namespace Concurrency;

 

// 태스크 정의

void LoadUIImage()

{

............

}

 

void LoadTexture()

{

............

}

 

void LoadFont()

{

............

}

 

int main()

{

        parallel_invoke( [] { LoadUIImage(); },

                                 [] { LoadTexture(); },

                                 [] { LoadFont(); }

                          );

 

}


저작자 표시
신고

Parallel Patterns Library(이하 PPL)에는 데이터 컬렉션을 대상으로 쉽게 병렬 작업을 할 수 있게 해 주는 알고리즘이 있습니다. 이 알고리즘들은 생소한 것들이 아니고 C++의 표준 템플릿 라이브러리(STL)에서 제공하는 알고리즘과 비슷한 모양과 사용법을 가지고 있습니다.

( *데이터 컬렉션은 데이터 모음으로 배열이나 STL 컨테이너를 생각하면 됩니다 )

 

 

PPL에서 제공하는 병렬 알고리즘은 총 세 개가 있습니다.

 

1. parallel_for        알고리즘

2. parallel_for_each 알고리즘

3. parallel_invoke    알고리즘

 

 

세 개의 알고리즘 중 3 parallel_invoke만 생소하지 1번과 2번은 앞의 ‘parallel_’이라는 글자만 빼면 ‘for’‘for_each’ C++로 프로그래밍할 때 자주 사용하는 것이므로 친숙하게 느껴질 겁니다.

실제 병렬 여부만 제외하면 우리가 알고 있는 것들과 비슷한 동작을 합니다. 그래서 쉽게 배울 수 있고 기존의 코드에 적용하기도 쉽습니다.

 


parallel_for 알고리즘은 일반적인 for문을 사용할 때와 비슷하게 데이터 컬렉션에서 시작할 위치와 마지막 위치, 증가분(생략 가능합니다)에 해야할 작업 함수를 파라미터로 넘기면 됩니다. 사용 방법에서 for문과 다른 점은 작업 함수를 넘긴다는 점입니다.

 

parallel_for_each 알고리즘은 기존 for_each와 거의 같습니다. 데이터 컬렉션에서 시작할 위치, 마지막 위치, 작업 함수를 파라미터로 넘기면 됩니다. parallel_for의 경우 기존의 for문을 사용할 때는 작업 함수를 파라미터로 넘기지 않기 때문에 기존 for 문에 비해서 구조가 달라지지만 parallel_for_each는 기존 for_each와 파라미터 사용 방법이 같기 때문에 알고리즘의 이름만 바꾸면 될 정도입니다.

 

parallel_invoke 알고리즘 이전 회에 설명한 태스크 그룹과 비슷한면이 있습니다. 태스크 그룹과의 큰 차이점은 병렬로 할수 있는 작업은 10개로 제한 되지만 사용 방법은 태스크 그룹보다 더 간결한 점입니다다. 병렬 작업의 개수가 10개 이하인 경우 태스크 그룹보다 parallel_invoke를 사용하는 것이 훨씬 더 적합하다고 생각합니다.

 

 

 

 

이번은 간단하게 PPL에 있는 세 가지 병렬 알고리즘을 소개하는 것으로 마칩니다. 다음 회부터는 이번에 소개했던 세 개의 알고리즘을 하나씩 하나씩 자세하게 설명하겠습니다.

저작자 표시
신고