Visual c++ 如何在64位C++;密码?

Visual c++ 如何在64位C++;密码?,visual-c++,visual-c++-2010,Visual C++,Visual C++ 2010,由于64位代码中的VC++2010不支持内联汇编,如何在代码中获得pausex86-64指令?与许多其他常见的汇编指令(例如,\uuu rdtsc(),\uuu cpuid(),等等)相比,这似乎没有内在的含义 在为什么方面,我希望该指令有助于处理繁忙等待用例,以便(超线程)CPU可供在该CPU上运行的其他线程使用(请参阅:在intel.com上)。pause指令对这个用例以及自旋锁实现非常有帮助,我不明白为什么MS没有将它作为一个内在函数 谢谢哇,这是一个很难找到的问题,但是如果其他人需要x8

由于64位代码中的VC++2010不支持内联汇编,如何在代码中获得
pause
x86-64指令?与许多其他常见的汇编指令(例如,
\uuu rdtsc()
\uuu cpuid()
,等等)相比,这似乎没有内在的含义

在为什么方面,我希望该指令有助于处理繁忙等待用例,以便(超线程)CPU可供在该CPU上运行的其他线程使用(请参阅:在intel.com上)。
pause
指令对这个用例以及自旋锁实现非常有帮助,我不明白为什么MS没有将它作为一个内在函数


谢谢

哇,这是一个很难找到的问题,但是如果其他人需要x86-64
暂停
指令:

windows.h
中的
YieldProcessor()
宏扩展到未记录的
\u mm\u pause
内部,最终扩展到32位和64位代码中的
pause
指令

顺便说一句,这完全没有文档记录,在MSDN中出现了部分内容(对于VC++2010文档来说是不正确的)

下面是一个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编译器都支持该指令,并可跨操作系统移植。IDK如果MS的文档在过去缺少,或者如果您只是错过了它~7年

#包括
并使用它。(或对于古代编译器
#包括SSE2的

在没有SSE2的CPU上,它解码为
rep nop
,这只是一个
nop

Gcc甚至知道这一点,并且在使用
-mno-sse
编译时仍然接受
\u mm\u pause()
。(与MSVC不同,对于未启用的指令,gcc和clang通常拒绝intrinics。)有趣的是,gcc甚至在其asm输出中发出
rep nop
,而其他三个发出
pause
。当然,它们组装成相同的机器代码


暂停使Sandybridge系列的超线程前端闲置约5个周期,直到Skylake。在Skylake上,Intel将其增加到约100个周期,以在自旋等待循环中节省更多的能量,并以延迟为代价提高总体吞吐量,特别是在超线程内核上

在所有CPU上,它还避免了离开自旋循环时内存顺序的错误推测。因此,当它最终再次重要时,它确实减少了延迟


另请参见。

不幸的是,MS“忘记”记录了许多函数,这非常烦人(特别是当记录了
\u yield
时)。有时,只需对intrin.h进行梳理,寻找与您所使用的名称相似的名称(这就是我发现的
\u mm\u pause
,尽管您的宏在可移植性方面似乎要好得多,+1)\u可能会有文档记录,但它只适用于IA64(即,不是人们实际使用的任何体系结构:)。事实上,当我发现它时,我非常高兴,但却发现它适用于x86/x86-64版本。
#include <immintrin.h>

void test() {
    _mm_pause();
    _mm_pause();
}
test():                               # @test()
    pause
    pause
    ret