簡體   English   中英

哪個整數操作在Rust中具有更高性能的替代方法?

[英]Which integer operations have higher performance alternate methods in Rust?

在Rust中編寫將運行數百萬次的整數函數(想想像素處理)時,使用性能最高的操作很有用 - 類似於C / C ++。

雖然參考手冊解釋了行為的變化,但並不總是清楚哪種方法的性能高於標准(參見注釋1)整數算術運算。 我假設wrapping_add編譯成等同於C的加法。

在標准操作(加/減/乘/模/除/移位/位操作......)中,哪些操作具有更高性能的替代方法,默認情況下不使用?


注意:

  1. 標准,我指的是使用符號a + bi / kc % e等的整數運算。
    編寫數學表達式時要使用的內容 - 除非您特別需要使用包裝或返回溢出的方法之一。
  2. 我意識到回答這個問題可能需要一些研究。 因此,我很高興通過查看生成的程序集來進行一些檢查,以查看哪些操作正在使用未經檢查/原始操作。
  3. 可能是檢查/未檢查操作之間的速度差異不大,如果是這種情況,我仍然希望能夠編寫一個“快速”版本的函數來與“安全”版本進行比較,來關於它是否是給定函數的合理選擇我自己的結論。
  4. 提到像素處理后,SIMD已成為可能的解決方案。 盡管這是一個很好的建議。 這仍然留給我們使用SIMD 無法優化的情況,因此快速整數算法的一般情況仍然需要考慮。

在標准操作(加/減/乘/模/除/移位/位操作......)中,哪些操作具有更高性能的替代方法,默認情況下不使用?

請注意,Rust是為性能而設計的; 因此,在Debug中檢查整數操作時,它們被定義為包裝Release中,除非您特別指示編譯器。

因此,在具有默認選項的發布模式下,兩者之間嚴格沒有性能差異:

  • +wrapping_add
  • -wrapping_sub
  • *wrapping_mul
  • /wrapping_div
  • %wrapping_rem
  • <<wrapping_shl
  • >>wrapping_shr

對於無符號整數,性能因此嚴格地類似於C或C ++; 但是,對於有符號整數,優化器可能會產生不同的結果,因為有符號整數的下溢/溢出是C和C ++中的未定義行為(gcc和Clang接受-fwrapv標志,即使對於有符號整數也要求包裝,但它不是默認值)。

我希望使用checked_*overflow_*saturating_*方法通常會慢一些。


因此,有趣的切線是了解當您翻轉開關並明確要求檢查算術時會發生什么。

目前,Rust實現1是下溢/溢出檢查的精確實現。 每個加法,減法,乘法,...都是獨立檢查的,優化器不擅長融合這些分支。

具體來說, 精確的實現排除了臨時溢出: 5 + x - 5不能優化為x ,因為5 + x可能溢出。 它還排除了一般的自動矢量化。

只有當優化器可以證明沒有溢出(通常不能)時,您可能希望重新獲得更易於優化的無分支路徑。

應該注意的是,在通用軟件上,影響幾乎不可察覺,因為算術指令只占總成本的一小部分。 然而,當這個比例上升時,它可能非常明顯,實際上它出現在與Clang的SPEC2006基准測試的一部分中。

這種開銷足以被認為不適合默認激活檢查。

1 這是由於LLVM方面的技術限制; Rust實現只委托給LLVM。


將來,我們希望能夠獲得模糊的支票實施。 模糊實現背后的想法是,不是檢查每個操作,而是執行它們並且設置標志或者在下溢/溢出的情況下中斷值。 然后,在使用結果之前,執行檢查(分支)。

根據Joe Duffy的說法,他們在Midori中有這樣的實現,性能影響幾乎不可察覺,因此它似乎是可行的。 但是,我還沒有意識到在LLVM中有任何類似的努力。

Rust不保證其運營速度。 如果您需要保證,則需要調用匯編程序。

也就是說,當前Rust轉發到LLVM,所以你可以調用內在函數,它將1:1映射到LLVM內在函數並使用這些保證。 但是,無論你做什么都不是asm,請注意優化器可能對你認為最優的東西有不同的看法,因此不優化你對LLVM內在函數的手動調用。

也就是說,Rust努力盡可能快,因此您可以假設(或者只是查看標准庫的實現)所有具有相同LLVM內在函數的操作將映射到該LLVM內在函數,因此可以像LLVM可以做到這一點。

對於給定的基本算術運算,哪個操作最快是沒有一般規則的,因為它完全取決於您的用例。

想像素處理

那么你根本不應該考慮單值操作; 您想要使用SIMD指令。 這些目前在穩定的Rust中不可用,但有些可通過功能門控功能訪問,並且所有功能都可通過匯編獲得。

是否有可能LLVM將代碼優化為SIMD,就像它對clang一樣?

正如aochagavia已經回復 ,是的,LLVM將自動調整某些類型的代碼。 但是,當您要求最高性能時,通常不希望自己處於優化器的一時興起。 我傾向於希望在我的普通普通代碼中進行自動向量化,然后為我的重數學內核編寫直線代碼,然后編寫SIMD代碼並測試速度的正確性和基准。

暫無
暫無

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

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