グローバル変数探索回数削減による高速化 for 3impVM

2,226 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,226
On SlideShare
0
From Embeds
0
Number of Embeds
77
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • グローバル変数探索回数削減による高速化 for 3impVM

    1. 1. <ul><ul><li>グローバル変数探索回数削減による </li></ul></ul><ul><ul><li>高速化 </li></ul></ul><ul><ul><li>for 3impVM </li></ul></ul><ul><ul><li>mokehehe </li></ul></ul>'09/04/05
    2. 2. 動機 <ul><li>3imp (Three Implementation Models for Scheme [ pdf ])という、Schemeコンパイラを実装するための論文がある </li></ul><ul><ul><li>SchemeのソースをコンパイルしVMで実行する </li></ul></ul><ul><li>スタックベースモデルの実装例 </li></ul><ul><li>速度検証してみよう </li></ul>
    3. 3. フィボナッチ計算 <ul><li>比較、if式、関数呼び出しと加算減算だけの簡単なお仕事 </li></ul>(define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) <ul><li>計算量は指数的に増加 -> 無駄な計算をさせるのに最適 </li></ul>
    4. 4. ベンチマーク <ul><li>fib(30)の処理時間の比較 </li></ul>
    5. 5. 遅い <ul><li>gccで機械語にコンパイルしたものはともかく、同じVM方式のGaucheやLuaにも負けてる </li></ul>うそっ…私の VM, 遅すぎ…? 5分 で判定! 26 万処理系が受けた大人気の フィボナッチベンチ 。あなたの 処理速度 や 呼び出し回数 がすぐわかる… <ul><li>何が遅いのか? </li></ul>
    6. 6. コンパイルされた命令列は? ( FRAME (CONST 2 ARG LREF 0 ARG GREF < APPLY 2) TEST ( LREF 0 RET ) FRAME ( FRAME (CONST 2 ARG LREF 0 ARG GREF - APPLY 2) ARG GREF fib APPLY 1 ) ARG FRAME (FRAME ( CONST 1 ARG LREF 0 ARG GREF - APPLY 2) ARG GREF fib APPLY 1 ) ARG GREF + SHIFT 2 APPLY 2 ) (define (fib n) (if (< n 2) n ( + (fib (- n 1)) (fib (- n 2)) ))) コンパイル 基本演算も関数呼び出しというところはあるが、別段おかしなところはない
    7. 7. プロファイルを取る <ul><li>よろしい、ならばプロファイリングだ </li></ul>Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 52.14 1.10 1.10 2 0.55 1.05 VM 28.67 1.71 0.61 9423958 0.00 0.00 ht_find 5.21 1.82 0.11 9423879 0.00 0.00 gvht_check 4.27 1.91 0.09 9423948 0.00 0.00 gvht_hash 3.08 1.97 0.07 2692536 0.00 0.00 subr_difference 2.37 2.02 0.05 2692537 0.00 0.00 subr_lessthan 1.90 2.06 0.04 2692537 0.00 0.00 check_argnum 1.42 2.09 0.03 1346268 0.00 0.00 subr_plus ... やたらと呼び出し回数の多いものがある
    8. 8. グローバル変数の探索が多すぎる <ul><li>fibを呼び出す度に6回GREFが発生 </li></ul><ul><li>スクリプト言語だと関数呼び出し時の、呼び出し先関数(グローバル変数)の参照にもコストがかかる </li></ul><ul><li>解決するには? </li></ul>
    9. 9. 回想シーン <ul><li>Ypsilon/LittleWingの藤田さんの話 </li></ul><ul><ul><li>実行時に命令を書き換えて、トップレベルの関数のアドレスを埋め込んでいる、との話 </li></ul></ul>
    10. 10. 回想シーン(2) <ul><li>Higeponさんのmosh高速化の話 </li></ul><ul><ul><li>聞いてくれ Mosh に信じられないことが起きたんだ </li></ul></ul><ul><li>Gauche:グローバル変数参照の最適化 </li></ul><ul><li>グローバル変数アクセスを改善したら劇的にスピードアップしたという話 </li></ul>
    11. 11. 3impVMでも試してみよう <ul><li>でもどうやって? </li></ul>
    12. 12. 実行時のグローバル変数探索 <ul><li>キー(変数名)からハッシュ値を計算 </li></ul><ul><li>ハッシュエントリを探す </li></ul>fib ハッシュ値 HashTable HashEntry fib 関数の実体 ...
    13. 13. コンパイルされたバイトコード GREF fib 次の命令 前の命令
    14. 14. GREF初回実行時に書き換え GLOC fib 関数の実体 GREF fib 次の命令 前の命令
    15. 15. 結果: (1)呼び出し回数 <ul><li>実行時の呼び出し回数上位を占めていたグローバル変数探索回数が激減! </li></ul>% cumulative self self total time seconds seconds calls s/call s/call name 52.14 1.10 1.10 2 0.55 1.05 VM 28.67 1.71 0.61 9423958 0.00 0.00 ht_find 5.21 1.82 0.11 9423879 0.00 0.00 gvht_check 4.27 1.91 0.09 9423948 0.00 0.00 gvht_hash 75.56 0.68 0.68 2 340.02 437.53 VM ... 0.00 0.90 0.00 87 0.00 0.00 ht_find 0.00 0.90 0.00 77 0.00 0.00 gvht_hash 0.00 0.90 0.00 8 0.00 0.00 gvht_check
    16. 16. 結果: (2)実行速度 <ul><li>fib(30)の速度: </li></ul><ul><ul><li>GLOC使用前:1.857秒 </li></ul></ul><ul><ul><li>GLOC使用後:0.961秒  48.2% 高速化! </li></ul></ul><ul><li>他の VM と比べても遜色ない速度を達成 </li></ul>
    17. 17. 結論 <ul><li>実行時に命令を書き換えてグローバル変数の探索を減らすことによってフィボナッチベンチマークで 約 50% の実行時間の短縮を実現できた </li></ul><ul><li>グローバル変数の参照(グローバル関数呼び出し含む)が多数を占めるプログラムではこの実行時書き換えは非常に有効 </li></ul>
    18. 18. 落ち <ul><li>それでもC版の35.6倍かかってるけどな! </li></ul>以上、ありがとうございました

    ×