当然,我已经假设<和< =运算符以相同的速度运行(per Jonathon Reinhart's logic, here)。最近,我决定测试这个假设,我对结果感到有些惊讶。
我知道,对于大多数现代硬件而言,这个问题纯粹是学术性的,因此不得不编写循环大约10亿次的测试程序(以获得任何微小的差异以加起来更可接受的水平)。这些计划尽可能基本(删除所有可能的干扰源)。
lt.c:
int main() {
for (int i = 0; i < 1000000001; i++);
return 0;
}
le.c:
int main() {
for (int i = 0; i <= 1000000000; i++);
return 0;
}
它们是在 Linux VirtualBox 3.19.0-18-generic#18-Ubuntu x86_64 安装上编译和运行的,使用GCC并设置了 -std = c11 标志
lt.c二进制文件的平均时间是:
real 0m2.404s
user 0m2.389s
sys 0m0.000s
le.c的平均时间是:
real 0m2.397s
user 0m2.384s
sys 0m0.000s
差别很小,但无论我运行二进制文件多少次,我都无法让它消失或反转。
<
汇编为jge
,<=
汇编为jg
。那是在处理if语句而不是for-loop,但这仍然是原因吗? jge
的执行是否需要稍长于jg
? (我认为这很具有讽刺意味,因为这意味着从C转移到ASM反转,哪一个是更复杂的指令,其中C在ASM中转换为gte并且转换为gt。) 答案 0 :(得分:0)
让我们在集会上发言。 (当然取决于架构) 比较时,您将使用cmp或test指令 - 当你使用&lt;等号指令将是jl,它检查SF和OF是否不相同(一些特殊标志称为sign和overflow) - 当你使用&lt; =相等的指令是jle时,它不仅检查SF!= OF而且还检查ZF == 1(零标志) 所以一个,更多here 但说实话,它甚至不是整个周期......我认为在正常情况下这种差异是不可测量的