コンパイラ演習 第 9 回 (2011/12/08) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴

Slides:



Advertisements
Similar presentations
論理回路 第 11 回
Advertisements

コンパイラ演習 第 6 回 2005/11/17 大山 恵弘 佐藤 秀明. 今回の内容 実マシンコード生成 – アセンブリ生成 (emit.ml) – スタブ、ライブラリとのリンク 末尾呼び出し最適化 – 関数呼び出しからの効率的なリターン (emit.ml) –[ 参考 ]CPS 変換 種々の簡単な拡張.
コンパイラ演習 第 6 回 (2011/11/17) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
コンパイラ演習 第 12 回 (2012/01/05) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
プログラミング演習( 2 組) 第 9 回
CPU設計と パイプライン.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
07. 値予測 五島 正裕.
07. 値予測 五島 正裕.
2006/11/9 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
タスクスケジューリング    .
プログラミング演習(1組) 第7回
ヒープソートの演習 第13回.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第4回 配列(2) 情報・知能工学系 山本一公
近似アルゴリズム 第10章 終了時刻最小化スケジューリング
計算機アーキテクチャ特論Chapter.6.6~6.9
2006/11/30 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
コンパイラ演習番外編 (その2): JVM コンテスト
コンパイラ演習番外編 (その1): min-rt 改 コンテスト
テープ(メモリ)と状態で何をするか決める
2006/10/12 山下 諒蔵 佐藤 春旗 前田俊行 大山 恵弘 佐藤 秀明 住井 英二郎
プログラミング演習(2組) 第12回
コンパイラ演習 第 8 回 (2011/12/01) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
2006/12/7 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2007/1/18 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/11/16 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
コンパイラ演習 第 4 回 (2011/10/27) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
Ibaraki Univ. Dept of Electrical & Electronic Eng.
2007/1/11 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
第5回 CPUの役割と仕組み3 割り込み、パイプライン、並列処理
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
8. 順序回路の簡単化,機能的な順序回路 五島 正裕.
第7回 2006/6/12.
論理回路 第7回
論理回路 第8回
変更文の移動を可能にした 静的単一代入形式上の部分冗長性除去
Advanced Computer Architecture
シャノンのスイッチングゲームにおけるペアリング戦略の複雑さについて
第25章 単一始点最短路 3節 Bellman-Fordのアルゴリズム
プログラミング演習(2組) 第8回
最適化の方法 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第11章.
Advanced Computer Architecture
レジスタの割付け 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第12章5節.
アルゴリズムとデータ構造 第3章 ヒープ 6月10日分
実行時情報を用いて通信を最適化するPCクラスタ上の並列化コンパイラ
連続領域におけるファジィ制約充足問題の 反復改善アルゴリズムによる解法 Solving by heuristic repair Algorithm of the Fuzzy Constraint Satisfaction Problems with Continuous Domains 北海道大学.
or-3. 作業リスト,スケジューリング,PERT図 (オペレーションズリサーチを Excel で実習するシリーズ)
08. メモリ非曖昧化 五島 正裕.
VMが利用可能なCPU数の変化に対応した 並列アプリケーション実行の最適化
コンピュータアーキテクチャ 第 11 回.
コンピュータアーキテクチャ 第 10 回.
09. メモリ・ディスアンビギュエーション 五島 正裕.
JAVAバイトコードにおける データ依存解析手法の提案と実装
論理回路 第12回
論理回路 第4回
コンピュータアーキテクチャ 第 9 回.
コンピュータアーキテクチャ 第 10 回.
直並列グラフの連続多重彩色 西関研究室 吉田進太郎.
コンピュータアーキテクチャ 第 3 回.
コンピュータアーキテクチャ 第 5 回.
論理回路 第5回
コンピュータアーキテクチャ 第 9 回.
コンピュータアーキテクチャ 第 5 回.
~sumii/class/proenb2009/ml6/
コンピュータアーキテクチャ 第 11 回.
情報システム基盤学基礎1 コンピュータアーキテクチャ編
Presentation transcript:

