使用OpenMP执行代码的速度较慢

时间:2016-11-25 21:04:42

标签: c performance openmp mandelbrot

我正在尝试使用OpenMP加速执行以下代码。该代码用于计算mandelbrot并将其输出到画布。

代码运行良好的单线程,但我想使用OpenMP使其更快。我尝试了各种私有和共享变量的组合,但到目前为止似乎没有任何工作。对于OpenMP,代码总是比没有它的情况慢一点(50 000次迭代 - 慢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

2 个答案:

答案 0 :(得分: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 );

答案 1 :(得分:0)

因为有人建议我的问题是由使用clock()函数引起的,该函数测量CPU时间。 使用omp_get_wtime()代替解决了我的问题。