看板 CompilerDev 關於我們 聯絡資訊
大家好, 最近發現 llvm ir 有一個 attribute 叫做 frame-pointer, 它會影響 performance 目前 O3 預設是 none 的, 而如果是用 clang -emit-llvm -Xclang -disable-O0-optnone 這樣的方式取得沒有優化過的 llvm ir,則會是 all 據我說知,他會消除 frame pointer 的儲存(如果是 none 的話), "理論上"會讓程式的 performance 好一點,畢竟會減少 register 的使用 經過測試,確實如果同是使用 O3 sequence,frame-pointer=none performance確實比較好 但是!! 我用我自己的優化順序, frame-pointer=none 得到的 runtime = 8 sec 左右 frame-pointer=all 得到的 runtime = 3.8 sec 差非常多! 然後我把他們轉成 Assembly code,確實不太一樣, 但 none 程式碼比較短,而且減少很多存取 卻讓 performance 更差勁 可以明白指令的多寡與 performance 無關, 但據我說知,frame-pointer 不去儲存與使用,應該會更快吧? 甚至我自己有些 IR 從 all 改 none 會更好 唯獨某幾個 IR code 會更差。 我測試的 source code 的是 insertion sort https://imgur.com/nqexaZb https://imgur.com/hKigtrh https://imgur.com/FR3qETS https://imgur.com/5119ek8 https://imgur.com/g3RHx98 這些是 Assembly code 的差異, 感覺與 insertion sort 本身的邏輯無關 補上 perf 之後的結果: frame-pointer=all Performance counter stats for './190_all' (10 runs): 142666 cache-misses # 0.020 % of all cache refs ( +- 5.01% ) 698701320 cache-references ( +- 0.71% ) 234781 branch-misses ( +- 0.44% ) 13059296783 cycles ( +- 0.16% ) 59991967735 instructions # 4.59 insn per cycle ( +- 0.05% ) 3.417880975 seconds time elapsed ( +- 0.26% ) frame-pointer=none Performance counter stats for './190_none' (10 runs): 352932 cache-misses # 0.046 % of all cache refs ( +- 2.58% ) 770977710 cache-references ( +- 0.81% ) 260282 branch-misses ( +- 0.33% ) 30052057516 cycles ( +- 0.05% ) 60037013675 instructions # 2.00 insn per cycle ( +- 0.05% ) 7.921856465 seconds time elapsed ( +- 0.05% ) 看起來branch-misses 高大概10% Insn per cycle 直接慢一半.. -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.43.59.118 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/CompilerDev/M.1636380668.A.B00.html
sonicyang: runetime 比較短performance 比較差?我漏看了什麼嗎 ? 11/09 00:50
抱歉,我秒數弄錯了
Lipraxde: Assembly 都在你眼前了,再加點油分析一下。 11/09 01:55
Lipraxde: LLVM 可以在每個 pass 跑完後 dump IR / machine IR,11/09 01:55
Lipraxde: 對了解優化、為什麼生出這樣的 pattern 很有幫助。11/09 01:55
Lipraxde: 另外就是不太確定你有沒有讀過 System V ABI,如果要做11/09 01:55
Lipraxde: 的這麼深的優化的話熟悉 ABI 是很重要的!11/09 01:55
Lipraxde: 啊...好像講了些不太相干的東西,回到你的問題,雖然給11/09 02:04
Lipraxde: 的資訊有點少,不過從執行時間的差距、codegen 結果的11/09 02:04
Lipraxde: 差異來看,我會覺得有可能是由於 cache 所造成的。11/09 02:04
剛剛使用 Linux 的工具 perf 分析兩者差異, 在 cache misses, cache reference 上沒有差異, 但在 instrcutions per cycle 上有著顯著的差異: frame-pointer=all 的 有 4.56 instruction num per cycles, frame-pointer=none 的則只有 1.99 instruction num per cycles. ※ 編輯: shane87123 (114.43.59.118 臺灣), 11/09/2021 02:17:11 ※ 編輯: shane87123 (114.43.59.118 臺灣), 11/09/2021 02:32:19
Lipraxde: Branch miss 呢?11/09 09:19
補上了!謝謝大大 ※ 編輯: shane87123 (101.12.89.21 臺灣), 11/09/2021 13:28:27 ※ 編輯: shane87123 (101.12.89.21 臺灣), 11/09/2021 13:28:51
Lipraxde: 有開 frame-pointer 的版本因為有多的 push、move 個關 11/09 16:50
Lipraxde: 係,因此不建議直接對 instruction num per cycles 下 11/09 16:50
Lipraxde: 定論。然後我注意到一個地方,all、none 的 instructio 11/09 16:50
Lipraxde: n 數量是差不多的,可以看看是為什麼 :) 11/09 16:50