コンパイラ演習 第 9 回 (2011/12/08) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎

今回の内容 命令スケジューリング グラフ彩色によるレジスタ割り当て

命令スケジューリングとは 命令の順序を並び替える事 二つの効果がある 命令レベル並列性の向上 データ局所性向上 (→ レジスタ割り当ての効率向上)

命令レベル並列性の向上 例: p[0][0] + p[1][1] + p[2][2] a = load p[0] b = load a[0] c = load p[1] d = load c[1] e = fadd b d f = load p[2] g = load f[2] R = fadd e g a = load p[0] c = load p[1] b = load a[0] d = load c[1] f = load p[2] e = fadd b d g = load f[2] R = fadd e g Data hazard Data hazard load load load load load load load load fadd load load fadd load load fadd fadd 14 サイクル 10 サイクル (load,faddのレイテンシが2の場合)

データ局所性の向上 例: p[0][0] + p[1][1] + p[2][2] 生存変数 生存変数 {a} {a,c} {a,b} {b,d} {b,d,f} {e,f} {e,g} {R} a = load p[0] c = load p[1] b = load a[0] d = load c[1] f = load p[2] e = fadd b d g = load f[2] R = fadd e g a = load p[0] b = load a[0] c = load p[1] d = load c[1] e = fadd b d f = load p[2] g = load f[2] R = fadd e g {a} {a,b} {b,c} {b,d} {e} {e,f} {e,g} {R} レジスタが 3 つ必要 レジスタは 2 つで良い

並列性と局所性のトレードオフ 命令レベル並列性を上げる為には… データの局所性を上げる為には… 無関係な (因果関係にない) 命令を近くに配置する データの局所性を上げる為には… 関係する (因果関係がある) 命令を近くに配置する どの様な戦略を取るべきかはアーキテクチャに依る

スケジューリング(リストスケジューリング)の手順 命令間の依存を解析しグラフ構築 グラフから一命令づつ取り出しながら スケジュール

依存解析 命令 a, bの順番を変えると意味が変わるとき 「b は a に依存する」という。 x = ... ... RAW (Read after Write) 依存関係 WAR (Write after Read) 依存関係 WAW (Write after Write) 依存関係 x = ... ... .. = .. x .. RAW .. = .. x .. ... x = ... WAR x = ... ... WAW

依存グラフと ready set 依存グラフ G = (V, E) と ready set R を構築 V = {命令} E = { (a, b) | bがaに依存 } R = { a | indegree(a) = 0 } i1 i2 i3 i4 i5 i6 i7 i8 R i1: a = load p[0] i2: b = load a[0] i3: c = load p[1] i4: d = load c[1] i5: e = fadd b d i6: f = load p[2] i7: g = load f[2] i8: R = fadd e g

資源制約 資源制約: 演算器等が使用可能かどうか? テーブルを作成して管理 ALU FADD MEM ALU FADD MEM c = fadd a b x = load p[0] ステージ 1 cycle n ステージ 2 ALU FADD MEM c = fadd a b x = load p[0] ステージ 1 cycle n+1 ステージ 2

レイテンシ制約 レイテンシ制約: 演算結果が使用可能かどうか? Ready set の各命令に あと何サイクル待つ 必要があるかを表す カウンタを付与 cycle n cycle n+1 cycle n+2 発行 i1 i2 i1 i2 i2 1

リストスケジューリング 全命令を並べ終わるまで以下を繰り返す。 Ready set に実行可能な命令あれば 優先度の高い命令を一つ取り出し並べる グラフ、ready set を更新 資源制約・レイテンシ制約を 1 サイクル分更新 i1 i2 i3 i4 i5 i6 i7 i8 R i3 i6 R i2 i4 i7 i5 ? ? ・・・ i1 ? ・・・ i8

