2016-11-25 133 views
0

我试图用OpenMP加速执行以下代码。该代码用于计算mandelbrot并将其输出到画布。使用OpenMP的代码执行速度较慢

该代码工作正常,单线程,但我想使用OpenMP,使其更快。我尝试了各种私有和共享变量的组合,但似乎没有任何工作到目前为止。与没有OpenMP相比,代码总是运行得慢一点(50000次迭代 - 慢了2秒)。

我使用Ubuntu 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

什么是这个问题的问题?它连续三次让人投票给我,而没有说什么。 – dreamcrash

+0

我认为这可能来自给出重复标志的其他人,或者是看到它并认为其他用户不值得获得代表重复问题答案的人的人。这是一个很好的答案,这里比链接的问题更加全面和具体。这里有一个+1补偿。 –

+0

最有可能的,谢谢你的支持 – dreamcrash

0

至于有人提出我的问题是使用时钟()函数,是衡量CPU的时间造成的。 使用omp_get_wtime()代替解决了我的问题。

+0

你可以用动态测试并告诉我它是否能改善你的表现吗?,我很想知道,谢谢。 – dreamcrash

+0

我做过了,这是一个学校作业,所以我也测试了这个选项。没有真正有所作为。 – martin49