В чем разница между атомарным и критическим в openMP? Я могу это сделать
#pragma omp atomic
g_qCount++;
но это не так, как
#pragma omp critical
g_qCount++;
В чем разница между атомарным и критическим в openMP? Я могу это сделать
#pragma omp atomic
g_qCount++;
но это не так, как
#pragma omp critical
g_qCount++;
Эффект на g_qCount тот же, но то, что сделано, отличается.
Критический раздел OpenMP полностью общий - он может окружать любой произвольный блок кода. Тем не менее, вы платите за эту общность, накладывая значительные накладные расходы каждый раз, когда поток входит и выходит из критического раздела (помимо стоимости, связанной с сериализацией).
(Кроме того, в OpenMP все неназванные критические разделы считаются идентичными (если вы предпочитаете, есть только одна блокировка для всех неназванных критических разделов), так что, если один поток находится в одном [неназванном] критическом разделе, как указано выше, ни один поток может войти в любой [неназванный] критический раздел. Как вы могли догадаться, вы можете обойти это, используя именованные критические разделы).
Атомная операция имеет намного меньшие накладные расходы. Там, где это возможно, он использует преимущества аппаратного обеспечения (скажем) атомной операции увеличения; в этом случае нет необходимости блокировки/разблокировки при вводе/выходе из строки кода, это просто инстанция атома, о которой аппаратное обеспечение говорит вам, не может быть помечено.
Верхние стороны - это то, что накладные расходы намного ниже, и один поток, находящийся в атомной операции, не блокирует любые (разные) атомные операции, которые должны произойти. Недостатком является ограниченный набор операций, поддерживаемых атомами.
Конечно, в любом случае вы несете себестоимость себестоимости.
Предыдущий ответ велик, если не считать маленького мысли, что в OpenMP все неназванные критические разделы являются взаимоисключающими. И самое важное различие между критическим и атомарным состоит в том, что атомный может защитить только одно назначение, и вы можете использовать его с конкретными операторами.
Критический раздел:
Может быть расширен до сериализации групп блоков с правильным использованием тега "name".
Медленнее!
Атомная операция:
Быстрее!
Обеспечивает сериализацию конкретной операции.
Самый быстрый путь не является ни критическим, ни атомным. Примерно, добавление с критической секцией в 200 раз дороже простого добавления, добавление атомов в 25 раз дороже, чем простое добавление.
Самая быстрая опция (не всегда применимая) заключается в том, чтобы дать каждому потоку собственный счетчик и уменьшить операцию, когда вам нужна общая сумма.
Важны ограничения atomic
. Они должны быть подробно описаны в спецификациях OpenMP. MSDN предлагает быстрый лист читов, так как я не удивлюсь, если это не изменится. (Visual Studio 2012 имеет реализацию OpenMP с марта 2002 года.) Чтобы процитировать MSDN:
Оператор выражения должен иметь одну из следующих форм:
x
= бинарный операторexpr
x++
++x
x--
--x
В предыдущих выражениях:
x
- выражениеlvalue
со скалярным типом.expr
- это выражение со скалярным типом, и оно не ссылается на объект, обозначенный символомx
. binop не является перегруженным оператором и является одним из+
,*
,-
,/
,&
,^
,|
,<<
или>>
.
Я рекомендую использовать atomic
, когда вы можете именовать критические разделы иначе. Именование их важно; вы избегаете отлаживать головные боли таким образом.
atomic относительно эффективен с точки зрения эффективности, когда вам нужно включить взаимное исключение только для одной команды, аналогичной, не относится к критике omp.
atomic - это один оператор Критический раздел, т.е. вы блокируете выполнение одного оператора
критический раздел - это блокировка блока кода
Хороший компилятор переведет ваш второй код так же, как и первый