650 likes | 777 Views
スケーラブルでないモジュールを含む 並列プログラムにおける高性能の達成 Achieving High Performance in Parallel Programs Containing Unscalable Modules. 東京大学 大学院 理学系研究科 情報科学専攻 大山恵弘. 満足のいく性能モデル. プロセッサ増加 ⇒ 実行時間減少 or 実行時間そのまま. すべてのプログラムで成立してほしい. はたして現実は?. Motivating Example. 各スレッドが独立に fib(10) と 共有カウンタの増加 を交互に繰り返し実行するプログラム
E N D
スケーラブルでないモジュールを含む並列プログラムにおける高性能の達成Achieving High Performance in Parallel Programs Containing Unscalable Modules 東京大学 大学院 理学系研究科 情報科学専攻 大山恵弘
満足のいく性能モデル プロセッサ増加 ⇒ 実行時間減少 or実行時間そのまま すべてのプログラムで成立してほしい はたして現実は?
Motivating Example • 各スレッドが独立にfib(10)と共有カウンタの増加を交互に繰り返し実行するプログラム • C + Pthreads, Sun Enterprise 10000 • 仕事量の総和はプロセッサ数に非依存 実行のほんの一部が逐次化 ↓ 満足のいく性能モデルが破綻
実行を逐次化するモジュール(ボトルネックモジュール)実行を逐次化するモジュール(ボトルネックモジュール) • Thread-unsafeライブラリ • MPICH、GTK+ • 共有資源の操作 • I/O、GUI、大域変数、共有バッファ • 並列ループの誘導変数 • 暗黙に排他処理するライブラリ • 多くのmallocの実装 広範囲に存在!
逐次モジュールが ほとんどないプログラム 並列分野の既存研究の多く 現状 多くの並列プログラムで不満足な性能モデル! 並列プログラム GUI Fib 行列積 自然言語処理 暗号破り webサーバ
ボトルネックの最大性能ギリギリ 本研究の目的 • 満足のいく性能モデルを、すべての並列プログラムで実現する言語 • 共有メモリ計算機が対象 We don’t like U
Q: 満足のいく性能モデルを 得ることに意味あるの? A: ある! このへんで実行したら悲劇 (最高性能の半分) time number of processors
U字の底のプロセッサ数で実行すればいいのでは?U字の底のプロセッサ数で実行すればいいのでは? • 最適なプロセッサ数は予測困難 • 動的な挙動の予測はときに困難 • 最適な数は入力やプログラムの場面に依存 色々なプロセッサ数で何回も同じ計算をするのは 処理系実装者やベンチマーク屋だけ!
並列処理を大きく discourage! 我々の怒り 多くの並列プログラマが 唯々諾々と従っている啓示 「並列化の恩恵受けたければ、 ボトルネックを皆無にすべし」 こんな高飛車で、万人に並列処理が普及するか? 「最高性能を出すプロセッサ数は プログラマが自分で見つけるべし」 そんな苦労をプログラマに負わせておいていいのか?
我々が取り組んだ問題 • ボトルネック存在下でも高性能を出すには • 排他処理 • スレッドスケジューリング • 言語設計 はどうあるべきか?
3つの本質的な部分問題 • ボトルネック部分の実行コストの削減 • ボトルネック担当プロセッサの動的導入で達成 • ボトルネック部分の実行回数の削減 • 複数の呼び出しの「融合」で達成 • ボトルネック部分での過大なメモリ消費の抑制 • プロセッサ数の動的制御で達成
1 2 3つのポイントがもたらすもの time number of processors
3 3つのポイントがもたらすもの メモリ消費量 limit number of processors
我々の言語Amdahl • C+++ 軽量スレッド+ 排他メソッド 単純なプログラミングモデルを提供
スレッド • API:athread_create(f, arg, thr_id); • Lazy Task Creation [Mohr et al. 91]にもとづくスレッド管理 • 低コストで多数のスレッドを生成可 • 「並列単位1つ ⇔ スレッド1つ」のプログラミング • ランタイムが自動的に動的負荷分散 • Task stealing
排他機構 • 排他メソッド • ≒ synchronized methods in Java • 1つのオブジェクト上で排他的に実行されるメソッド class Counter { int value; … sync inc(int n) { value += n; } }
Part 1ボトルネック部分の実行におけるメモリ通信コストの最小化 情報処理学会論文誌に掲載 その拡張版を国際学会PDSIA ’99で発表
既存の逐次化モジュールの実装法 • ロックを付加し呼び出しを逐次化 CPU1 CPU2 CPU3 ボ
既存の方法の問題 (1) • ロック操作で大きなメモリアクセス遅延 • 同じアドレスへのアクセスの衝突→アクセスコストの飛躍的増加 CPU2 CPU1 CPU3
既存の方法の問題 (2) • 更新された情報の読出でキャッシュミス • 異なるプロセッサが交代で実行するため CPU1 CPU2 CPU3 ボ a, b
担当するぞ! Amdahlのランタイム技術 • アクセス衝突 → 呼び出しデータ(タスク)のリスト作成 • 複数の呼び出しを1プロセッサが連続実行 CPU2 CPU3 f(5) f(3) f(7) ボ CPU1 a, b
Amdahlのランタイム技術 • アクセス衝突 → 呼び出しデータ(タスク)のリスト作成 • 複数の呼び出しを1プロセッサが連続実行 f(5) f(3) f(7) CPU2 CPU3 ボ CPU1 a, b
この方法がもたらす利益 • ロック操作の大幅減少 • 例: 1回ロック操作して、30個メソッド実行 • 全部消えはしない • 連続実行中:オブジェクトの読出と更新 ⇔ キャッシュの読出と更新 • ボトルネックに常にプロセッサ
Amdahlのコンパイル時最適化 • メモリ読出コストをさらに削減 • Prefetch 命令の挿入 • 手続き間 register promotion これの実行中 この情報をprefetch 連続実行中はa,bをレジスタに置く f(5) f(3) f(7) ボ a, b CPU1
実験 • アプリケーション • N body, RNA • 比較したもの • C + Solaris threads + task queue • Spin locks, mutex locks • Amdahl • Spin locks, mutex locks, 我々の提案する方法 • Sun Enterprise 10000 (64 CPU)
非衝突時の性能 • Amdahlの方法の実行時間: • 単純なblocking lockの0.92倍 • 単純なspin lockの1.32倍
Part 2複数の排他的な操作を融合する機構 情報処理学会論文誌に掲載
既存の枠組みの問題 • プログラムの動的挙動に適応する効率化支援機構が少ない • 我々の観測: アクセス衝突時に生じる効率化の機会を 有効利用できていない 重複して呼び出し CPU2 CPU3 repaint repaint repaint CPU1 window
Amdahlのアプローチ • 排他メソッドの複数の呼び出しの融合 • 動的に逐次化された2つの呼び出しを融合 • プログラマが融合規則を記述
プログラム例 (1/2) class Window { … sync repaint() { … } fusion repaint() & repaint() { repaint(); } } 融合規則 repaintを「まびき」
プログラム例 (2/2) class Buffer { int len; double elements[...]; ... sync void put(double v) { elements[len++] = v; } sync double get() { return elements[--len]; } fusion put(v) & get() { return v; } } 融合規則 putとgetを「バイパス処理」
♪ 専念! 融合処理の実装 タスクリストの操作で実現 CPU2 CPU3 repaint repaint repaint CPU1 window
この融合の研究の広い見方 • 並列言語ならではの効率化の機会を指摘した • 逐次言語: • 並列言語: 文面に現れない制御フロー • 既存研究の盲点 x = y-2;x += 3; x = y+1; val +=1; val +=3; val +=2;
実験 • ImageViewer • repaint & repaint → repaint • FileWriter • write & write → strcat + write • RNA • inc & inc → inc
Part 3プロセッサ数の動的調節によるメモリ消費量の制御
単純な実装における問題 • ボトルネックにおける大きなメモリ消費量 CPU2 ….. f() f() f() CPU3 ... CPU1 ボ CPUn 生産者消費者アプリケーション一般が共有
メモリ消費量拡大による悪影響 • Cache miss, page faultの増加 • Working setの増加による • 他ジョブで使えるメモリが減少 • 1つの邪悪なプログラムが、その計算機上の全プログラムを凍らせうる
Motivating Example ボトルネックに付加されるタスク数: 数百のオーダ ←タスク数
我々の目標 • 1つのオブジェクト(モジュール)に付加されるタスク数の最大値を小さく抑える • 例:各オブジェクトに最大64個 • 「メモリ消費量の制限⇔タスク数の制限」と問題を限定
目標達成のための単純な方法 • タスク数 = 閾値→タスクを入れようとするCPUはスピンして待つ 64 ….. f() f() CPU3 CPU1 デッドロック発生! (詳細は論文を参照) ボ f()
我々はより緩い目標をめざす • Soft limitをほとんどの場合に越えない soft limit タスク数 時間
我々のアプローチの概要 • プロセッサ数の動的調節でタスク数を制御 • タスク数がsoft limitを越えそう →プロセッサ減らす タスク生成ペースを遅らせる • タスク数がsoft limitを越える気配なし →減らしたプロセッサを復活させる
脱退! Amdahlの実装 生存可能プロセッサ数カウンタ 現プロセッサ数カウンタ 28 50 定期的に更新 CPU2 CPU3 ….. f() f() ... CPU1 ボ CPU50