ETH官方钱包

創作內容

2 GP

最佳化C++的fmodf函式

作者:巧克力喬斯達│2024-12-12 03:47:12│巴幣:4│人氣:21
因緣際會下, 意外地發現fmodf()還有最佳化的餘地
這個還有fmod(), fmodl()等等變種, 主要就是去取小數點相除的餘數

計算方式很單純:
V1 % V2 = V1 - V2 * truncate(V1 / V2)
truncate就是去把小數部分去掉

但實測之後, fmodf就是會多花點時間, 以下是三種實作方法的比較時間
而且這是在Release build下測試的, 也就是說程式最佳化基本上已經有了 (/O2)
另外還把Floating Point Model設定為快速 (/fp:fast)
從0.354ms -> 0.124ms ->0.019ms, 到底經歷了什麼?

fmodf方法:
測試很單純, 簡單寫個迴圈去加總 <i除以*Dividend的餘數>
*被除數應該叫Dividend, 截圖時才發現打錯了

而Fmodf_Fast, Fmodf_Fast2是自己寫的另外兩個小函式:

Fmodf_Fast就是去算公式, 用了另一個內建函式truncf(), 與fmodf相比耗時直接砍半
Fmodf_Fast2則是再加以利用SSE指令集, 先透過_mm_load_ss轉換為__m128
再用_mm_cvtt_ss2si轉換為整數, 最後cast成float回傳, 又比前一個方法快十倍


不過造成這種差異的主因到底是什麼?
難道fmodf()做了預料之外的事? 還真的是
先看一下兩個自製函式的彙編指令:

不意外SSE版本的指令是最少的, 內建的truncf稍微多了一點
最後則是fmodf的彙編指令:

果然很多指令! 從裡面很多jl與cmp指令來判斷, 主要應該是在做錯誤處理的部分
不過不能怪它, 畢竟它要做為一個標準函式庫的內容, 這些檢查是必須的

------------------------------------------------------------------------------------------
大概就分享到這~
實際上如果被除數不是這麼好看的數字, 自製函式跟fmodf的輸出結果會有一點不同
如果應用程式不需要很精確的浮點數餘數, 並且以速度為主的話 (例如遊戲開發)
那麼自己去做fmodf還是挺值得的

至於沒有0或NaN的檢查也不是大問題
在呼叫餘數計算之前就應該要處理好或者直接避免這種情況出現

引用網址:http://www.jamesdambrosio.com/TrackBack.php?sn=6054997
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

2喜歡★ltes50414 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:英國購屋流程紀錄...


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情? 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】