Optimization 为什么INC和ADD 1具有不同的性能?

Optimization 为什么INC和ADD 1具有不同的性能?,optimization,assembly,x86,hardware,cpu-architecture,Optimization,Assembly,X86,Hardware,Cpu Architecture,这些年来我读过很多次,你应该使用XOR ax,ax,因为它更快。。。或者在用C编程时使用计数器++或计数器+=1,因为它们会INC或ADD。。。或者在Netburst奔腾4中,INC比ADD 1慢,因此必须警告编译器您的目标是Netburst,以便它将所有var++转换为ADD 1 我的问题是:为什么INC和ADD有不同的性能?例如,为什么有人声称INC在Netburst上运行得较慢,而在其他处理器上运行得更快?XOR ax,ax位是,我收集的数据已经过时几年了,现在赋值为零比它要好(我被告知)

这些年来我读过很多次,你应该使用XOR ax,ax,因为它更快。。。或者在用C编程时使用计数器++或计数器+=1,因为它们会INC或ADD。。。或者在Netburst奔腾4中,INC比ADD 1慢,因此必须警告编译器您的目标是Netburst,以便它将所有var++转换为ADD 1


我的问题是:为什么INC和ADD有不同的性能?例如,为什么有人声称INC在Netburst上运行得较慢,而在其他处理器上运行得更快?

XOR ax,ax位是,我收集的数据已经过时几年了,现在赋值为零比它要好(我被告知)

关于
计数器+++
而不是
计数器+=1
的C位已经过时几十年了。当然

第一个使用汇编的原因很简单,因为所有指令都将被转换为CPU部分的某种操作,尽管设计者总是试图使一切尽可能快,但他们使用某些指令会比使用其他指令做得更好。不难想象一家公司怎么会更快,因为它只需要处理一个寄存器,尽管这太过简化了(但我对这些事情不太了解,所以我只能在这方面做得太过简化)


然而,C字在很久以前是毫无意义的。如果我们有一个特定的CPU,其中INC优于ADD,那么对于
计数器+++
计数器+=1
,编译器设计者究竟为什么不使用INC而不是ADD呢?编译器进行了大量优化,而这类更改远不是最复杂的。

对于x86体系结构,INC更新条件代码的子集,而ADD则更新整个条件代码集。(其他体系结构有不同的规则,因此本讨论可能适用,也可能不适用)

因此,INC指令必须等待更新条件代码位的其他先前指令完成,然后才能修改先前的值以生成最终的条件代码结果

ADD可以生成最终的条件码位,而不考虑条件码的先前值,所以它不需要等待先前的指令完成条件码值的计算

结果:您可以与许多其他指令并行执行ADD,而与较少的其他指令并行执行INC。因此,ADD在实践中似乎更快

(我认为在全宽寄存器(例如EAX)的上下文中使用8位寄存器(例如AL)也存在类似的问题,因为AL更新要求之前的EAX更新首先完成)


我不再在高性能汇编代码中使用INC或DEC。如果您对执行时间不太敏感,那么INC或DEC就可以了,可以减少指令流的大小。

我认为这个问题只与x86体系结构有关。我不知道有哪种微体系结构的
INC
本身速度更快。我能看到它唯一的优点就是尺寸更小。顺便说一句,
x++
x+=1
不一定分别转换为
inc
add
,除非是在ultra-lame编译器中。在x86体系结构中,使用变长指令编码时,可能存在两种情况:一种优于另一种。如果较短的on适合缓存线或解码块,而较大的on则不适合,那么它将出现在前面。如果较短的一个将下一条指令的一半留在窗口中,剩下的一半在下一个窗口中,那么较大的一条可能会更好地对齐其后续指令。@Lưu Vĩnh Phúc看看问题日期,我的问题比你链接的问题要老,它不可能是重复的(除非你相信我可以穿越时间)@speeder,时间在这里无关紧要。2010年的大量问题被2016年的更好的问题解决了。
xor
现在的技巧更棒了。在SandyBridge上,它由寄存器重命名器处理——它甚至不再进入任何执行单元。@harold sweet。另一个让我感到高兴的原因是,我从编译器中获益,人们对这方面的了解比我以往任何时候都要多;)@harold Sandy Bridge甚至为
子X、X提供了特殊情况。不知道为什么需要这样做,因为所有正常的编译器都已经使用了xor X,X
。@Mysticial这肯定有点倒退了?如果他们只关注当前使用的编译器,那么最新技术的发展将受到阻碍,不是吗?@Mystical,理智的编译器做什么并不特别重要,英特尔花了很多时间试图让20年前用蹩脚的编译器编译的fortran/cobol/汇编代码运行得更快。在许多情况下,源代码找不到,或者生成可执行文件的工具链不再存在。这听起来很有趣。您是否知道EFLAGS问题会导致INC的微体系结构延迟,或者这是一种猜测?我想知道是否有一些推测性的方法来处理EFLAG,以消除INC/DEC的大多数延迟。srking许多micro Arch将EFLAG拆分为单独的部分,以避免这种错误的依赖性。当部件必须重新组合时,仍然会发生暂停(例如将进位标志与其他标志一起使用的跳转)。我不知道处理器有多聪明,但那些工程师有很多晶体管可玩。一个有趣的观察结果:如果INC指令后面跟着ADD,INC的条件代码就不再有趣了,从技术上讲,INC不需要依赖以前的CC值。因此,在INC之后,某个东西会重击整个CC位集,这可能会加快它的速度:-}将优化代码放在计算之后非常奇怪!我很确定部分eflags暂停在《英特尔优化指南》中有记录。或者可能在Agner Fog的白皮书中。AL/AX/EAX分区寄存器问题是原因