본문 바로가기

병렬프로그래밍

tbb를 배워보자.. parallel_for의 사용법.. 1

OpenMP, PPL, TBB 이 3개중 한개만이라도 일단 배워보자 하는 마음에.
어제 속도 테스트에 혹해서 TBB에 대해서 본격적으로 배워보기로 했습니다..

먼저
TBB의 parallel_for에 대해서 알아보겠습니다..

 
#include <iostream> 
#include <string> #include <tbb\tbb.h> 
#include <time.h>
#include <vector>

using namespace std;

class TbbTest
{
  std::vector<int>* const m_vecTest;
public:
  void operator() (tbb::blocked_range<int>&r) const
  {
    std::vector<int>* vecTemp = m_vecTest;
    for(int i = r.begin(); i != r.end(); i++)
    {
      (*vecTemp)[i]=i;
    }
  }

  TbbTest(std::vector<int> &vecTemp)
   :m_vecTest(&vecTemp)
  {
  }
};


int _tmain()  
{ 
 const int MAX_NUM  = 100000000;
 time_t start,stop;
 
 tbb::task_scheduler_init init;
 std::vector<int> vecTest(MAX_NUM);
 
 start = clock();
 tbb::parallel_for(tbb::blocked_range<int>(0,MAX_NUM),TbbTest(vecTest));
 stop = clock();
 cout << "Grainsize 미지정 : " << double(stop - start) /double(CLOCKS_PER_SEC) << endl; 
 
 start = clock();
 tbb::parallel_for(tbb::blocked_range<int>(0,MAX_NUM,MAX_NUM/4),TbbTest(vecTest));
 stop = clock();
 cout << "Grainsize 지정 : " << double(stop - start) /double(CLOCKS_PER_SEC) << endl; 
 
 start = clock();
 tbb::parallel_for(tbb::blocked_range<int>(0,MAX_NUM),TbbTest(vecTest),tbb::auto_partitioner());
 stop = clock();
 cout << "자동지정 : " << double(stop - start) /double(CLOCKS_PER_SEC) << endl; 


 start = clock();
 tbb::parallel_for(tbb::blocked_range<int>(0,MAX_NUM),
  [&vecTest](const tbb::blocked_range<int>&r)
  {
    for(int i = r.begin(); i != r.end(); i++)
    {
     vecTest[i]=i;
    }
  });
 stop = clock();
 cout << "람다로 TBB사용 : " << double(stop - start) /double(CLOCKS_PER_SEC) << endl; 
	
 return 0; 
}



아래결과는  릴리즈모드, 속도최적화 사용안함 상태일때의 결과입니다.



병렬프로그램이라 매번 결과가 다르게 나오지만 평균적으로 2<1=4<3번의 결과가 나옵니다.
테스트 환경의 컴퓨터가 쿼드코어라서 정확히 4등분해서 실행한 2번재의 결과가 빠를수 밖에 없었고
3번의 같은경우 자동으로 분활해준다고 하는데.. 미지정한것보다 느리면.. 쓰지 말아야 되나요 ;;;
이런 단순한 코드 말고 다른경우에도 실험좀 해봐야겠네요...


다시한번 집고 넘어가면
TBB같은경우는 TbbTest 클래스와
void operator() (tbb::blocked_range<자료형>&r) const
같은 연산자가 꼭있어야만 사용가능합니다..(vs2010이상에서는 람다로 4번째처럼 사용하셔도 상관없습니다..)

tbb::parallel_for() 에서 tbb::blocked_range<int>(0,n,Grain)의 의미는
0부터 n-1까지 돌려라~ 이고 3번째 Grain은 분활자 즉 각각의 쓰레드에 몇개의 for문을 분활할지 정하는 변수입니다.

만약   tbb::blocked_range<int>(0,100,100) 이렇게 사용하면 쿼드코어라도 for문은 한개의 코어만을 사용하게 됨니다.
위의 문장은 0부터 99까지 for문을 도는데 쓰레드당 100개씩 할당하겠다는 의미이며
한개의 코어에 100개를 할당했기때문에 나머지 3개의 코어들은 놀고 있는것이지요...


parallel_for은 여기까지 입니다...
다음은 parallel_reduce입니다..