Правильное использование «атомарной директивы» для блокировки контейнера STL - PullRequest
0 голосов
/ 22 апреля 2010

У меня есть большое количество наборов целых чисел, которые я, в свою очередь, вставил в вектор указателей. Мне нужно иметь возможность обновлять эти наборы целых чисел параллельно, не вызывая условия гонки. Более конкретно. Я использую конструкцию OpenMP "Параллельно для".

Для работы с общими ресурсами OpenMP предлагает удобную «атомарную директиву», которая позволяет избежать состояния гонки на определенном фрагменте памяти без использования блокировок. Было бы удобно, если бы я мог использовать «атомарную директиву» для предотвращения одновременного обновления моих целочисленных наборов, однако я не уверен, возможно ли это.

По сути, я хочу знать, может ли следующий код привести к состоянию гонки

vector< set<int>* > membershipDirectory(numSets, new set<int>);

#pragma omp for schedule(guided,expandChunksize)
for(int i=0; i<100; i++)
  {
    set<int>* sp = membershipDirectory[rand()];
    #pragma omp atomic
      sp->insert(45);
  }

Обратите внимание, что я использую случайное целое число для индекса, потому что в моем приложении любой поток может обращаться к любому индексу (в моем более крупном приложении есть случайный элемент, но мне не нужно вдаваться в подробности).

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

Ответы [ 3 ]

2 голосов
/ 22 апреля 2010

После поиска я нашел руководство по OpenMP C и C ++ API на openmp.org, а в разделе 2.6.4 описаны ограничения атомарной конструкции.

По сути, атомарная директива может использоваться только со следующими операторами:

Унарное: ++, - (префикс и постфикс)

Binary: +, -, *, /, ^, &, |, <<, >>

Так что я буду использовать только замки!

(В некоторых ситуациях критические разделы могут быть предпочтительнее, но в моем случае блокировки обеспечат детальный доступ к общему ресурсу, обеспечивая более высокую производительность, чем критический раздел.)

1 голос
/ 25 апреля 2010

Вы не должны использовать атомарный, где выражение является вызовом функции, это относится только к простым выражениям (возможно, со встроенными модулями: power, квадратный корень).

Вместо этого используйте критическую секцию (именованную или по умолчанию)

0 голосов
/ 22 апреля 2010

Ваш код не понятен. Предполагая, что membersDirectory [5] на самом деле является membersDirectory [i], атомарная директива не нужна. Например, для двух процессоров OpenMP создает два потока, один обрабатывает i = 0-49, другой - 50-99 интервалов. В этом случае нет необходимости защищать membersDirectory [i]. Директива atomic необходима для защиты некоторого общего ресурса, который не зависит от индекса цикла, например, общей суммы.

...