内容要旨 | | 今日,並列計算機は実用段階に入り,商用の並列計算機も数多く発売されている.例えば,共有メモリ並列計算機なら数〜数十台程度の規模のものが,分散メモリ並列計算機なら千台以上の規模のものが,現実に稼働している.このため,ハードウェアの面からみれば,並列計算はもはや現実のものである.しかし,ソフトウェアの面からみれば必ずしもそうとはいえない.並列処理記述の負担が,プログラマにとって非常に重いためである. 現在,プログラマは主にライブラリを用いて明示的に並列処理を記述している.このため,プログラマがバグのない並列プログラムを書くことは容易ではなく,並列計算機の普及にも関わらず,並列プログラムは一般的ではない. この困難を克服するため,これまでにさまざまな研究がなされてきた.それらは,大きく分けて,並列化コンパイラの研究と並列プログラミング言語の研究に分類される. 並列化コンパイラは,逐次のプログラミング言語で記述したプログラムを,コンパイラが解析することにより,並列に実行できるようにするものである.ある意味理想的な手法であり,数値計算のような極めて定型的で単純なプログラムにおいては,すでにかなりの成功を収めている.しかし,より複雑なプログラム,例えばコンパイラやエディタのようなプログラムでは,解析が困難になるため,並列化の効果はまったく期待できない. 並列プログラミング言語は,並列性を採り入れた新しい言語を定義し,それでプログラムを記述することで,並列プログラムの記述を容易にしようというものである.本論文の対象言語であるFlengもこの部類に入る.並列プログラミング言語には,並列関数型言語,並列論理型言語,並列オブジェクト指向型言語などがある.並列関数型言語,並列論理型言語は,関数型言語,論理型言語といった,理論的に扱いやすい言語をベースにすることで,プログラマに並列処理の複雑さを意識させることなく,容易に並列プログラムを記述できるようにしたものである.並列オブジェクト指向言語は,プログラムを並列に動作するオブジェクトとしてモデル化することにより,やはり容易な並列プログラムの作成を目指している. 我々の研究室では,このような点を考慮に入れ,並列論理型言語Flengを設計,実装している.Flengは,複雑なプログラムにおいても容易に並列プログラムが記述でき,かつ大量の並列性を抽出可能であるという利点がある.現実に,Flengコンパイラ自身もFlengで記述され,並列に動作している.しかし,Flengを含め,これら並列プログラミング言語では,実行時のオーバーヘッドが大きく,実行効率を向上させるのが難しいという問題点がある. このオーバーヘッドは,大きく分けて2種類に分類できる.細粒度実行に由来するオーバーヘッドと配列処理に由来するオーバーヘッドである.本研究では,これらのオーバーヘッドを取り除く手法を提案し,高い性能を発揮するFlengの最適化コンパイラの実装を行なった. まず,細粒度実行に由来するオーバーヘッドについて説明する.Flengでは,すべてのゴール(Flengにおける実行の単位)を並列に実行する.決まっていない値を参照しなければ実行できないゴールは実行を中断(サスペンド)し,他のゴールによって値が決定されるまで待つ.値が決定された時点で,そのゴールは実行を再開(アクティベイト)する.このような機構を用いることで,複雑なプログラムからでも容易に大量の並列性を抽出することが可能になる.ただし,この機構を矛盾なく実現するため、変数は単一代入変数であり,書き換えることはできない. このような機構を用いると,並列性の抽出は容易に行なうことが可能になるが,並列実行の単位がゴール一つ一つといった,非常に細かなものになる.このため,ゴールの起動やサスペンド,アクティベイトといったそれぞれのゴール間での同期のコストが大きなものになってしまう. この問題点を解決するため,ゴール融合という手法と強制インライン展開という手法を提案した. ゴール融合は複数のゴールを一つにまとめることで,粒度の最適化を行なうものである.このことで,ゴールの起動や同期といったオーバーヘッドを削減することができる.しかし,これは一種のプログラムの逐次化に相当する.もともと並行に動作するものとして記述されたプログラムの逐次化を行なうため,デッドロックの危険性が存在する.したがって,デッドロックを防ぐため,プログラム全体に渡る大域的なデータフロー解析を行ない,安全にゴール融合を行なう手法を提案,実装した. 次に,強制インライン展開は,同期の部分も含めてインライン展開を行なうことで粒度の最適化を行なうものである.通常のインライン展開では,サスペンドする可能性のあるゴールについては展開できなかった.これは,値を待つ必要があるゴールをインライン展開すると,本来待たなければならない値を待たずに実行することになるからである.強制インライン展開は,サスペンドする可能性のあるゴールについても,その同期部分を含めてインライン展開することで,任意のゴールについてインライン展開を可能にした.ただし,任意のゴールで展開が可能なため,過剰な展開によるコードの爆発を防ぐ必要がある.本研究では,高い性能を保ちながら,過剰な展開を防ぐ方法について提案,実装した. 本研究では,これらゴール融合,強制インライン展開の手法について実装,評価を行ない,最大数倍以上の速度向上を達成した. 二つ目の問題点は,配列処理に由来するオーバーヘッドである.先に述べたように,Flengでは,単一代入変数を用いている.このため,もとの配列から一部だけを変更した配列を得ようとした時,新しい配列を確保して,変更部分以外を元の配列からコピーする必要がある.これは,ハッシュやヒストグラム,あるいは数値計算的なプログラムにとっては,非常に大きな問題である.場合によっては,計算の複雑さのオーダーまで変えてしまう. この問題を解決するため,本研究では,配列更新時のコピー操作を除去する手法を提案した.この手法では,更新時にその配列を参照しているゴールが他になければ安全に破壊代入による更新が可能であることを利用する.コンパイル時に配列の参照と更新を逐次化してしまい,配列の更新時にはその配列を参照しているゴールが他にないことを保証する.ただし,ゴール融合の場合と同様,プログラムの逐次化はデッドロックの危険性を持つため,大域的なデータフロー解析を行ない,安全に逐次化を行なう.配列のコピー除去を行なうことで,最大数十倍の速度向上を達成することができた. また,配列処理を行なう際,並列化コンパイラなどで用いられているようなデータ並列的な並列性の抽出が行なわれていない.データ並列とは,配列の各要素に対し,独立に操作が可能な場合,それぞれを並列に実行する方法である.このため,データ並列機構を用いれば抽出可能な並列度を抽出することが出来ず,並列度が低下する場合があった. この問題を解決するために,Flengコンパイラでデータ並列性を抽出する手法を提案した.この手法では,配列のコピー除去を行ない,破壊代入による配列更新を行なう繰り返しにおいて,並列化コンパイラで提案されているような繰り返しを跨ぐデータ依存を解析し,安全にデータ並列性を抽出する.この手法を用いることにより,最大数倍程度の速度向上を達成した. このように,本研究ではFlengコンパイラにおいて新しい最適化手法を提案,実装,評価し,従来のコンパイラに比べて数〜数十倍の速度向上を達成した. |