Есть ли в WinAPI, POSIX или в других расширениях эквиваленты API-OS для все уровни барьеров памяти из C ++ 11 станд :: memory_order, которые определяют пределы оптимизации при переупорядочении операций компилятором и конвейером процессора?
enum memory_order {
memory_order_relaxed,
memory_order_consume,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst
};
Сложение: Пример в WinAPI присутствует MemoryBarrier (), но это только эквиваленты std::atomic_thread_fence( std::memory_order_seq_cst );
, Поскольку Windows в основном работает на x86-системах, где обычные загрузки получают семантику, а простые хранилища имеют семантику выпуска: http://www.stdthread.co.uk/forum/index.php?topic=72.0
Но даже если кэш L3 (LLC) и конвейер x86 отменяют оптимизацию переупорядочения для load()
а также store()
в соответствии с этой семантикой — std::memory_order_acquire/std::memory_order_release
Также необходимо отключить оптимизацию компилятора.
Присутствует в WinAPI:
_ReadBarrier, _WriteBarrier и _ReadWriteBarrier компилятор
встроенные функции предотвращают только переупорядочение компилятора. Чтобы процессор не
переупорядочивая операции чтения и записи, используйте макрос MemoryBarrier.
Есть в GCC встроенный функции для модели памяти с учетом атомарных операций:
__ATOMIC_RELAXED Нет барьеров или синхронизации.
__ATOMIC_CONSUME Зависимость данных только для барьера и синхронизации с другим потоком.
__ATOMIC_ACQUIRE Барьер для подъема кода и синхронизации с освобождением (или более сильными) семантических хранилищ из другого потока.
__ATOMIC_RELEASE Барьер для утечки кода и синхронизации с приобретением (или усилением) семантических нагрузок из другого потока.
__ATOMIC_ACQ_REL Полный барьер в обоих направлениях и синхронизируется с загрузкой загрузки и освобождением магазинов в другом потоке.
__ATOMIC_SEQ_CST Полный барьер в обоих направлениях и синхронизируется с загрузкой загрузки и освобождением магазинов во всех потоках.
И могу ли я отключить этот компилятор оптимизации с помощью POSIX?
Обычно не является частью стандартов API, но доступно в виде встроенных компонентов в большинстве компиляторов в той или иной форме.
Например, компиляторы Visual Studio имеют _ReadBarrier
, _ReadWriteBarrier
а также _WriteBarrier
, (Я связал только один, так как есть ссылки с этой страницы на остальные. И нет, это не все уровни, которые вы перечислили — но это все уровни, которые есть у x86 … Список в std::memory_order
охватывает множество других архитектур тоже. [И явно memory_order_relaxed
это «ничто»].
В GCC описан другой тип встроенной функциональности Вот, которая направлена на обеспечение атомарных обновлений, а не конкретно барьеров.
Тем не менее, в общем, я бы оставил это компилятору / ОС иметь дело с атомарными вещами — используйте std::atomic<>
и тому подобное.
Почти наверняка нет. Целью стандарта было охватить все
случайностей; Вы указываете необходимый минимум, а
компилятор обеспечивает минимум в своей среде, который отвечает
требования.
Что касается оптимизации компилятора: я полагаю, что компилятор мог
оценить эти аргументы для атомарных функций, и сделать
оптимизация зависит от него, но я скорее подозреваю, что большинство
компиляторы будут использовать гораздо более простое правило: не переупорядочивать память
доступы (на уровне компилятора) через доступы к атомарному
тип.
И я не уверен, какие оптимизации компилятора вы хотите
отключить. Если компилятор совместим с Posix, он отключит
все переупорядочение доступа к памяти через любой из
pthread_...
функции; и, вероятно, по всей системе
функции. (Представьте, если он переупорядочил запись в буфер
после звонка write
или чтение из буфера перед
позвонить read
.)