2016-11-25 22 views
0

Я пытаюсь ускорить выполнение следующего кода с помощью OpenMP. Код предназначен для вычисления мандельброта и вывода его на холст.Выполнение кода медленнее с помощью OpenMP

Код работает отлично однопоточным, но я хочу использовать 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

+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

Я думаю, что это может быть от другого человека, который дал дубликат флага, или того, кто его видел, и думал, что другие пользователи не заслуживают ответа на ответ на дублированный вопрос. Это приятный ответ, гораздо более всеобъемлющий и конкретный здесь, чем в связанном Q. Вот +1, чтобы компенсировать. –

+0

Скорее всего, спасибо за поддержку – dreamcrash

0

Как было предложено моя проблема была вызвана с помощью функции синхронизации(), который измеряет время центрального процессора. Использование omp_get_wtime() вместо этого решило мою проблему.

+0

Не могли бы вы протестировать с динамикой и сказать мне, улучшит ли производительность? Мне любопытно узнать, спасибо. – dreamcrash

+0

Я сделал это, это было школьное задание, поэтому я также опробовал этот вариант. На самом деле ничего не изменилось. – martin49

 Смежные вопросы

  • Нет связанных вопросов^_^