2012-05-14 4 views
5

OpenMP를 사용하여 간단한 응용 프로그램을 작성하려고합니다. 불행히도 나는 speedup에 대한 문제가있다. 이 응용 프로그램에서는 루프가 하나 있습니다. 이 루프의 본문은 순차적으로 수행되어야하는 명령어와 루프에 대한 명령어로 구성됩니다. 나는이 루프를 병렬로 만들기 위해 #pragma omp parallel for을 사용한다. 이 루프는 많은 작업을하지는 않지만 매우 자주 호출됩니다.OpenMP - 한 번만 스레드 만들기

두 개의 for 루프 버전을 준비하고 1, 2 및 4 코어에서 응용 프로그램을 실행합니다.
버전 1 (for 루프의 반복 횟수 : 22 초, 23 초, 26 초).
버전 2 (for 루프에서 100000 반복) : 20 초, 10 초, 6 초

앞에서 볼 수 있듯이 for 루프에 많은 작업이 없으면 2 코어 및 4 코어의 시간이 1 코어보다 높습니다. 그 이유는 #pragma omp parallel for은 while 회 돌이마다 새로운 스레드를 생성한다는 것입니다. 그래서, 나는 당신에게 물어볼 것이다. - while 루프 이전에 한 번 쓰레드를 만들 수있는 가능성이 있는가? while 루프의 일부 작업이 순차적으로 수행 될 수 있도록 보장 할 것인가?

#include <omp.h> 
#include <iostream> 
#include <math.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
int main(int argc, char* argv[]) 
{ 
    double sum = 0; 
    while (true) 
    { 
     // ... 
     // some work which should be done sequentially 
     // ... 

     #pragma omp parallel for num_threads(atoi(argv[1])) reduction(+:sum) 
     for(int j=0; j<4; ++j) // version 2: for(int j=0; j<100000; ++j) 
     { 
      double x = pow(j, 3.0); 
      x = sqrt(x); 
      x = sin(x); 
      x = cos(x); 
      x = tan(x); 
      sum += x; 

      double y = pow(j, 3.0); 
      y = sqrt(y); 
      y = sin(y); 
      y = cos(y); 
      y = tan(y); 
      sum += y; 

      double z = pow(j, 3.0); 
      z = sqrt(z); 
      z = sin(z); 
      z = cos(z); 
      z = tan(z); 
      sum += z; 
     } 

     if (sum > 100000000) 
     { 
      break; 
     } 
    } 
    return 0; 
} 

답변

5

당신은 while (true) 루프의 외부 병렬 지역을 이동하고 코드의 시리얼 부분은 하나 개의 스레드에서 실행할 수 있도록하기 위해 single 지시어를 사용할 수 있습니다. 그러면 포크/조인 모델의 오버 헤드가 제거됩니다. 또한 OpenMP는 매우 적은 반복 횟수 (예 : 버전 1)의 thight 루프에서는 유용하지 않습니다. 기본적으로 루프 내부의 작업은 매우 빨라졌습니다. 초월 함수를 사용하는 반복 횟수는 현재 세대 CPU에서 2 초 미만입니다 (2GHz 및 FP 이외의 약 100 사이클을 추가하는 것 외에는 ~ 100 ms 걸릴).

OpenMP를 선택적으로 작은 루프의 parallelisation을 해제하는 데 사용할 수있는 if(condition) 절 제공 이유

: 또한 일반 루프에 대한 schedule(static) (즉 루프입니다 사용하는 것이 좋습니다

#omp parallel for ... if(loopcnt > 10000) 
for (i = 0; i < loopcnt; i++) 
    ... 

을하는 모든에 반복은 계산하는 데 거의 동일한 시간이 소요됨).

8

대부분의 OpenMP 구현은 프로그램 시작시 많은 스레드를 생성하고 프로그램 기간 동안 유지합니다. 즉, 대부분의 구현은 실행 중에 동적으로 스레드를 만들고 파괴하지 않습니다. 이렇게하면 심각한 스레드 관리 비용으로 성능에 영향을 미칩니다. 스레드 관리에 대한이 접근 방식은 OpenMP의 일반적인 사용 사례와 일치하며 적절합니다.

OpenMP 스레드의 수를 늘릴 때 속도가 느려지는 것은 반복 횟수가 적은 루프에 병렬 오버 헤드가 부과되는 것입니다. Hristo의 답변이 이것을 다룹니다.