Как вы используете инструкцию по сборке пауз в 64-разрядном коде на С++?

Поскольку встроенная сборка не поддерживается VС++ 2010 в 64-разрядном коде, как мне получить инструкцию pause x86-64 в мой код? Для этого, похоже, не характерно, как для многих других общих инструкций сборки (например, __rdtsc(), __cpuid() и т.д.).

С другой стороны, я хочу, чтобы инструкция помогала с занятым случаем ожидания ожидания, так что (гиперпотоковый) процессор доступен для других потоков, работающих на указанном CPU (см. Performance Insights на intel.com). Инструкция pause очень полезна для этого варианта использования, а также для реализаций спин-блокировки, я не могу понять, почему MS не включила его как внутреннюю.

Спасибо

Ответ 1

Вау, это была очень сложная задача для отслеживания, но в случае, если кому-то еще нужна инструкция x86-64 pause:

Макрос YieldProcessor() от windows.h расширяется до недокументированного _mm_pause внутреннего, который в конечном счете расширяется до инструкции pause в 32-битном и 64-битном коде.

Это совершенно недокументировано, кстати, с частичной (и некорректной для документации VС++ 2010) для YieldProcessor(), отображаемой в MSDN.

Вот пример того, как скомпилируется макрос YieldProcessor():

    19:     ::YieldProcessor();
000000013FDB18A0 F3 90                pause  
    20:     ::YieldProcessor();
000000013FDB18A2 F3 90                pause  
    21:     ::YieldProcessor();
000000013FDB18A4 F3 90                pause  
    22:     ::YieldProcessor();
000000013FDB18A6 F3 90                pause  
    23:     ::YieldProcessor();
000000013FDB18A8 F3 90                pause  

Кстати, каждая инструкция паузы, по-видимому, производит около 9-ти циклов задержки на архитектуре Nehalem в среднем (т.е. 3 нс на CPU с частотой 3,3 ГГц).