由于VC ++ 2010在64位代码中不支持内联汇编,因此如何获取 pause
x86-64指令进入我的代码?似乎没有像这样的固有的许多其他常见的汇编指令(例如, __rdtsc()
, __cpuid()
等等......)
在为什么这一方面,我希望指令帮助忙碌的等待用例,以便(超线程)CPU可用于在所述CPU上运行的其他线程(参见: 绩效见解 在intel.com)。该 pause
指令对于这个用例以及自旋锁实现非常有用,我无法理解为什么MS没有将它作为内在包含。
谢谢
由于VC ++ 2010在64位代码中不支持内联汇编,因此如何获取 pause
x86-64指令进入我的代码?似乎没有像这样的固有的许多其他常见的汇编指令(例如, __rdtsc()
, __cpuid()
等等......)
在为什么这一方面,我希望指令帮助忙碌的等待用例,以便(超线程)CPU可用于在所述CPU上运行的其他线程(参见: 绩效见解 在intel.com)。该 pause
指令对于这个用例以及自旋锁实现非常有用,我无法理解为什么MS没有将它作为内在包含。
谢谢
哇,这是一个非常难以追查的问题,但万一其他人需要x86-64 pause
指令:
该 YieldProcessor()
来自的宏 windows.h
扩展到无证件 _mm_pause
内在的,最终扩展到 pause
32位和64位代码指令。
顺便说一句,这完全没有记录,部分(和VC ++ 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
顺便说一句,每个暂停指令似乎平均在Nehalem架构上产生大约9个周期的延迟(即3.3 GHz CPU上的3 ns)。
哇,这是一个非常难以追查的问题,但万一其他人需要x86-64 pause
指令:
该 YieldProcessor()
来自的宏 windows.h
扩展到无证件 _mm_pause
内在的,最终扩展到 pause
32位和64位代码指令。
顺便说一句,这完全没有记录,部分(和VC ++ 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
顺便说一句,每个暂停指令似乎平均在Nehalem架构上产生大约9个周期的延迟(即3.3 GHz CPU上的3 ns)。
该 _mm_pause()
英特尔完全记录了内在因素 并且所有主要的x86编译器都支持可移植的操作系统。 IDK,如果过去缺乏MS的文档,或者你错过了它〜7年了。
#include <immintrin.h>
并使用它。 (或者对于古代编译器 #include <emmintrin.h>
对于SSE2)。
#include <immintrin.h>
void test() {
_mm_pause();
_mm_pause();
}
在所有4个gcc / clang / ICC / MSVC上编译为asm(在Godbolt编译器资源管理器上):
test(): # @test()
pause
pause
ret
在没有SSE2的CPU上,它解码为 rep nop
这只是一个 nop
。 跨平台实现x86暂停指令
Gcc甚至知道这一点,仍然接受 _mm_pause()
编译时 -mno-sse
。 (正常情况下,gcc和clang拒绝使用未启用指令的内容,与MSVC不同。)有趣的是,gcc甚至会发出 rep nop
在其asm输出中,而其他三个发出 pause
。当然,它们组装成相同的机器代码。
在Sandybridge家族停留超过5个周期之前暂停闲置,直到Skylake。在Skylake上,英特尔将其增加到约100个周期,以便在自旋等待循环中节省更多功率。
也可以看看 x86中“PAUSE”指令的目的是什么?。