簡體   English   中英

為什么<慢於<=? [C]

[英]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

差別很小,但是無論我運行二進制文件多少次,我都無法消除它或反轉它。

  • 我在lt.c的for循環中使比較值比le.c大一圈(因此它們都循環了相同的次數)。 這是一個錯誤嗎?
  • 根據<是比<=快嗎? <編譯為jge<=編譯為jg 那是在處理if語句而不是for循環,但這是否仍是原因? jge的執行時間可能比jg時間長一點嗎? (我認為這是具有諷刺意味的,因為這意味着從C轉換為ASM會反轉這是更復雜的指令,C中的lt轉換為ASM中的gte,而lte轉換為gt。
  • 或者,這是否僅僅是硬件專用的,以致於不同的x86系列產品或單個芯片可能始終顯示出相反的趨勢,相同的趨勢或沒有差異?

在對我的問題的評論中有一些請求,要求包括GCC為我生成的程序集。 在進入編譯器彈出每個文件的程序集版本之后,我檢查了一下。

結果:
事實證明,默認優化設置將兩個for循環都轉換為同一程序集。 實際上,兩個文件在組裝形式上都是相同的。 diff確認了這一點。)

先前觀察到的時差的可能原因:
看來我運行二進制文件的順序是造成運行時間差異的原因。

  • 在給定的運行時間中,程序通常在每次連續執行時都更快地執行,大約執行3次后才達到穩定。
  • 我在time ./lttime ./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

* *遮住臉* ...繼續...

讓我們在組裝中講話。 (當然取決於架構)比較時,您將使用cmp或測試指令,然后-當您使用<時,等於指令將是jl,它檢查SF和OF是否不相同(一些特殊的標志,稱為符號和溢出) -當您使用<=時,相等指令是jle,它不僅檢查SF!= OF,而且檢查ZF == 1(零標志)等等, 這里更多但老實說,它甚至不是整個循環,所以...在正常情況下差異是無法測量的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM