intel x86-64中的哪种模式执行指令的速度更快

时间:2018-01-11 04:14:43

标签: performance x86 x86-64 intel isa

英特尔 - 真实模式 - 保护模式 - 虚拟实模式 - 64位模式

在这些模式中,哪一个更快地执行相同的指令集?

使用前缀可以改变地址&大小可以与其他模式类似。

1 个答案:

答案 0 :(得分:0)

TL:DR:告诉编译器制作64位可执行文件,以便在大多数情况下获得最佳性能。

英特尔(和AMD)的CPU没有任何固有的惩罚措施,使得解码或执行在任何模式下效率都会降低。

但是操作数大小的一些选择比其他选择更糟糕(例如因为partial-register false dependencies or stalls而导致16位糟糕),而16位代码需要使用前缀来使用32位操作数大小和地址大小。英特尔CPU在解码大量前缀时没有问题,但通常较大的代码大小是一件坏事,会降低L1I缓存中的代码密度,有时还会降低uop缓存中的代码密度。

64位代码具有更大的指令(因为64位操作数大小需要REX前缀)。通常这并不重要,因为uop缓存和L1I缓存通常完全隐藏代码大小对性能的影响。对于大多数指令,32位和64位操作数大小都是相同的速度,64位代码仍然可以使用32位操作数大小,除非它确实需要宽类型,以避免64位整数除法的额外成本(和REX前缀)。

  

场景是,我想写一个通用程序。我想知道哪种模式更快,为什么?

这是一个与你提出的问题不同的问题。

长模式通常是最快的,因为它通常需要较少的指令来完成相同的工作,因为更好的调用约定和更多的寄存器(更少的溢出)。特别是如果你有任何FP计算或SIMD友好循环,64位模式可能是一个很大的胜利,因为FP代码通常可以利用更多的寄存器。

但64位代码中指针繁重的数据结构的缓存占用量是32位代码的两倍(可以在protected / compat模式下运行)。此外,具有64位对齐要求可能会导致更多的结构填充,因此指针+ int结构将在64位代码中为16字节而不是12字节。

因此,您可以在64位代码中获得更多缓存未命中,这可能使其比32位慢。 Linux's x32 ABI试图充分利用两个世界(对于不需要大量虚拟地址空间的代码):长模式下的32位指针。

如果所有"指针"只是存储32位数组索引而不是指针可以工作。进入您分配的同一个池中。但beware that it can result in worse load/use latency因为您(或编译器)需要索引寻址模式或单独的添加指令。