С++ 0x draft имеет представление о заборе, которое кажется очень отличным от уровня заграждений уровня CPU/чипа, или сказать, что ожидают ядро Linux-ядра из заборов. Вопрос заключается в том, действительно ли проект подразумевает чрезвычайно ограниченную модель, или формулировка просто плохая, и на самом деле она подразумевает истинные заборы.
Например, в разделе 29.8 "Заборы" указываются такие вещи, как:
Заблокировочный затвор A синхронизируется с приобретать забор B, если существуют атомные операции X и Y, работающие на некоторый атомный объект M, такой, что A является последовательность до X, X модификаций M, Y - секвенированы до B, а Y - значение, написанное X, или значение, записанное любой стороной в гипотетическом освобождение последовательности X будет голова, если она были операцией выпуска.
Он использует эти термины atomic operations
и atomic object
. В проекте есть такие атомные операции и методы, но означает ли это только те, что? Заборный забор звучит как забор магазина. Забор магазина, который не гарантирует запись всех данных перед забором, почти бесполезен. Аналогично для нагрузки (приобретать) забор и полный забор.
Итак, являются ли заграждения/барри в правильных заборах С++ 0x, а формулировка просто невероятно плоха или они чрезвычайно ограничены/бесполезны, как описано?
В терминах С++, скажем, у меня есть этот существующий код (предполагая, что забор доступен как конструкции высокого уровня прямо сейчас - вместо того, чтобы использовать __sync_synchronize в GCC):
Thread A:
b = 9;
store_fence();
a = 5;
Thread B:
if( a == 5 )
{
load_fence();
c = b;
}
Предположим, что a, b, c имеют размер, имеющий атомную копию на платформе. Вышеизложенное означает, что c
будет присваиваться только 9
. Обратите внимание, что нам не важно, когда Thread B видит a==5
, только когда он делает это, также видит b==9
.
Что такое код в С++ 0x, который гарантирует одинаковые отношения?
ANSWER. Если вы прочтете мой выбранный ответ и все комментарии, вы получите суть ситуации. С++ 0x, похоже, заставляет вас использовать атом с ограждениями, тогда как обычный аппаратный забор не имеет этого требования. Во многих случаях это все равно можно использовать для замены одновременных алгоритмов, пока sizeof(atomic<T>) == sizeof(T)
и atomic<T>.is_lock_free() == true
.
Однако, к сожалению, is_lock_free
не является constexpr. Это позволило бы использовать его в static_assert
. Наличие atomic<T>
вырожденного использования блокировок, как правило, является плохой идеей: атомные алгоритмы, которые используют мьютексы, будут иметь ужасные проблемы конфликтов по сравнению с алгоритмом, разработанным мьютексом.