Является ли `__asm nop` Windows эквивалентом`asm volatile("nop");`от компилятора GCC
В винде можно __asm nop
поменяться местами asm volatile("nop");
(используется в компиляторе GCC) и дать тот же результат?
Я прочитал это volatile()
(в GCC) гарантирует, что вызов не будет оптимизирован. Тем не менее, он не портируется напрямую в Windows, и мне было любопытно, можно ли его просто удалить или его нужно заменить аналогичной конструкцией.
2 ответа
__asm
Реализация ключевых слов довольно проста в MSVC. Он всегда выдает машинный код без изменений, а оптимизатор его не трогает. Он также не делает никаких предположений о состоянии машины после __asm, который обладает способностью побеждать другие оптимизации.
Так что нет, ничего похожего на volatile()
требуется, оно не может исчезнуть. гладкий __asm { nop }
всегда выживет невредимым и эквивалентно сборке GCC.
Имейте в виду, что встроенная сборка не является хорошей долгосрочной стратегией, ее поддержка полностью удалена в компиляторе x64 и вряд ли когда-либо вернется. Вам придется обратиться к внутренним кодам или ссылочному коду, написанному на ассемблере и скомпилированным, скажем, с ml64.exe. Это препятствует внедрению NOP, но оптимизатор уже хорошо позаботился о выравнивании кода и не нуждается в помощи. Также причина, по которой вы, вероятно, не должны делать это вообще.
Прямой эквивалент в Visual Studio - встроенная функция _ReadWriteBarrier.
я полагаю, что __asm nop
будет иметь тот же эффект при компиляции для x86, но встроенный ассемблер не поддерживается на x64 или ARM. (Тем не менее, код может делать другие предположения, которые являются недопустимыми на платформах, отличных от x86, поэтому это может не быть проблемой.)
Обратите также внимание на макрос MemoryBarrier, который не позволяет ЦП (в отличие от компилятора) переупорядочивать операции чтения и записи.
Для компилятора Microsoft используйте __nop()
встроенная функция для выдачи инструкции nop без помех оптимизатору компилятора. Это также будет кросс-платформенным для всех целей Windows (32-битная ARM V7, 64-битная ARM V8, IA32, X64).