Использование блокировки в OpenMP и Pthreads - PullRequest
1 голос
/ 14 апреля 2011

У меня есть программа, которая использует как Pthreads, так и OpenMP. По сути, 2 потока (потоки A и B) создаются с использованием Pthreads для выполнения работы, а в потоке A OpenMP используется для распараллеливания цикла for.

Если у меня есть глобальная переменная, к которой обращаются потоки OpenMP, а также поток B, могу ли я использовать блокировку в OpenMP, чтобы убедиться, что у меня нет условий гонки?

Что я имею в виду:

int count = 0;

pthread_create(&ThreadA, &attr, WorkA, NULL);
pthread_create(&ThreadB, &attr, WorkB, NULL);

void *WorkA (void *t)
{
   #pragma omp parallel for
   for (i = 0 ; i < N ; i++)
   {
      // Do some work
      #pragma omp critical
      {
         // Do some other work
         OMP_SET_LOCK(&lock);
         count++;
         OMP_UNSET_LOCK(&lock);
      }
   }
}

void *WorkB (void *t)
{
   if (count > 0)
   {
      OMP_SET_LOCK(&lock);
      count--;
      OMP_UNSET_LOCK(&lock);
      // Do some work
   }
}

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 апреля 2011

Используйте атомарные операции для изменения количества.Во-первых, использование мьютекса для защиты простого ++ или - не нужно.Мьютексы предназначены для защиты всего, что не может быть сделано атомарно любым другим способом.Во-вторых, на мой взгляд, производительность = 1 / ((блокирует) ^ 5).Т.е. блокировки быстро становятся источником проблем с производительностью в многопоточных приложениях, поэтому избегайте их.В-третьих ... атомная операция будет хорошо играть с OpenMP.Используйте __ sync_add_and_fetch или аналогичную атомарную операцию для изменения счетчика.Он реализован аппаратно на чипе, поэтому он примерно в 2 раза медленнее, чем ++ или -, по сравнению примерно в 40 раз медленнее при использовании мьютексов.

1 голос
/ 14 апреля 2011

В зависимости от реализации OpenMP базовый код вполне может использовать pthreads. Тем не менее, спецификация OpenMP ничего не говорит о том, будут ли разные модели потоков "хорошо играть вместе". Это может работать, а может и не работать, в зависимости от того, выполнила ли используемая вами реализация работу, позволяющую это сделать. К сожалению, все, что я могу сказать, это проверить документацию на продукт, который вы используете, и посмотреть, говорит ли он что-нибудь. Я считаю, что большинство реализаций пытались позволить этому работать.

...