2016-08-11 8 views
5

Из documentation:ли MS-специфические летучие предотвратить инструкции аппаратного переназначения

Microsoft Конкретные

Когда летучие /: мс параметр компилятора используется, по умолчанию при кроме ARM архитектур target - компилятор генерирует дополнительный код для поддержания порядка среди ссылок на изменчивые объекты в , а также на поддержание порядка ссылок на другие глобальные объекты . В частности:

  • Запись в изменчивый объект (также называемый volatile write) имеет семантику Release; то есть ссылка на глобальный или статический объект
    , который возникает до того, как запись в энергозависимый объект в инструкции
    будет происходить до того, как эта изменчивая запись будет записана в скомпилированном
    двоичном.
  • Чтение изменчивого объекта (также известного как изменчивое чтение) имеет семантику Acquire; то есть ссылка на глобальный или статический объект
    , который возникает после считывания энергозависимой памяти в инструкции
    Последовательность будет происходить после этого волатильного чтения в скомпилированном двоичном файле.

Это позволяет использовать изменчивые объекты для блокировки и освобождения памяти в многопоточных приложениях.

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

Но, как мы все знаем, есть такая вещь, как аппаратное переупорядочение (например, процессор может переупорядочить инструкции по своей воле). volatile предотвращает это? Я знаю, что примитивы синхронизации (такие как мьютексы) делают, но как насчет MS-specific volatile?

+1

«Архитектура, отличная от ARM», MS, вероятно, означает x86 и x64. На x86 и x64 нагрузки не переупорядочиваются с другими нагрузками. А магазины не заказываются в других магазинах. (за некоторыми исключениями, такими как невременные магазины) IOW, если компилятор ничего не переупорядочивает, и процессор не будет. Кажется, что '/ volatile' для MS пытается обеспечить функциональность' std :: atomic', которая не существовала до C++ 11. – Mysticial

+0

Кроме того, они говорят, что «имеет семантику выпуска», поэтому документация, безусловно, * утверждает, что '' volatile' предотвращает переупорядочение процессора. –

+0

@Mysticial «Кажется, что/volatile для MS пытается обеспечить функциональность std :: atomic» - нет, это не так. Например, не гарантируется, что операции чтения и записи переменных «volatile» являются атомарными. Фактически, они - потому что x86 гарантирует атомарность операций чтения и записи для 1-байтовых переменных, но это не гарантируется в MSDN 'volatile' – FrozenHeart

ответ

7

Документы MSDN о неустойчивом поведении, характерном для MS, полностью возвращаются к VS2003. Так что это было давно, задолго до существования std::atomic в C++ 11.

Таким образом, уязвимость, специфичная для MS, кажется, заключается в том, что в старые времена была достигнута семантика получения/выпуска. Но теперь это в основном устарело, и они оставили сноску, отталкивающую вас от MS-volatile в пользу std::atomic и /volatile:iso для межпоточной связи.

Что касается того, почему они исключают ARM, Microsoft не собирала ARM до относительно недавнего времени. Помимо ARM, они поддерживают x86, x64 и Itanium (который мертв).

На x86 и x64 большинство загрузок и хранилищ уже имеют семантику получения/выпуска (с исключениями, такими как невременные магазины). До тех пор, пока компилятор ничего не изменит, процессор не будет * и поэтому сохранит семантику получения/выпуска.Флаг /volatile:ms сообщает компилятору не изменять порядок, чтобы семантика получения/выпуска могла быть достигнута на x86 и x64.

Поскольку поддержка ARM Microsoft является относительно нового, и MS-специфического летучие (/volatile:ms) является устаревшим в пользу std::atomic, они, вероятно, решили отказаться от классической летучей семантики, а не обновлять их для работы на ARM, а также (что, вероятно, означает повсеместное добавление барьеров памяти, учитывая отсутствие аппаратной поддержки).

* Процессор по-прежнему будет выполнять любые изменения, которые он хочет, но он сохранит семантику получения/выпуска программы, так как это требуется для x86/x64. (минус исключительные случаи, такие как nt-магазины или clflush). Как это происходит без нарушения порядка памяти, это другая тема.