从英特尔手册中可以找到here,看起来ADD / SUB指令在一个特定架构上的周期便宜了半个周期 . 但请记住,英特尔为它使用了无序执行模型's (recent) processors. This primarily means, performance bottlenecks show up wherever the processor has to wait for data to come in (eg. it ran out of things to do during the L1/L2/L3/RAM data-fetch). So if you' re profiler告诉你INC可能是问题;从形成数据吞吐量的角度看它,而不是查看原始循环计数 .
Instruction Latency1 Throughput Execution Unit
2
CPUID 0F_3H 0F_2H 0F_3H 0F_2H 0F_2H
ADD/SUB 1 0.5 0.5 0.5 ALU
[...]
DEC/INC 1 1 0.5 0.5 ALU
4 回答
同一寄存器上的两条指令(或更一般地说,两条读 - 修改 - 写指令)总是具有至少两个周期的依赖链 . 这假设一个inc的一个时钟延迟,这是自486以来的情况 . 这意味着如果周围的指令不能与两个inc指令交错以隐藏那些延迟,则代码将执行得更慢 .
但是没有编译器会发出你提出的指令序列(
mov eax,0
将被xor eax,eax
替换,见What is the purpose of XORing a register with itself?)它会被优化
如果您想知道x86指令的原始性能统计数据,请参阅Dr Agner Fogs listings(准确地说是第4卷) . 关于编译器的部分,那依赖于编译器的代码生成器,而不是你应该依赖的东西 .
旁注:我觉得有趣/具有讽刺意味的是,在一个关于性能的问题中,你使用了
MOV EAX,0
将寄存器归零而不是XOR EAX,EAX
:P(并且如果MOV EAX,0
事先完成,最快的变体就是删除inc 's and add'和只是MOV EAX,2
) .出于所有目的,它可能无关紧要 . 但请注意 inc 使用较少的字节 .
请考虑以下代码:
在不使用任何优化标志的情况下, GCC 将此代码编译为:
使用
-O1
和-O2
,它变为:好笑,不是吗?
从英特尔手册中可以找到here,看起来ADD / SUB指令在一个特定架构上的周期便宜了半个周期 . 但请记住,英特尔为它使用了无序执行模型's (recent) processors. This primarily means, performance bottlenecks show up wherever the processor has to wait for data to come in (eg. it ran out of things to do during the L1/L2/L3/RAM data-fetch). So if you' re profiler告诉你INC可能是问题;从形成数据吞吐量的角度看它,而不是查看原始循环计数 .