[英]Why would < be slower than <=? [C]
自然地,我假設<和<=運算符以相同的速度運行( 根據Jonathon Reinhart的邏輯,在此處 )。 最近,我決定測試該假設,結果令我有些驚訝。
我知道,對於大多數現代硬件而言,這個問題純粹是學術性的,因此必須編寫循環大約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;
}
使用帶有-std = c11標志的GCC,可以編譯它們並在Linux VirtualBox 3.19.0-18-通用#18-Ubuntu x86_64安裝上運行。
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循環,但這是否仍是原因? jge
的執行時間可能比jg
時間長一點嗎? (我認為這是具有諷刺意味的,因為這意味着從C轉換為ASM會反轉這是更復雜的指令,C中的lt轉換為ASM中的gte,而lte轉換為gt。 在對我的問題的評論中有一些請求,要求包括GCC為我生成的程序集。 在進入編譯器彈出每個文件的程序集版本之后,我檢查了一下。
結果:
事實證明,默認優化設置將兩個for循環都轉換為同一程序集。 實際上,兩個文件在組裝形式上都是相同的。 ( diff
確認了這一點。)
先前觀察到的時差的可能原因:
看來我運行二進制文件的順序是造成運行時間差異的原因。
time ./lt
和time ./le
之間來回time ./le
,因此第一次跑步會偏向平均時間。 代碼摘錄:
movl $0, -4(%rbp)
jmp .L2
.L3:
addl $1, -4($rbp)
.L2
cmpl $1000000000, -4(%rbp)
jle .L3
mol $0, %eax
pop %rbp
* *遮住臉* ...繼續...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.