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

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

Это - для меня - headbanger. Этот следующий код работал отлично, и по какой-то причине прекратил распараллеливание. Я добавил 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++. Пока не нашли причину...

2 ответа

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

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

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

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

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

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()

Другие вопросы по тегам