スケジューリングの戦略 何を優先的に取り出すか? どれくらい真面目に計算するか? 実行時間を優先 vs 資源節約を優先 「優先度が高いが制約を満たさない命令」 と「優先度は低いが制約を満たす命令」 のどちらを先に並べるべきか? どれくらい真面目に計算するか? 最適なスケジューリングを行う事は一般に NP 困難

実行時間優先のスケジューリング (例) クリティカルパスを優先的にスケジュール 先行命令のレイテンシを辺の重みとする ALU FADD cycle = 0 i1 i2 i3 i4 i5 i6 i7 i8 ALU FADD MEM 2 2 2 2 2 2 2

実行時間優先のスケジューリング (例) クリティカルパスを優先的にスケジュール ALU FADD MEM i1 cycle = 0 i1 i1 i2 i3 i4 i5 i6 i7 i8 ALU FADD MEM i1 2 2 2 2 2 2 2 i1

実行時間優先のスケジューリング (例) クリティカルパスを優先的にスケジュール ALU FADD MEM i3 i1 cycle = 1 i3 i6 ALU FADD MEM i3 i1 2 2 1 i2 i4 i7 2 2 i5 2 2 i1 i3 i8

実行時間優先のスケジューリング (例) クリティカルパスを優先的にスケジュール ALU FADD MEM i2 i3 cycle = 3 i6 ALU FADD MEM i2 i3 2 i2 1 i4 i7 2 2 i5 2 2 i1 i3 i2 i8

実行時間優先のスケジューリング (例) クリティカルパスを優先的にスケジュール i1: a = load p[0] i3: c = load p[1] i2: b = load a[0] i4: d = load c[1] i6: f = load p[2] i5: e = fadd b d i7: g = load f[2] i8: R = fadd e g 10 サイクル レジスタ 3 個 i1 i3 i2 i4 i6 i5 i7 i8

資源節約優先のスケジューリング (例) 既に並べた命令に依存する命令を 優先的にスケジュール 1 i1 i2 i3 i4 i5 i6 i7 2 2 2 3 4 後続命令に先行命令より高い優先度を付与

資源節約優先のスケジューリング (例) 既に並べた命令に依存する命令を 優先的にスケジュール 1 i1 i2 i3 i4 i5 i6 i7 2 2 2 3 i1 4 後続命令に先行命令より高い優先度を付与

資源節約優先のスケジューリング (例) 既に並べた命令に依存する命令を 優先的にスケジュール 1 i3 1 i6 2 2 i2 i4 2 3 i5 i1 i2 4 i8 後続命令に先行命令より高い優先度を付与

資源節約優先のスケジューリング (例) 既に並べた命令に依存する命令を 優先的にスケジュール 1 i3 1 i6 2 i4 2 i7 3 4 i8 後続命令に先行命令より高い優先度を付与

資源節約優先のスケジューリング (例) 既に並べた命令に依存する命令を 優先的にスケジュール i1: a = load p[0] i2: b = load a[0] i3: c = load p[1] i4: d = load c[1] i5: e = fadd b d i6: f = load p[2] i7: g = load f[2] i8: R = fadd e g 14 サイクル レジスタ 2 個 i1 i2 i3 i4 i5 i6 i7 i8 後続命令に先行命令より高い優先度を付与

グラフカラーリングによる レジスタ割り当て 現実のコンパイラで幅広く用いられている方法 手順 生存解析 干渉グラフ構築 グラフ塗り分け

生存解析 各命令実行直後に生きている変数を求める 「生きている ⇔ その後使われる」なので後方解析 live[i]: 命令iの実行直後に生きている変数 def[i]: 命令iが定義する変数 use[i]: 命令iが使用する変数 live = (A\{x})U{a,b} x = a + b live = A

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret R: 戻り値用レジスタ live

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret {R} R: 戻り値用レジスタ live

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret {R} # ({R}\Φ)UΦ {R} R: 戻り値用レジスタ live

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret {c,g} # ({R}\{R})U{c,g} {R} R: 戻り値用レジスタ live

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret {c,f} # ({c,g}\{g})U{f} {c,g} {R} R: 戻り値用レジスタ live

