Перестал работать распараллеливание OpenMP

На Linux 8-ядерный процессор AMD, использующий g ++ 4 7.1.

Это — для меня — хедбэнгер. Этот следующий код работал отлично, и по какой-то причине прекратил распараллеливание. Я добавил 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);
}

РЕДАКТИРОВАТЬ: я думаю, что я нашел что-то здесь … Командная строка для g ++, сгенерированная Anjuta, содержит это:

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

Кажется, что определение PACKAGE_SRC_DIR «включает» флаг -fopenmp, что скрыло бы его от g ++. Пока не нашли причину …

1

Решение

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

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

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

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

0

Другие решения

Попробуйте переписать это так:

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() Msgstr «Возвращает количество процессоров, доступных программе.» в соответствии с краткой справочной картой синтаксиса OpenMP API 3.1 C / C ++ — поэтому не обязательно указывается, сколько потоков фактически используется в регионе. За это вы можете захотеть omp_get_num_threads() или же omp_get_thread_num()

0

По вопросам рекламы [email protected]