2016-11-25 1 views
0

OpenMP로 다음 코드의 실행 속도를 높이려고합니다. 이 코드는 만델 브로를 계산하여 캔버스로 출력합니다.OpenMP로 코드 실행 속도가 느림

이 코드는 단일 스레드로 작동하지만 OpenMP를 사용하여 빠르게 처리하려고합니다. 개인 변수와 공유 변수를 여러 가지 조합으로 시도했지만 지금까지 아무 것도 작동하지 않는 것 같습니다. 코드는 OpenMP가 없으면 항상 느리게 실행됩니다 (50 000 반복 - 2 초 느림).

나는 우분투 16.04를 사용하고 있고 GCC로 컴파일 중이다.

void calculate_mandelbrot(GLubyte *canvas, GLubyte *color_buffer, uint32_t w, uint32_t h, mandelbrot_f x0, mandelbrot_f x1, mandelbrot_f y0, mandelbrot_f y1, uint32_t max_iter) { 
mandelbrot_f dx = (x1 - x0)/w; 
mandelbrot_f dy = (y1 - y0)/h; 
uint16_t esc_time; 
int i, j; 
mandelbrot_f x, y; 

//timer start 
clock_t begin = clock(); 

#pragma omp parallel for private(i,j,x,y, esc_time) shared(canvas, color_buffer) 
for(i = 0; i < w; ++i) { 
    x = x0 + i * dx; 
    for(j = 0; j < h; ++j) { 
     y = y1 - j * dy; 
     esc_time = escape_time(x, y, max_iter); 

     canvas[ GET_R(i, j, w) ] = color_buffer[esc_time * 3]; 
     canvas[ GET_G(i, j, w) ] = color_buffer[esc_time * 3 + 1]; 
     canvas[ GET_B(i, j, w) ] = color_buffer[esc_time * 3 + 2]; 

     } 
} 

//time calculation 
clock_t end = clock(); 
double time_spent = (double)(end - begin)/CLOCKS_PER_SEC; 
printf("%f\n",time_spent); 
} 
코드 사용

escape_time 기능 :

inline uint16_t escape_time(mandelbrot_f x0, mandelbrot_f y0, uint32_t max_iter) { 
mandelbrot_f x = 0.0; 
mandelbrot_f y = 0.0; 
mandelbrot_f xtemp; 
uint16_t iteration = 0; 
while((x*x + y*y < 4) && (iteration < max_iter)) { 
    xtemp = x*x - y*y + x0; 
    y = 2*x*y + y0; 
    x = xtemp; 
    iteration++; 
} 
return iteration; 

}

주석에 암시 같은 코드는이 저장소로부터 https://github.com/hortont424/mandelbrot

+5

가능한 [OpenMP 시간 및 클록()은 두 가지 다른 결과를 계산합니다] (http://stackoverflow.com/questions/10673732/openmp-time-and-clock-calculates-two-different-results) –

답변

1

먼저이다 omp_get_wtime() 대신 clock() 사용 (모든 스레드에서 누적 된 클럭 틱 수를 제공합니다) 시간을 측정합니다. 내가 올바르게 기억 둘째,이 알고리즘은로드 밸런싱 문제를, 그래서 동적 스케줄링 사용하려고 :

내 문제를 제안했다으로
//timer start 
double begin = omp_get_wtime(); 

#pragma omg parallel for private(j,x,y, esc_time) schedule(dynamic, 1) 
for(i = 0; i < w; ++i) { 
    x = x0 + i * dx; 
    for(j = 0; j < h; ++j) { 
     y = y1 - j * dy; 
     esc_time = escape_time(x, y, max_iter); 

     canvas[ GET_R(i, j, w) ] = color_buffer[esc_time * 3]; 
     canvas[ GET_G(i, j, w) ] = color_buffer[esc_time * 3 + 1]; 
     canvas[ GET_B(i, j, w) ] = color_buffer[esc_time * 3 + 2]; 

     } 
} 

//time calculation 
double end = omp_get_wtime(); 
double time_spent = (double)(end - begin)/CLOCKS_PER_SEC; 
printf("%f\n",time_spent); 
+0

무엇입니까? 이 질문에 문제가 있습니까? 3 번 연속으로 사람들이 아무 말도하지 않고 나를 투표하는 것입니다. – dreamcrash

+0

중복 깃발을 쓴 다른 사람이나 다른 사람이 중복 된 질문에 대한 답변을 받기 위해 다른 사람을 볼 가치가 없다고 생각하는 사람이있을 수 있습니다. 좋은 답변입니다. 링크 된 Q보다 훨씬 포괄적이고 구체적입니다. 여기에 +1이 있습니다. –

+0

대부분의 지원에 감사합니다. – dreamcrash

0

가 CPU 시간을 측정하는 시계() 함수를 사용하여 발생했습니다. 대신 omp_get_wtime()을 사용하면 문제가 해결됩니다.

+0

동적으로 테스트하고 실적이 개선되는지 알려주시겠습니까?, 궁금한 점이 있습니다. 감사합니다. – dreamcrash

+0

나는 학교에서 과제를 배웠으므로이 옵션도 테스트했다. 차이를 만들지 않았습니까? – martin49

관련 문제