Небольшая программа OpenMP иногда зависает (gcc, c, linux) - PullRequest
1 голос
/ 20 декабря 2010

Просто напишите небольшой тест omp, и он не всегда будет работать правильно:

#include <omp.h>
int main() {
  int i,j=0;
#pragma omp parallel
  for(i=0;i<1000;i++)
  {
#pragma omp barrier
    j+= j^i;
  }
  return j;
}

Использование j для записи из всех потоков некорректно в этом примере, НО

  • должно быть только недетерминированное значение j

  • У меня заморозка.

Скомпилировано с gcc-4.3.1 -fopenmp a.c -o gcc -static

Запуск на 4-ядерном x86_Core2 сервере Linux: $ ./gcc и получил зависание (иногда; например, 1 остановка для 4-5 быстрых запусков).

Strace:

[pid 13118] futex(0x80d3014, FUTEX_WAKE, 1) = 1
[pid 13119] <... futex resumed> )       = 0
[pid 13118] futex(0x80d3020, FUTEX_WAIT, 251, NULL <unfinished ...>
[pid 13119] futex(0x80d3014, FUTEX_WAKE, 1) = 0
[pid 13119] futex(0x80d3020, FUTEX_WAIT, 251, NULL                       
                        <freeze>

Почему у меня заморозка (тупик)?

Ответы [ 3 ]

3 голосов
/ 22 декабря 2010

Попробуйте сделать меня приватным, чтобы у каждого цикла была своя копия.

Теперь, когда у меня больше времени, я попытаюсь объяснить. По умолчанию переменные в OpenMP являются общими. Есть пара случаев, когда есть значения по умолчанию, которые делают переменные закрытыми. Параллельные регионы не являются одним из них (поэтому ответ High Performance Mark неправильный). В исходной программе у вас есть два условия гонки - одно на i и одно на j. Проблема в том, что на мне. Каждый поток выполнит цикл несколько раз, но поскольку каждый поток меняет i, количество раз, когда любой поток выполняет цикл, является неопределенным. Поскольку все потоки должны выполнить барьер для того, чтобы барьер был удовлетворен, вы сталкиваетесь с случаем, когда вы будете зависать на барьере, который никогда не закончится, поскольку не все потоки будут выполнять его одинаковое количество раз. *

Поскольку в спецификации OpenMP четко указано (спецификация OMP V3.0, раздел 2.8.3 Конструкция барьера), «последовательность встречающихся областей разделения и барьерных областей должна быть То же самое для каждого потока в команде ", ваша программа не соответствует требованиям и, как таковая, может вести себя неопределенно.

1 голос
/ 21 декабря 2010

Вы пытаетесь добавить в одно место несколько потоков.Вы не можете делать то, что пытаетесь делать параллельно.Если вы хотите сделать сумму параллельно, вам нужно разделить ее на более мелкие части и затем собрать их.

Обновление по a5b: правильная идея, но обнаружена неправильная часть кода.Переменная i изменяется обоими потоками.

0 голосов
/ 19 января 2011

@ ejd, если я отмечу себя как личную, будет ли моя программа совместимой?

Извините - я только что увидел этот вопрос.Технически, если вы пометите переменную "i" как приватную, ваша программа будет совместима с OpenMP.ОДНАКО, по-прежнему существует условие гонки для "j", и хотя ваша программа соответствует требованиям (поскольку существуют допустимые случаи для условий гонки), значение "j" не указано (согласно спецификации OpenMP).

В одном из своих предыдущих ответов вы сказали, что пытаетесь измерить скорость внедрения барьера.Есть несколько «тестов», на которые вы можете посмотреть, которые опубликовали результаты для различных конструкций OpenMP.Один был написан Марком Буллом (EPCC, Университет Эдинбурга), другой (Сфинкс) из Ливерморской национальной лаборатории им. Лоуренса (LLNL), а третий (Parkbench) из Японского компьютерного партнерства.Они могут предложить вам некоторые рекомендации.

...