生存解析の例 a = load m[i] b = load m[j] d = load x[i] c = fmul a b 例:m[i]*m[j]/(x[i]-x[j])^2 a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret {c,d,e} # ({c,f}\{f})U{d,e} {c,f} {c,g} {R} R: 戻り値用レジスタ live

生存解析の例 {i,j,m,x} {a,i,j,m,x} {a,b,i,j,x} {a,b,d,j,x} {c,d,j,x} {c,d,e} 例:m[i]*m[j]/(x[i]-x[j])^2 {i,j,m,x} {a,i,j,m,x} {a,b,i,j,x} {a,b,d,j,x} {c,d,j,x} {c,d,e} {c,f} {c,g} {R} a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret R: 戻り値用レジスタ live

干渉グラフ G = (V, E) V = {変数 or レジスタ} E = {(a, b) | a,bが同時に生存} m {i,j,m,x} {a,i,j,m,x} {a,b,i,j,x} {a,b,d,j,x} {c,d,j,x} {c,d,e} {c,f} {c,g} {R} a x a = load m[i] b = load m[j] d = load x[i] c = fmul a b e = load x[j] f = fsub d e g = fmul f f R = fdiv c g ret f i j c g b d e R

レジスタ割り当て レジスタ割り当て ⇒ 干渉グラフのカラーリング m m a x a x f f i j c i j c g g b d e レジスタ割り当て ⇒ 干渉グラフのカラーリング m m a x a x f f i j c i j c g g b d e b d e R R

カラーリングの方法 色数が最小となる最適カラーリング を求める事は NP 困難 各変数が spill した場合のコストを計算し それが大きい順に割り当てる Spill コストの大きい変数 ループ内変数 複数回参照される変数 同一命令中で使われる他の変数が spill している 普通、一命令中で複数のメモリアクセスはできない

スケジューリングとレジスタ割り当て: 全体の流れ レジスタ数に余裕があるなら スケジューリング → レジスタ割り当て ないなら レジスタ割り当て→スケジューリング 微妙なら交互に スケジューリング レジスタ割り当て 最初は速度優先 後半はレジスタ節約優先 レジスタが足りなくなったら、 その変数は保留

生存区間分割 長く生きている変数の名前を途中で替える a = ... ... = ... a ... ... .. ここではレジスタに載らなくても良い

生存区間分割 長く生きている変数の名前を途中で替える a = ... ... = ... a ... ... ..

共通課題 二つの共通課題のうち一つ以上を 解いてください

課題1 リストスケジューリングを実装せよ どのような優先順位を設定したか説明すること 最低2種類の戦略を実装し、比較・評価をすること

課題2 min-rt.ml から適度に大きい関数を選び 手作業でレジスタ割り当てと スケジューリングをした結果を示せ 何らかのアルゴリズムに従って行うこと 各班の自作コンパイラの出力を用いてもよいしMinCaml の出力を用いてもよい。

コンパイラ係向け課題 グラフカラーリング (もしくはそれに準ずるアルゴリズム) によるレジスタ割り当てを実装せよ どのような塗り分け方法を採ったか 選択の理由を含めて説明せよ

課題の提出先と締め切り 提出先: compiler-report-2011@yl.is.s.u-tokyo.ac.jp 締め切り: 2 週間後 (12/22) の午後 1 時 (JST) コンパイラ係向け課題締切:2012/2/27 Subject: Report 9 <学籍番号: 5 桁> 例: Report 9 11099 本文にも氏名と学籍番号を明記のこと 半角スペース 1 個ずつ 質問は compiler-query-2011@yl.is.s.u-tokyo.ac.jp まで