[問題] 拆迴圈+效能測試

看板C_and_CPP作者 (冷羽翼塵)時間12年前 (2011/10/13 20:34), 編輯推噓6(6037)
留言43則, 9人參與, 最新討論串1/3 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Microsoft Visual C++ 2010 Express 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) CLR 問題(Question): 不曉得為什麼把迴圈拆開後結果反而差了~ 囧了 希望各位大大指點迷津.... 餵入的資料(Input): (無) 預期的正確結果(Expected Output): 拆開後的迴圈測試會比較快 錯誤結果(Wrong Output): (未拆的迴圈比較快?) 程式碼(Code):(請善用置底文網頁, 記得排版) http://pastie.org/2688459 補充說明(Supplement): 輸出: 20.1379 0.0022 PS: 本來是想說拆開迴圈後會比較快的話,那搞一個執行期時把拆開後的迴圈程式 編譯後再動態載入~ 嘿嘿~ 可一開始的測試就跌破我眼鏡說XD -- ※ 發信站 :批踢踢實業坊(ptt.cc) ◆ From: 218.164.80.203

10/13 20:36, , 1F
可以觀察看看編譯出來MSIL
10/13 20:36, 1F

10/13 20:39, , 2F
猜測可能迴圈版本有被編譯器辨識出來可用SIMD來處理
10/13 20:39, 2F

10/13 20:41, , 3F
先解釋一下你為什麼覺得拆開迴圈會比較快
10/13 20:41, 3F

10/13 20:44, , 4F
反組譯出來的MSIL,test1比test2大了610倍...
10/13 20:44, 4F

10/13 20:45, , 5F
不過看不出test2有用了什麼神奇的做法,好像只是普通迴圈
10/13 20:45, 5F

10/13 20:46, , 6F
test1 http://codepad.org/vnMlvu8X (不完整)
10/13 20:46, 6F

10/13 20:47, , 7F
10/13 20:47, 7F

10/13 20:49, , 8F
@@a 因為這邊把迴圈拆了連i++和往回跳的動作都省啦~所以
10/13 20:49, 8F

10/13 20:49, , 9F
才會覺得在相同條件下會比較快就是了
10/13 20:49, 9F

10/13 20:50, , 10F
編譯器會最佳化阿~"~
10/13 20:50, 10F

10/13 20:51, , 11F
release的test2就很明顯了 http://codepad.org/O6X5JoaT
10/13 20:51, 11F

10/13 21:01, , 12F
嗯...(搔頭) 是說迴圈整個被省掉了...?
10/13 21:01, 12F

10/13 21:03, , 13F
cpblk
10/13 21:03, 13F

10/13 21:03, , 14F
一般純C++也會optimize成memcpy
10/13 21:03, 14F

10/13 21:07, , 15F
我剛剛很無聊幫你測試一下,我發現主要應該是assignment太多
10/13 21:07, 15F

10/13 21:07, , 16F
導致.net有額外的overhead
10/13 21:07, 16F

10/13 21:09, , 17F
在debug模式下,test1是15.xms,test2是0.2xms
10/13 21:09, 17F

10/13 21:09, , 18F
但是!! 如果在test1()和test2()裡面各用迴圈重跑十次
10/13 21:09, 18F

10/13 21:09, , 19F
test1是17.xms,test2是3.x ms
10/13 21:09, 19F

10/13 21:10, , 20F
也就是說一千次迴圈的確有它的overhead
10/13 21:10, 20F

10/13 21:10, , 21F
可是call一千行指令的function也有它的overhead
10/13 21:10, 21F

10/13 21:11, , 22F
光是call這個function還沒做事就導致它要花掉12ms以上
10/13 21:11, 22F

10/13 21:19, , 23F
感謝這個測試,我本來想寫loop unrolling的template
10/13 21:19, 23F

10/13 21:21, , 24F
剛google了一下cpblk是指opcodes.cpblk(copy block)?
10/13 21:21, 24F

10/13 21:24, , 25F
我想小提一下,loop 有時確實展開較佳,這在bit hack 還
10/13 21:24, 25F

10/13 21:24, , 26F
是數值分析, 是蠻常被拿來加速的, 依情況而定.
10/13 21:24, 26F

10/13 21:25, , 27F
這邊我想延伸問一個問題,如果不是完全展開迴圈
10/13 21:25, 27F

10/13 21:26, , 28F
有了~我把計時器擺進function內,結果為0.0107, 0.0054
10/13 21:26, 28F

10/13 21:26, , 29F
而是改成一次跳一段,loop counter判斷會變少,會快嗎
10/13 21:26, 29F

10/13 21:27, , 30F
@s3748679, 我推你原版 timer 被 release 亂放或洗掉.
10/13 21:27, 30F

10/13 21:32, , 31F
@iamstudent: 真有緇硃必究到這種地步的話,建議去看
10/13 21:32, 31F

10/13 21:32, , 32F
asm怎麼翻的,永遠不知道compiler會免費服務到什麼地步.
10/13 21:32, 32F

10/13 21:33, , 33F
"理論上" 減少branch,確實是可達到加速功效。
10/13 21:33, 33F

10/13 21:37, , 34F
感謝回答,所以還是應該要用實際測試來判斷結果
10/13 21:37, 34F

10/13 21:39, , 35F
演算法改善永遠放第一,細節優化永遠放演算法後面。
10/13 21:39, 35F

10/13 21:44, , 36F
(啊對~ 忘了說剛那數據是我能關的最佳化都關的情況下測的
10/13 21:44, 36F

10/13 21:45, , 37F
(晚點來搞搞看,想辦法不讓它cpblk =w=
10/13 21:45, 37F

10/13 22:13, , 38F
其實我懷疑在runtime的時候還有做一次最佳化...
10/13 22:13, 38F

10/13 22:14, , 39F
畢竟這種二次編譯的程式,要動手腳的機會好像更多?XD
10/13 22:14, 39F

10/13 22:15, , 40F
關最佳化並沒有任何的意義...
10/13 22:15, 40F

10/13 23:02, , 41F
原來編譯能幹那麼多偷雞摸狗的事喔..(汗
10/13 23:02, 41F

10/13 23:04, , 42F
compiler是個很恐怖的東西啊....
10/13 23:04, 42F

10/15 01:31, , 43F
理論上有一種叫做預測
10/15 01:31, 43F
文章代碼(AID): #1Ebjhbds (C_and_CPP)
文章代碼(AID): #1Ebjhbds (C_and_CPP)