2013-11-19 1 views
1

На linux AMD 8-ядерный процессор с использованием g ++ 4 7.1.OpenMP-распараллеливание перестало работать

Это - для меня - головной убор. Этот следующий код работал отлично и по какой-то причине прекратил распараллеливать. Я добавил omp_get_num_procs(), и он печатает 8 процессоров. Я проверил компилятор, и -fopenmp присутствует как опция как для компоновки, так и для компиляции. Сообщение об ошибке компиляции/ссылки отсутствует. Я проверил, были ли определены какие-либо переменные среды (OMP_xxx) - их не было.

Существуют ли другие - внешние факторы, которые могут повлиять?

#pragma omp parallel 
{ 
    lightray ray; 
    rgba L; 
    printf("Max nr processors: %d\n", omp_get_num_procs()); 

    #pragma omp for schedule(dynamic) 
    for (int xy = 0; xy < xy_range; xy++) { 
    int x = x_from + (xy % x_width); 
    int y = y_from + (xy/x_width); 
    ray = cam->get_ray_at(x, y); 
    L = trace_ray(ray, 0, cam->inter); 
    cam->set_pixel(x, y, L); 
    } 
} 
dtime = omp_get_wtime() - dtime; 
printf("time %f\n", dtime); 
} 

EDIT: Я думаю, что я нашел что-то здесь ... Командная строка для г ++, порожденного Anjuta содержит следующее:

-DPACKAGE_LOCALE_DIR=\""/usr/local/share/locale"\" -DPACKAGE_SRC_DIR=\"".. -fopenmp . "\" 

Определение PACKAGE_SRC_DIR, кажется, «включить» в -fopenmp флаг , который скроет его из g ++. Не нашли причину еще ...

+0

Где находится 'xy_range'? – Richard

+0

'rgba L' и' lightray ray' создают взаимозависимость между итерациями цикла, которые могут отбрасывать компилятор, нужно ли их определять за пределами цикла? – Mgetz

+0

int xy_range; (значение постоянное - никакого конфликта. О переменных rgba и lightray, я пробовал как внутри, так и снаружи - никакой разницы, и это работало раньше, так же как и сейчас. Спасибо, хотя! – jcoppens

ответ

0

Try переписывания так:

lightray ray; 
rgba L; 
printf("Max nr processors: %d\n", omp_get_num_procs()); 

#pragma omp parallel for schedule(dynamic) private(ray,L) 
for (int xy = 0; xy < xy_range; xy++) { 
    int x = x_from + (xy % x_width); 
    int y = y_from + (xy/x_width); 
    ray = cam->get_ray_at(x, y); 
    L = trace_ray(ray, 0, cam->inter); 
    cam->set_pixel(x, y, L); 
} 
dtime = omp_get_wtime() - dtime; 
printf("time %f\n", dtime); 

Таким образом, вы приведете ray и L как переменные специфичные для каждого из потоков тегов объединившись цикла. Поскольку переменные, определенные за пределами параллельного региона, по умолчанию делятся потоками, ваша текущая реализация объединяет эти две переменные.

Кроме того, omp_get_num_procs() «Возвращает количество процессоров, доступных для программы». в соответствии с OpenMP API 3.1 C/C++ Syntax Quick Reference Card - поэтому он не обязательно расскажет вам, сколько потоков фактически используется в регионе. Для этого вам может понадобиться omp_get_num_threads() или omp_get_thread_num()

+0

Запуск сейчас, но кажется, не имеет никакого значения. Все еще занимает только 1 ядро.Я действительно чувствую, что есть что-то внешнее (чтобы программировать), которое не позволяет занимать все ядра. Спасибо хоть! – jcoppens

+0

omp_get_num_procs: 8 omp_get_num_threads: 1 – jcoppens

+0

Я добавил num_threads (8) в #pragma omp parallel и все равно получаю omp_get_num_threads: 1. Итак, что-то _is_ limit ... – jcoppens

0

Кажется, что проблема была внешней по отношению к программе. Я изменил версии IDE (Anjuta). Anjuta очень зависит от pkg-config. У OpemMP нет файлов pkg-config .pc, поэтому я сделал один для библиотеки libgomp. Я добавил -lgomp в Libs: все прошло отлично, и добавлено -fopenmp для обеих Libs: и Cflags: это не пошло хорошо.

По какой-то причине -fopenmp был добавлен в параметр командной строки с именем -DPACKAGE_SRC_DIR (внутри его цитируемого значения - см. Править в исходном сообщении) и как таковой был проигнорирован компоновщиком и компилятором. Я спрошу об этом на форуме Anjuta.

Итак, решение заключалось в том, чтобы удалить его из файла .pc и добавить его вручную к параметрам проекта как 'CXXFLAGS = -fopenmp' 'LDFLAGS = -fopenmp' (я хотел избежать этого, так как в следующий раз я Я забуду это сделать :)

В любом случае, это работает так. Спасибо за предложения.