以下に、本発明の並列化プログラム生成方法の概略及び実施例を添付の図面を用いて詳細に説明する。
本発明の並列化プログラム生成方法では、まず逐次プログラムからプログラム依存グラフを生成する。次に、他プロセッサエレメントで実行するに適した処理量となるまで、依存関係を縮退し、文の集合を頂点とするプログラム依存グラフを作成する。作成したプログラム依存グラフに基づいて、プログラムを並列化する。このとき、遠隔手続きとして実行される部分プログラムについては、プロセッサエレメントが実行する手続に対応する各頂点において、入出力データを格納するための変数を生成する必要がある。その後、各頂点に相当する「手続き」と、手続きを遠隔プロセッサエレメント上で実行させてデータ転送や同期を制御する「制御プログラム」とを生成する。また並列実行のメカニズムとして、待ち付き制御付き非同期遠隔手続き呼び出しと、データ転送方式と、データ転送制御方式とを用いる。
具体的には、本発明の並列化プログラム生成方法は、次の5つの構成要素を含む。
(1)プログラム解析手法:縮退プログラム依存グラフ
(2)並列実行方式:待ち付き制御付き非同期遠隔手続き呼び出しとデータ転送
(3)データ転送制御方式:データ転送制御情報と制御関数
(4)並列プログラム生成手法:遠隔手続き呼び出し用変数生成方法
(5)並列プログラム生成手法:制御プログラム生成方法
図1は、本発明による並列化プログラム生成方法の概略を示す図である。
ステップS1で、逐次プログラムの依存関係を解析して縮退プログラム依存グラフを生成する。即ち、逐次プログラムからプログラム依存グラフ(PDG:Program Dependence Graph)を生成し、更に各プロセッサエレメントで実行するに適した処理量となるまで依存関係を縮退することにより、手続きを頂点とする縮退プログラム依存グラフを作成する。このステップS1が上記の(1)プログラム解析手法に相当する。
ステップS2で、変数を生成する。実行するマルチプロセッサシステムが分散メモリの場合、手続きへの入出力データをプロセッサ上のメモリ領域に転送し、プロセッサがその領域を用いて計算を行ない、結果を他の適切な領域に転送することになる。そのために用いるデータ変数の複製領域を生成する。このステップS2が、上記の(4)並列プログラム生成手法(遠隔手続き呼び出し用変数生成方法)に相当する。
ステップS3で、作成した縮退プログラム依存グラフから、非投機的に手続きの起動と同期を制御する手続き制御プログラムを生成する。このステップS3が上記の(5)並列プログラム生成手法(制御プログラム生成方法)に相当する。
またステップS4で、縮退プログラム依存グラフから、その各頂点に相当する手続きプログラムを生成する。また上記(2)並列実行方式である待ち付き制御付き非同期遠隔手続き呼び出しとデータ転送とに対応する構成として、並列実行ライブラリ100を用いる。また更に上記(3)データ転送制御方式であるデータ転送制御情報と制御関数とに対応する構成として、データ転送制御ライブラリ101を用いる。
以下に、上記5つの構成要素について詳細に説明する。
(1)プログラム解析手法:縮退プログラム依存グラフ
大規模な組み込みソフトウェアの解析を行なう方法として、依存関係を縮退したプログラム依存グラフという考え方がある。これを利用することによって、大規模ソフトウェアの解析及び並列化が可能となる。
まず逐次プログラムからプログラム依存グラフを生成する処理(図1のステップS1の前半の処理)について説明する。プログラム依存グラフとは、例えば非特許文献2乃至4等に説明されるように、プログラムの文を頂点とし、文と文の間の関係を辺で表現したグラフである。非特許文献2乃至4に記載されるプログラム依存グラフは、次のような頂点集合Vと辺集合Eの組で表現されるものであり、逐次プログラムを解析することにより生成できる。
[V:頂点集合]
エントリ:プログラムの開始ポイントを表す。
初期定義:プログラム開始時の初期値の定義を表す。
プリディケート: If-then-elseまたはwhile-loopの条件判定を表す。
代入文:プログラムの代入文を表す。
最終使用:プログラム終了時の変数の参照を表す。
[E:辺集合]
[制御依存辺: v→c L w]プリディケート頂点vに対して、その条件判定結果により、頂点wに到達するか否かが決まることを表す。Lは条件判定のフラグを表し、L=Tのときは条件判定結果が真の場合に頂点wを実行し、L=Fのときは結果が偽の場合に頂点wを実行する。
[データ依存辺]
[ループ独立フロー依存辺: v→li x w]頂点vで代入された変数xの値を、頂点wで参照するような場合のデータ依存関係を表す。ここでは、ループを繰り越さない場合のみを表す。
[ループ繰り越しフロー依存辺: v→lc(L) x
w]頂点vで代入された変数xの値を、頂点wで参照するような場合のデータ依存関係を表す。ループLを繰り越す場合を表す。
[定義順序関係: v→do(u) x w]頂点v及び頂点wが変数xの値を代入し、頂点uで参照するような場合の、頂点vと頂点wの順序関係を表す。制御の流れによっては、v, w, u, あるいは、v, uの順に実行される可能性がある場合に、v, wの実行順序を表すものである。
以下において、縮退プログラム依存グラフを作成する処理(図1のステップS1の後半の処理)について説明する。上記のような一般的なプログラム依存グラフでは、文または代入式を頂点としたグラフとなっている。文または代入式を頂点とした場合、大規模なソフトウェアではグラフの頂点数が数千〜数万となってしまう。一般的に、コンパイラのグラフを用いた最適化の問題の計算量は、グラフの規模に対して指数関数的に増大することが知られている。したがって、例えば数個の手続きなどを対象とした頂点数が数十程度のグラフの場合には、解析が可能であるが、現実的な規模のソフトウェア全体に対する最適化は困難といえる。
そこで、プログラム依存グラフの頂点数及び辺数を低減すべく、プログラム依存グラフの依存関係を縮退して頂点を融合し、粗粒度のプログラム依存グラフを作成する。依存関係を縮退することによりグラフの規模を1/10〜1/100とすることで、現実的な時間にて、プログラムの最適化を可能にする。
依存関係の縮退は、次のような方法で、縮退可能な依存関係及び頂点の集合を求め、依存関係を削除して頂点を1つの頂点に融合することにより実行される。
1.構文規則に基づく縮退
一般にプログラム依存グラフから等価な逐次プログラムの制御の流れを再構成することは、困難と言われている。これは、制御の依存関係のみの表現となっているため、依存関係を満足する制御の流れは一意に決定できない上に、グラフを変形するような最適化を行なった場合、依存関係を満足するような制御の流れが存在しないような場合も出てくるためである。
しかし、表現するプログラムの制御構造を、if文、while文、及び、代入文に限定し、プログラム依存グラフの制御依存部分グラフ(頂点と制御依存辺のみで構成される部分グラフ)の形が木構造となる場合は、プログラムの制御の流れを再構成できることが知られている(非特許文献2)。そこで、プログラムにおけるif文、while文でない制御文に対して、入り口と出口がそれぞれ1つとなるようなプログラムのブロックを求める。ブロック全体とブロック内部の依存関係を1つの頂点に縮退することで、安全に制御の流れを再構成可能な範囲の縮退プログラム依存グラフを作成する。
2.結合度に基づく縮退
プログラム依存グラフを探索して、頂点間の結合の強さを求める。結合度は、データ依存辺とその大きさ、及び、制御依存辺、処理の大きさから計算されるものとする。ある結合度以上の頂点に対して、縮約可能な条件を満足する場合は、頂点を結合し依存関係を縮約する。ここで、次の2つ条件を満たすときに、頂点を結合しての縮約が可能となる。
1)プログラム依存グラフに対応するCFG(Control
Flow Graph:制御フローグラフ)上で頂点集合外から頂点集合内への分岐は頂点集合の先頭頂点へのみであり、頂点集合内から頂点集合外への分岐は頂点集合の最後の頂点のみである。
2)頂点間のデータ依存パスに外部の頂点が含まれない。
以上のようにして、「構文規則に基づく縮退」又は「結合度に基づく縮退」により、頂点数が大幅に削減された縮退プログラム依存グラフを生成することができる。縮退プログラム依存グラフは、次の要素から構成される。
[V:頂点集合]
エントリ:プログラムの開始ポイントを表す。
初期定義:プログラム開始時の初期値の定義を表す。
プリディケート: If-then-elseまたはwhile-loopの条件判定を表す。
文の集合: プログラムを構成する文の集合を表す。
最終使用:プログラム終了時の変数の参照を表す。
[E:辺集合]
[制御依存辺: v→c L w]プリディケート頂点vに対して、その条件判定結果により、頂点wに到達するか否かが決まることを表す。Lは条件判定のフラグを表し、L=Tのときは条件判定結果が真の場合に頂点wを実行し、L=Fのときは結果が偽の場合に頂点wを実行する。
[データ依存辺]
[ループ独立フロー依存辺: v→li x w]頂点vで代入された変数xの値を、頂点wで参照するような場合のデータ依存関係を表す。ここでは、ループを繰り越さない場合のみを表す。
[ループ繰り越しフロー依存辺: v→lc(L) x
w]頂点vで代入された変数xの値を、頂点wで参照するような場合のデータ依存関係を表す。ループLを繰り越す場合を表す。
[定義順序関係: v→do(u) x
w]頂点v及び頂点wが変数xの値を代入し、頂点uで参照するような場合の、頂点vと頂点wの順序関係を表す。制御の流れによっては、v, w, u, あるいは、v, uの順に実行される可能性がある場合に、v, wの実行順序を表すものである。
(2)並列実行方式:待ち付き制御付き非同期遠隔手続き呼び出しとデータ転送
集中制御方式の並列化プログラムを生成する方法として、例えば、手続を非同期の遠隔呼び出しとして呼び出すことにより並列にスレッドを実行する方式、手続に実行開始するメッセージを送信することにより並列にスレッドを実行する方式、スレッド間で共有メモリを利用して入出力変数の受け渡しを行なうことにより並列にスレッドを実行する方式等が考えられる。しかしこれらの方式では、第1の手続(スレッド)の実行結果を利用する第2の手続がある場合、第1の手続の終了を待つ命令とそれに続く第2の手続を実行する命令とを、他の手続の実行に要する時間などを見積もって、プログラム中の適当な場所に配置しておくことになる。この場合、第1の手続が予想以上に早く終了した場合などに、第2の手続を実行するまでに、不必要な待ち時間が発生してしまう。
図2は、無駄な待ち時間の発生について説明するための図である。図2において、プロセッサ0乃至プロセッサ3の4つのプロセッサが用いられる。プロセッサ0でスレッド制御プログラム1(各スレッドに対応する手続の実行及び終了待ちを制御するプログラム)を実行する。図2の例では、まずプロセッサ0から、プロセッサ1乃至プロセッサ3に対して手続A乃至Cの実行を順番に要求する(start A()〜start C())。その後プロセッサ0は、手続Aの終了を待って(wait A())、手続Aの実行結果を利用する手続Dの実行を要求する(start D())。その後、手続Bの終了を待って(wait B())、手続Bの実行結果を利用する手続Eの実行を要求する(start E())。更にその後、手続Cの終了を待って(wait C())、手続Cの実行結果を利用する手続Fの実行を要求する(start F())。
この例では、手続Cが終了してから手続Fの実行を要求するまでに待ち時間が発生している。これは、スレッド制御プログラム中において、手続Bの終了待ち合わせ(wait B())と手続Eの実行要求(start E())が、手続Cの終了待ち合わせ(wait C())と手続Fの実行要求(start F())よりも前に配置されているからである。このような命令配置順のために、手続Bが終了しないと、手続Cの終了待ち合わせ及び手続Fの実行要求が実行されないことになる。
このような命令配置は、手続Bが手続Cよりも早く実行が終了するであろうという見積もりに基づくものである。手続Cの方が手続Bよりも早く終了することが分かっていたならば、手続Cの終了待ち合わせ及び手続Fの実行要求を、手続Bの終了待ち合わせ及び手続Eの実行要求よりも前に配置することが考えられる。しかし実際には、手続の実行にかかる時間は処理データの内容等にも依存するので、終了時間を正確に見積もることは不可能である。従って、単純な遠隔手続呼び出し、共有メモリによるスレッド、メッセージ送信等の上記方式では、図2に示すような待ち時間を無くすことはできない。
本願の出願人は、非同期遠隔手続呼び出し方式として、並列化プログラムの各スレッドの実行を制御する際に、各手続毎に他の手続に対する依存関係を実行条件として指定し、各手続をプロセッサ毎の実行キューに投入し、実行条件が満たされた手続を実行していくという方式を既に提案している。このような方式を、依存関係待ち合わせ付き非同期遠隔手続呼び出し方式と呼ぶ。
図3は、依存関係待ち合わせ付き非同期遠隔手続呼び出し方式による手続実行の制御について説明するための図である。図3において、プロセッサ0乃至プロセッサ3の4つのプロセッサが用いられる。プロセッサ0でスレッド制御プログラム2(各スレッドに対応する手続きの実行及び依存関係を制御するプログラム)を実行する。この際プロセッサ0は、手続き呼出しプログラム3を実行することにより、スレッド制御プログラム2に規定される各手続きを各プロセッサ毎のキューを用いて管理する。
図3の例では、まず制御プログラム2の命令start A()に従って、プロセッサ1の実行キュー4に手続Aが投入される。また制御プログラム2の命令start B()に従って、プロセッサ2の実行キュー5に手続Bが投入される。更に制御プログラム2の命令start C()に従って、プロセッサ3の実行キュー6に手続Cが投入される。
同様に、制御プログラム2の命令start D()、start E()、及びstart F()に従って、実行キュー4乃至6にそれぞれ手続D、E、及びFが投入される。またスレッド制御プログラム2中のdep(x, y, …)は依存関係を指定する命令であり、手続Xの依存先が手続Y、・・・であることを示す。即ち、手続Xを実行するためには、手続Y、・・・の実行が終了している必要があることを示す。制御プログラム2の命令dep(D, A)に従って、プロセッサ1の実行キュー4中の手続Dに対して、依存先の手続がAであることが登録される。また制御プログラム2の命令dep(E, A, B)に従って、プロセッサ2の実行キュー5中の手続Eに対して、依存先の手続がA及びBであることが登録される。更に、制御プログラム2の命令dep(F, A, C)に従って、プロセッサ3の実行キュー6中の手続Fに対して、依存先の手続がA及びCであることが登録される。
このようにして各プロセッサ毎に設けた実行キューに投入されている手続を、キューの順番に従って対応するプロセッサで実行する。この際、依存先が登録されていない手続(図3においてNULLで示されている手続)については無条件に実行し、依存先が登録されている手続については、依存先の手続の終了を検出してから実行する。このようにプロセッサ毎にキューを設け、実行条件が満たされたキュー内の手続き(実行可能手続き)から順番に実行していくことで、図2に示したような待ち時間を無くすことができる。
以上説明したように、上記の依存関係待ち合わせ付き非同期遠隔手続呼び出し方式を用いれば、並列化プログラムの実行時における不要な待ち合わせ時間の発生を防ぐことができる。従って、大規模なソフトウェアを対象として、逐次プログラムを並列化することにより、マルチプロセッサ上で効果的に動作する非投機的な並列化プログラムを生成する際には、上記の依存関係待ち合わせ付き非同期遠隔手続呼び出し方式に適用可能な並列化プログラムを生成することが望ましい。
本願の出願人は、依存関係待ち合わせ付き非同期遠隔手続呼び出し方式に適用可能な並列化プログラム生成方法を既に提案している。この並列化プログラム生成方法では、まずプログラムの実行順序関係を計算し、分岐(IF、GOTO、LOOP等)や合流を含まない順番に実行される頂点の列である基本ブロックを求める。そして、同一の基本ブロック内部で依存関係がある手続きの実行については、依存関係待ち合わせ付き非同期遠隔手続呼び出しにより手続きを実行する。また、異なる基本ブロックをまたいでの手続き間の依存関係については、先行手続きの終了待ち合わせを行ってから、後続手続きを実行するようにしている。このような構成とすることで、複雑な制御の依存関係が存在する基本ブロック間については、手続きの実行を待ち合わせにより実現することで制御プログラムの生成を容易なものとし、また実行順が固定である同一基本ブロック内については、依存関係待ち合わせ付き非同期遠隔手続呼び出しにより無駄な待ち合わせ時間をなくすことができる。
ここでは、処理間の依存関係のみに着目しているが、分散メモリ環境の場合には、プロセッサ間の入出力データの転送を行なう必要がある。データ転送についても、同様の実行キューを用いて制御することで、データ転送間、あるいは、データ転送と手続きの間の依存関係に基づいて並列実行をさせることができる。
(3)データ転送制御方式:データ転送制御情報と制御関数
制御の流れによって、手続き間データ転送の転送元が変化する場合がある。また先行ループにおいて必要なデータの転送が完了する前に、次ループの処理がこのデータを上書きしてしまう可能性がある場合がある。そのような場合に、適切な転送元からのデータ転送及び上書きを防ぐための待ち合わせによるデータ転送を実現するために、データ転送制御情報と制御関数とが必要になる。
例えば、図4のようなプログラムを並列化して実行する場合を考える。この際、例えばプロセッサエレメントPE0が初期値代入「x=1;y=0」及びwhile文を実行し、プロセッサエレメントPE1が「y=f(x)」を実行し、プロセッサエレメントPE2が「z=g(y)」を実行するとする。PE2により実行する「z=g(y)」の入力変数yは、ループの判定結果に依存して、PE1により実行される「y=f(x)」の結果となる場合と、PE0により設定される初期値「y=0」となる場合がある。即ち、制御の流れによって、手続き間データ転送の転送元が変化する。
無駄なデータ転送を避けるためには、データ転送はそのデータが実際に必要となる直前に転送することが望ましい。即ち、データ変数yについては、「z=g(y)」を実行する直前にデータ転送することが望ましい。そのような直前のデータ転送を実現するためには、上記のように手続き間データ転送の転送元が変化することを考慮して、転送元データのアドレスを制御の流れに従って管理する必要がある。
また待ち時間を削減するためには、転送元「y=f(x)」の手続きの完了を待ち合わせて「z=g(y)」を実行することが望ましい。従って、転送元の識別子も管理する。
また「z=g(y)」を起動後に、処理が再度内側のループ(while(P)のループ)の実行に入ったとする。この場合、起動中の「z=g(y)」が入力yとして必要とする「y=f(x)」のデータが手続「z=g(y)」へデータ転送される前に、次のループの「y=f(x)」が実行されて、必要なデータyが上書きされてしまう可能性がある。そこで、データの転送状況を制御情報として管理し、データ転送状況がデータ転送予約に設定されると、データ転送が完了するまでは上書きをするような手続きの実行を抑制するように管理する。
具体的には、データ転送制御情報として、
・転送元データのアドレス;
・転送元遠隔手続き呼び出しの識別子;
・データの転送状況(未転送、転送予約、転送済) ;
・データ転送の識別子;
を用いることになる。データ転送状況が「未転送」であれば、転送先の手続きの実行が未確定であって、データの転送が行なわれていない状態を示す。「転送予約」であれば、転送先の手続きの実行が確定し、データ転送が指示されている状態を示す。ただし、データ転送が完了しているかどうかは不明である。「転送済」であれば、手続きへのデータ転送が完了した状態を示す。この場合、次回の転送先手続き実行に対応する新たな値は定義されていない。
またデータ転送制御関数としては、
・wait_for_use
(self, f);
・wait_for_def_and_move(self)
・regist_dependence(self,
id)
・def_data(self,
f, addr)
を用いる。ここで“self”は、手続きgの入力yに関するデータ転送制御情報を表す構造体である。
図5は、データ上書き抑制のための待ち合わせ制御を行なう関数wait_for_use (self, f)の内容を示す図である。上記の例(図4の例)のように手続きfの出力データを使用(参照)する手続きgがある場合に、手続きgが、前回の手続きfの結果を必要としている場合、手続きgへのデータ転送を待ち合わせる。具体的には、転送元の手続が「f」で転送状況が「転送予約」の場合に、データ転送識別子(前回の手続きfの結果を転送する処理の識別子)が示すデータ転送を待ち合わせ、その後、転送状況を「転送済」にする。データ上書きをする可能性がある次回の手続fは、転送状況が「転送済」になってから実行すればよい。この関数を用いることにより、データ上書きを回避することができる。
図6は、参照データ取得のための待ち合わせ制御関数wait_for_def_and_move(self)の内容を示す図である。手続きgの入力データを定義(代入)する手続きfを待ち合わせ、手続fが終了するとデータ転送を指示する。具体的には、転送状況が「未転送」であり且つ転送元の手続の識別子がある(fがφでない)場合、「転送元遠隔手続き呼び出し識別子」が示す転送元の手続fが終了するのを待ち合わせる。転送元の手続fが終了すると、転送状況を「転送予約」に設定し、「転送元アドレス」から当該PEへの転送動作「move」を開始する。またデータ転送識別子としては転送動作「move」を識別する値が設定される。
図7は、データ転送が行なわれる場合にデータ転送から手続への依存関係を登録する関数regist_dependence(self, id)の内容を示す図である。ここで識別子idは、例えば上記の例であれば手続gを示す値である。具体的には、転送状況が「転送予約」である場合に、手続gの実行はデータ転送識別子が示すデータ転送に依存すること、即ち入力変数yがデータ転送されて初めて手続gが実行可能であることを登録する。依存関係を登録する関数がdepend()である。
図8は、手続きで参照するデータについて値の代入に関する情報を登録する関数def_data(self, f, addr)の内容を示す図である。手続きgで参照するデータはyであり、この値を持っているのは手続きfであり、転送するデータのアドレスはaddrである。従って、「転送元遠隔手続き呼び出し識別子」として手続きfの識別子を登録し、更に「転送元アドレス」として変数yのアドレスaddrを登録する。
(4)並列プログラム生成手法:遠隔手続き呼び出し用変数生成方法
実行するマルチプロセッサシステムが分散メモリの場合、手続きへの入出力データをプロセッサ上のメモリ領域に転送し、プロセッサがその領域を用いて計算を行ない、結果を他の適切な領域に転送することになる。この場合のデータ変数の割り付け方としては、1)プロセッサ毎に使用する可能性のある変数の複製領域を作成する方式と、2)手続き毎に使用する可能性のある変数の複製領域を作成する方式とが考えられる。プロセッサ毎に変数の複製領域を作成する方式では、同一のプロセッサが実行する第1の手続きと第2の手続きとが同一の変数xを使用する場合、このプロセッサのメモリ領域には1つの変数xの領域しか設けない。また手続き毎に変数の複製領域を作成する方式では、同一のプロセッサが実行する第1の手続きと第2の手続きとが同一の変数xを使用する場合、このプロセッサのメモリ領域には第1の手続きの変数xの領域と第2の手続きの変数xの領域とをそれぞれ別個に設ける。また更に、両方式の組み合わせとして、3)プロセッサ毎に使用する可能性のある変数の複製領域を作成し、逆依存関係又は出力依存関係による待ち合わせが発生する場合は、手続き毎の異なる領域を作成する方式が考えられる。これら第1乃至第3の方式において、同一の変数に対する複製領域の各々について、異なる名前を付けて区別する。
逆依存関係は、第1の命令においてある変数の値が使われた後に第2の命令においてその変数が定義される可能性がある場合に対応し、第1の命令から第2の命令に逆依存関係が存在すると言う。また出力依存関係は、第1の命令においてある変数の値が定義された後に第2の命令においてその変数が定義される可能性がある場合に対応し、第1の命令から第2の命令に出力依存関係が存在すると言う。何れの関係においても、第2の命令を実行してから第1の命令を実行するように実行順序を逆にすることはできない。本発明では、データ転送を遅らせることにより制御が複雑化するので、逆依存/出力依存関係が発生しない上記2)又は3)の方式を用いる。
以下において、変数生成方法の第1の実施例として、2)手続き毎に使用する可能性のある変数の複製領域を作成する方式により変数を生成する方法について説明する。
図9は、変数生成方法の第1の実施例である手続き毎に変数を生成する処理のフローチャートを示す図である。図9に示す処理は、図1のステップS2の処理に相当する。
ステップS1で、縮約したプログラム依存グラフの各頂点vについて以降の処理を繰り返すループを開始する。
ステップS2で、着目頂点vがプログラム・ブロック頂点の場合、その頂点の手続きを実行するプロセッサに対して、既にその頂点(手続き)に対応する変数を作成済みか否かを判定する。実行するプロセッサについて変数が作成済みの場合はステップS4に進む。実行するプロセッサについて変数が未作成の場合は、ステップS3で変数を作成し、その後ステップS4に進む。
ステップS4で、変数の名前を付けかえる。即ち、例えばプロセッサPE1に手続きP1の変数xを作成してある場合、この変数xがプロセッサPE1の手続きP1の変数xであることを示すような変数名(例えばPE1_P1_x)に変更する。以上の処理を、縮約したプログラム依存グラフの各頂点について実行する。その後、ステップS5で、依存関係を抽出する。
次にステップS6で、頂点間の実行順序関係を計算し、求めた実行順序(制御の流れ)から基本ブロックを抽出する。
上記のように手続き毎に変数を作成することにより、全ての逆依存関係及び出力依存関係が削除されることになる。従って、逆依存関係及び出力依存関係については抽出する必要がない。
図10は、頂点間の実行順序関係を決定する方法を示すフローチャートである。図10の処理は、図9のステップS6の前半部分に相当する。図10に示す処理の入力は縮退したプログラム依存グラフPDGであり、出力は縮退したプログラム依存グラフPDG及びその制御の流れである。
ステップS1で、縮退したプログラム依存グラフPDGのエントリ頂点(プログラムの開始ポイント)をvとする。ステップS2で、頂点v以下の制御の流れを再構成する。以上で処理を終了する。
図11は、頂点v以下の制御の流れを再構成する処理(図10のステップS2)を示すフローチャートである。図11の処理の入力は、縮退したプログラム依存グラフPDG及び頂点vである。
ステップS1で、Region(v, T) = {u | u ∈ V, v→c Tu
∈ E}が空集合であるか否かを判断する。空集合であれば処理を終了し、空集合でなければステップS2に進む。ここでRegion(v, T)とは、頂点uの集合であって、頂点vから頂点uへのL=Fの制御依存関係が存在するものである。ここでVは頂点集合、Eは辺集合、v→c TuはL=Fの制御依存辺を示すものである。
ステップS2で、Region(v, T)の実行順序関係を計算する。ステップS3で、Region(v, F) = {u | u ∈ V, v→c Fu
∈ E}が空集合であるか否かを判断する。空集合であれば処理を終了し、空集合でなければステップS4に進む。ここでRegion(v, F)とは、頂点uの集合であって、頂点vから頂点uへのL=Fの制御依存関係が存在するものである。以上で処理を終了する。
図12は、Regionの実行順序関係を計算する処理を示すフローチャートである。この処理は、図11のステップS2及びステップS4の各々に対応する。図12の処理の入力は、縮退したプログラム依存グラフPDG及びV’(着目Region)である。
ステップS1で、着目領域V’の各頂点vについて、ステップS2乃至S3の処理を繰り返すループを開始する。ステップS2で、vがプレディケート頂点(If-then-else又はwhile-loopの条件判定を表す頂点)であるか否かを判断する。vがプレディケート頂点である場合のみ、ステップS3を実行する。ステップS3で、頂点v以下の実行順序関係を計算する。
次に、ステップS4で、逆依存及び出力依存を求める。ここでは制御の流れに起因するデータ依存関係(逆依存、出力依存)を抽出する。具体的には、着目領域(Region)を越えるデータ依存関係から、着目領域内の逆依存及び出力依存を表出する。
次に、ステップS5で、逆依存及び出力依存を求める。ここでは着目領域(Region)内の実行順序を決定する。即ち、実行順序が一意に定まらないRegion内頂点の集合について適切な実行順序制約を決定する。具体的には、求められた逆依存関係や出力依存関係などによる実行順序制約をもとに、Region内の逆依存関係や出力依存関係を明らかにして、実行順序を決定する。実行順序が任意となる場合は、実行順序を仮定して逆依存関係、出力依存関係を求め、矛盾が起きない実行順序が得られるまで試行を繰返す。
最後にステップS6でスケジューリングを行う。即ち、上で求めた実行順次関係に基づいて頂点の実行順を決定する。これは、半順序関係の成立するグラフのスケジューリングという一般的な問題に帰着できる。従って、トポロジカル・ソートや、頂点の実行時間の概算を重みとしたリスト・スケジューリングなどのよく知られたスケジューリング手法を適用することができる。この際、各頂点の各PE(プロセッサエレメント)への割り付けも行われる。
図13は、逆依存及び出力依存を求める処理(図12のステップS4)を示すフローチャートである。図13の処理の入力は、縮退したプログラム依存グラフPDG及びV’(着目Region)である。
ステップS1で、着目領域V’を越える変数参照を抽出してVdefとする。ステップS2で、着目領域V’を越える変数代入を抽出してVuseとする。ステップS3で、Vuse及びV’に基づいて逆依存辺を追加する。ステップS4で、Vdef及びV’に基づいて出力依存辺を追加する。以上で処理を終了する。
図14は、着目領域を越える変数参照を抽出する処理を示すフローチャートである。図14の処理は図13のステップS1に相当し、縮退したプログラム依存グラフPDG及びV’(着目Region)を入力とする。
ステップS1で、頂点の集合Vuseを空にする。ステップS2で、着目領域V’内の各フロー依存辺について以降の処理を繰り返すループを開始する。ここでフロー依存辺としては、ループ独立フロー依存辺とループ繰り越しフロー依存辺とを含む。ステップS3で、フロー依存辺eの依存元頂点をuとするとともに、辺eの依存先頂点をvとする。
ループ繰り越しフロー依存辺である場合には、ステップS4で、依存先頂点vが着目領域V’に含まれるという条件が満たされるか否かを判定する。またループ独立フロー依存辺である場合には、ステップS5で、依存元頂点uが着目領域V’に含まれず且つ依存先頂点vが着目領域V’に含まれるという条件が満たされるか否かを判定する。この判定結果がyesの場合のみ、ステップS6を実行する。ステップS6で、頂点の集合Vuseに依存先頂点vを追加する。
最後に、ステップS7で、頂点の集合Vuseを値として返す。以上で処理を終了する。
図15は、着目領域を越える変数代入を抽出する処理を示すフローチャートである。図15の処理は図13のステップS2に相当し、縮退したプログラム依存グラフPDG及びV’(着目Region)を入力とする。
ステップS1で、頂点の集合Vdefを空にする。ステップS2で、着目領域V’内の各フロー依存辺について以降の処理を繰り返すループを開始する。ここでフロー依存辺としては、ループ独立フロー依存辺とループ繰り越しフロー依存辺とを含む。ステップS3で、フロー依存辺eの依存元頂点をuとするとともに、辺eの依存先頂点をvとする。
ループ繰り越しフロー依存辺である場合には、ステップS4で、依存先頂点vが着目領域V’に含まれるという条件が満たされるか否かを判定する。またループ独立フロー依存辺である場合には、ステップS5で、依存元頂点uが着目領域V’に含まれ且つ依存先頂点vが着目領域V’に含まれないという条件が満たされるか否かを判定する。何れかの判定結果がyesの場合のみ、ステップS6を実行する。ステップS6で、頂点の集合Vdefに依存先頂点vを追加する。
最後に、ステップS7で、頂点の集合Vdefを値として返す。以上で処理を終了する。
図16は、逆依存の追加処理を示すフローチャートである。図16の処理は図13のステップS3に相当し、縮退したプログラム依存グラフPDG、V’(着目Region)、及び頂点集合Vuseを入力とする。
ステップS1で、頂点集合Vuseの各頂点vに対して以降の処理を繰り返すループを開始する。ステップS2で、頂点vで使用する各変数xに対して以降の処理を繰り返すループを開始する。ステップS3で、着目領域V’の各頂点uに対して以降の処理を繰り返すループを開始する。
ステップS4で、頂点uが変数xを定義するか否かを判定する。判定結果がyesの場合のみ、ステップS5を実行する。ステップS5において、vからuへの逆依存辺を追加する。以上で処理を終了する。
図17は、出力依存の追加処理を示すフローチャートである。図17の処理は図13のステップS4に相当し、縮退したプログラム依存グラフPDG、V’(着目Region)、及び頂点集合Vdefを入力とする。
ステップS1で、頂点集合Vdefの各頂点uに対して以降の処理を繰り返すループを開始する。ステップS2で、頂点uで使用する各変数xに対して以降の処理を繰り返すループを開始する。ステップS3で、着目領域V’の各頂点vに対して以降の処理を繰り返すループを開始する。
ステップS4で、頂点vが変数xを定義するか否かを判定する。判定結果がyesの場合のみ、ステップS5を実行する。ステップS5において、vからuへの出力依存辺を追加する。以上で処理を終了する。
図18は、逆依存及び出力依存を求める処理(図12のステップS5)を示すフローチャートである。図18の処理の入力は、縮退したプログラム依存グラフPDG及びV’(着目Region)である。
ステップS1で、着目領域内の全域木を求めSとする。変数xを定義する頂点vとその変数xを使用するRegionR内の頂点との集合として、頂点vの変数xに関する全域木が、
Span(v,
x) = {v}∪{u| v→li xu ∈ ER}
と定義される。図19は、全域木を説明するための図である。図19に示されるプログラム依存グラフにおいて、頂点viにおいて変数xが定義され、2つの頂点v1及びv2が変数xを使用する。この場合、頂点vi、v1、及びv2で全域木21を形成する。また頂点vjにおいて変数xが定義され、2つの頂点v3及びv4が変数xを使用する。この場合、頂点vj、v3、及びv4で全域木22を形成する。図20は、全域木を模式的に示す図である。全域木Span(vi, x)及び全域木Span(vj, x)が、データ依存グラフとして図20に示されるように構成される。
図18に戻り、ステップS2で、実行順が未決定である2つの任意の全域木を順次選択して以降の処理を繰り返すループが開始される。ステップS3で、着目領域に閉路がなく、同一変数xに対する独立した全域木Span(h0,x)及びSpan(h1,x)が存在するか否かを判定する。ここで、「独立した」とは、2つの全域木 Span(h0,x)及びSpan(h1,x)について、Span(h0,x)に含まれる頂点とSpan(h1,x)に含まれる頂点との間に辺(依存関係)がないことを言う。
ステップS4でR(Region)のオリジナルをスタックに退避させる。ステップS5で、h0→h1の出力依存辺を追加し、推移閉包を求める。ステップS6で、全域木間の順序関係を計算する。
ステップS7で、R(Region)に閉路が存在するか否かを判定する。存在しない場合には、以降の処理ステップS8〜ステップS11をスキップする。存在する場合には、ステップS8に進む。ステップS8で、スタックが空か否かを判断する。空の場合にはエラー終了する。空でない場合には、ステップS9で、Rのオリジナルをスタックから取り出す。
以上の処理は、頂点h0からh1への出力依存関係をグラフに追加したときに、巡回グラフとならない場合には追加した依存関係を確定させ、巡回グラフになった場合には元のグラフに戻すことに相当する。元のグラフに戻した後は、以降に示すように、頂点h1からh0への出力依存関係をグラフに追加する。即ち、ステップS10で、h1→h0の出力依存辺を追加し、推移閉包を求める。ステップS11で、全域木間の順序関係を計算する。
以上の処理により、2つの全域木 Span(h0,x)及びSpan(h1,x)に対する実行順序が決定する。更に、実行順が未決定である2つの任意の全域木を順次選択して同様の処理を繰り返し、全ての全域木間の順序関係が決定されたところで終了する。
図21は、全域木間の順序関係を計算する処理を示すフローチャートである。図21の処理は、図18のステップS6及びステップS11に相当する。図21の処理の入力は、縮退したプログラム依存グラフPDG及びV’(着目Region)である。
ステップS1で、着目領域内の各辺e(頂点v→頂点w)について以降の処理を繰り返すループを開始する。ステップS2で、頂点wで定義され、頂点vで参照される各変数xについて以降の処理を繰り返すループを開始する。
ステップS3で、Va ← { u | v ∈ Span(u, x) }とするとともに、Vb ← { u | w ∈ Span(u, x) }とする。これは、頂点vを要素として含む変数xに関する全域木における変数xを定義する頂点の集合を求めるとともに、頂点wを要素として含む変数xに関する全域木における変数xを定義する頂点の集合を求めることである。
ステップS4で、Vaの各頂点vaについて以降の処理を繰り返すループを開始する。ステップS5で、Vbの各頂点vbについて以降の処理を繰り返すループを開始する。更にステップS6で、Span(va, x)の頂点であってSpan(vb, x)の頂点でない各頂点vcについて以降の処理を繰り返すループを開始する。
ステップS7で、vc→vbがE(辺集合)に含まれるか否かを判定する。判定結果がyesの場合のみステップS8を実行する。ステップS8で、vc→vbの逆依存辺を追加し、推移閉包を求める。以降、各ループの処理を繰り返す。
図22は、図21の処理による逆依存辺の追加について説明する図である。図22には、頂点vの変数xに関する全域木Span(v,x)と頂点wの変数xに関する全域木Span(w,x)とが示される。頂点vを要素として含む変数xに対する全域木Span(va, x)(即ちSpan(v,x))の各頂点vc(即ちv、25、26)に対して、全域木Span(vb, x)(即ちSpan(w,x))のヘッドvb(変数を定義している頂点w)への逆依存辺32、33を追加する。
図23は、基本ブロックを抽出する処理のフローチャートを示す図である。図23に示す処理は、図9のステップS6の後半部分の処理に相当する。図23の処理の入力は、実行順序関係が決定された縮退したプログラム依存グラフである。
制御の流れとして求めた半順序関係を、トポロジカル・ソートや、リスト・スケジューリングなどの手法を用いてPEに割り付けソートする。ソートした順(求めた制御の流れの順)に頂点を探索し、頂点の種類に応じた処理を行なう。以下の説明においてBは基本ブロックの集合であり、Biはi番目の基本ブロックである。またvは現在の頂点(着目頂点)であり、uは現在の頂点の1つ前の頂点である。
まずステップS2で、最初の基本ブロックB0を空集合として生成する。次にステップS2で、uをエントリ頂点(プログラムの開始ポイント)として、vをエントリ頂点の次の頂点とする。ステップS4で、現在の頂点vが最終頂点であるか否かを判断する。最終頂点である場合には、処理を終了して基本ブロックの集合Bが生成される。
現在の頂点vが最終頂点でない場合には、ステップS5に進み、現在の頂点vがプレディケート頂点(If-then-else又はwhile-loopの条件判定を表す頂点)であるか否かを判断する。プリディケート頂点である場合には、ステップS6に進み、iをインクリメントしてからBiの要素をvとすることで、新たなプリディケートのみの基本ブロックBiを形成する。その後ステップS7で、更にiをインクリメントして、新たな空集合の基本ブロックBiを形成する。
現在の頂点vがプレディケート頂点でない場合(S5でNoの場合)には、ステップS8で、現在の頂点vと1つ前の頂点uとが、同一のプレディケート頂点からの制御依存関係を有し、且つその制御依存関係が同一の条件判定フラグに基づくものであるか否かを判定する。この判定結果がNOとなるのは、例えばuとvとが、IF文の内部と外部とに対応する場合や、IF文のTHEN節とELSE節とに対応する場合等である。即ち、ステップS8においては、同一の条件判定に応じて双方共に実行される2つの頂点であるか否かが判定されている。
ステップS8の判定がYESの場合には、ステップS9で、現在の基本ブロックに現在の頂点vを追加する。ステップS8の判定がNOの場合には、ステップS10で、iをインクリメントして新たな空集合の基本ブロックBiを形成する。その後ステップS11で、この新たに生成された基本ブロックBiに現在の頂点vを追加する。その後ステップS12でuとvとをそれぞれ次の頂点に更新し、ステップS4に戻り以降の処理を繰り返す。
以上の処理により、分岐(IF、GOTO、LOOP等)や合流を含まない順番に実行される頂点の列である各基本ブロックBiを生成し、これらの基本ブロックを要素とする基本ブロックの集合Bを生成することができる。分岐や合流を含まない頂点の列とは、固定の1つの実行順に従い順番に実行される頂点の列のことである。図23のフローチャートから分かるように、各プレディケート頂点は単独で1つの基本ブロックBiを構成し、プレディケート頂点でない1つの基本ブロックBiには、途中で分岐も合流もなく固定の1つの実行順に従い順番に実行される頂点の列が含まれることになる。
本発明では、異なる基本ブロックをまたいでの手続き間の依存関係については、先行手続きの出力データ転送の終了待ち合わせを行ってから、後続手続きを実行するようにする。また同一の基本ブロック内部で依存関係がある手続きの実行については、依存関係待ち合わせ付き非同期遠隔手続呼び出しにより手続きを実行する。即ち、基本ブロック間をまたいでの依存関係がある手続きについては先行手続きの出力データ転送を待ち合わせる命令の後に後続手続きを実行する命令を配置することにより、依存関係を満たすように手続き制御する。また同一の基本ブロック内部で依存関係がある手続きについては後続手続きの先行手続きの出力データ転送への依存関係を明示的に登録する命令を生成するようにして、依存関係を満たすように手続き制御する。このような構成とすることで、複雑な制御の依存関係が存在する基本ブロック間については、手続きの実行を待ち合わせにより実現することで制御プログラムの生成を容易なものとし、実行順が固定である同一基本ブロック内については、依存関係待ち合わせ付き非同期遠隔手続呼び出しにより無駄な待ち合わせ時間をなくすことができる。
以上により、基本ブロックを抽出することができる。即ち、図9のステップS6の後半部分の処理が実行される。
以下において、変数生成方法の第2の実施例として、3)プロセッサ毎に使用する可能性のある変数の複製領域を作成し、逆依存関係又は出力依存関係による待ち合わせが発生する場合は、手続き毎の異なる領域を作成する方式により変数を生成する方法について説明する。
図24は、変数生成方法の第2の実施例である必要に応じてプロセッサ毎又は手続き毎に変数を生成する処理のフローチャートを示す図である。図24に示す処理は、図1のステップS2の処理に相当する。
まずステップS1で、頂点間の実行順序関係を計算し、求めた実行順序(制御の流れ)から基本ブロックを抽出する。縮退したプログラム依存グラフは、データ及び制御の依存関係のみを表現したグラフであって頂点間の実行順序は明示されていないので、これから適切な制御の流れを再構成する必要がある。そこで、縮退したプログラム依存グラフの制御依存部分木について、各中間節点の子頂点の実行順序を計算する。この結果、頂点間の半順序関係を求めることができる。この実行順序関係を用いて、制御プログラムを生成することとなる。またその課程において、逆依存関係、出力依存関係が抽出される。更に、求めた実行順序(制御の流れ)から、基本ブロックを抽出する。この処理は、第1の実施例において説明した図9のステップS6と同一の処理である。
ステップS2で、縮約したプログラム依存グラフの各頂点vについて以降の処理を繰り返すループを開始する。
ステップS3で、着目頂点vがプログラム・ブロック頂点の場合、その頂点の手続きを実行するプロセッサに対して、既にその頂点(手続き)に対応する変数を作成済みか否かを判定する。実行するプロセッサについて変数が作成済みの場合はステップS5に進む。実行するプロセッサについて変数が未作成の場合は、ステップS4で変数を作成し、その後ステップS5に進む。
ステップS5で、変数の名前を付けかえる。即ち、例えばプロセッサPE1に変数xを作成してある場合、この変数xがプロセッサPE1の変数xであることを示すような変数名(例えばPE1_x)に変更する。以上の処理を、縮約したプログラム依存グラフの各頂点について実行する。
その後、ステップS6で、全ての逆依存関係及び出力依存関係を探索して、各依存関係に対して以下の処理を繰り返し実行する。
ステップS7で、着目している依存関係(逆依存関係又は出力依存関係)が、ステップS4の変数名変更により解消されているか否かを判断する。依存関係が解消されているものについては、その依存関係を削除する。依存関係が解消されていない場合(未解決の場合)は、ステップS7で、処理を実行するプロセッサ上に、着目依存関係に対応する手続きの変数を複製して作成し、その後ステップS8に進む。
変数xに関する逆依存関係v→anti x wが未解決となる条件は、次の2通りである。
第1条件:PE(v)=PE(w)
第2条件:∃ u∈V w→f x u∈E かつ PE(v)=PE(u)
ここでPE(v)は頂点vが実行されるプロセッサPEを表し、上記第1の条件では、逆依存関係にある頂点vとwが同一のプロセッサPEに割り付けられていることを示している。頂点vとwが、同一PEであるPEiに対して割り付けられているため、PEiの変数xに関して逆依存関係となる。頂点vとwで異なる変数を使うように変数を複製することとなる。例えば、頂点wの変数をx’に変更することが考えられる。
上記第2の条件では、頂点wで代入された値が、頂点uで参照される場合を示している。頂点vと頂点uが同一のPEであるPEi に割り付けられているとすると、頂点wで代入された値が頂点uで参照するために、PEiの変数xに転送されることとなる。これを解決するために、頂点vとuで異なる変数を使うように変数を複製することとなる。例えば、頂点uの変数をx’に変更することが考えられる。
変数xに関する出力依存関係v→output x wが未解決となる条件は、次の2通りである。
第1条件:PE(v)=PE(w)
第2条件:¬∃u∈V w→f x
u∈E PE(v)=PE(u)
上記第1条件では、頂点vとwが、同一PEであるPEiに対して割り付けられているため、PEiの変数xに関して出力依存関係となる。頂点vとwで異なる変数を使うように変数を複製することとなる。例えば、頂点wの変数をx’に変更することが考えられる。
上記第2の条件では、頂点wで代入された値が、頂点uで参照されることを想定する。ここで、頂点vと頂点uが同一のPEであるPEi に割り付けられているとすると、頂点wで代入された値が頂点uで参照するためにPEiの変数xに転送されることとなる。頂点vにおける変数xへの代入と衝突するため、これを解決するには頂点vとuで異なる変数を使うように変数を複製することとなる。例えば、頂点uの変数をx’に変更することが考えられる。
なお、定義順序関係に相当する場合は、定義順序関係として扱い、出力依存関係は削除するものとする。
ステップS9で、変数の名前を付けかえる。即ち、例えばプロセッサPE1に手続きP1の変数x及び手続きP2の変数xを作成してある場合、これらの変数の変数名を例えばPE1_P1_x及びPE1_P2_xのように各プロセッサ及び各手続きに固有の名前に変更する。以上の処理を、各逆依存関係及び出力依存関係について実行する。
(5)並列プログラム生成手法:制御プログラム生成方法
上記説明したような図1のステップS2の変数生成処理により、変数の生成、プログラムの実行順序関係の計算、および、基本ブロックの抽出が完了している。このようにして求められた実行順序関係と基本ブロックとに基づいて制御プログラムを生成する。各中間節点が表す制御構造と子頂点が表す「手続き」の呼び出しを行なうプログラムを生成することで、並列プログラムを生成する「手続き」を実行する上で必要となる入力および出力データの送受信と待ち合わせを行なうコードも生成する。基本ブロック内の手続き呼び出しおよびデータ転送の依存関係に関しては、依存関係待ち合わせのメカニズムを用いて制御し、データ転送の制御には、データ転送の制御方式を用いる。
図25は、手続き制御プログラムの構造を示す図である。
図25に示されるように、制御プログラムは、変数の宣言初期化部分41、プレディケートへの入力データ待合わせ部分42、プレディケートの制御構造43、基本ブロックの出力データ転送完了待ち合わせ部分44、基本ブロックへの入力データ転送指示部分45、基本ブロック内の手続呼び出しと依存関係登録部分46、及び、手続き及びデータ転送の待ち合わせ終了処理部分46を含む。基本ブロック内の手続呼び出しと依存関係登録部分46では、非同期遠隔手続き呼び出しの起動指示、基本ブロック内のデータ転送指示、出力データ転送情報の登録、依存関係の登録、手続きのディスパッチ(実行開始)を行う。
データを参照する箇所とデータを上書きする可能性のある箇所について、データ転送指示とデータ転送完了待ち合わせそれぞれ行なう。つまり、条件判定を行なうプレディケート頂点について、参照する変数のデータ転送を指示し、待ち合わせる。また、手続きの実行によって未転送のデータを上書きすることがないように前ループでの出力データ転送を待ち合わせる。その後、基本ブロック内の手続きを実行するために必要なデータの転送、遠隔手続き呼び出しの起動、基本ブロック内のデータ転送を指示し、依存関係を登録し、実行を開始する。プログラムの最後では、処理の結果を得るべく、遠隔手続き呼び出しの出力データを制御プロセッサに転送させ、終了処理を行なう。
まず手続きプログラムの生成について説明する。縮退プログラム依存グラフの頂点は、入力逐次プログラムの文の部分集合であって、文の間の制御の流れの情報を有している。従って、着目する1つの頂点へのデータフロー入力辺が表す変数を入力とし、データフロー出力辺が表す変数を出力とする、1つの手続きプログラムを1つの頂点に対して生成する。また、制御の流れより手続きプログラムの本文を、また、本文の実行に必要な局所変数をそれぞれ生成する。
図26は、手続きプログラム生成方法の概要を示す図である。図27は、図26の手続きプログラム生成方法により生成される手続きプログラムを示す図である。
図26のステップS1において、着目頂点についてデータフロー入力辺が表す変数を入力として、入力変数を引数として受信するためのプログラム部分を生成する。これにより、図27に示す入力変数の引数受信部分10が生成される。ステップS2において必要な変数を探索する。更にステップS3において、探索により見つかった変数について変数宣言を生成する。これにより、図27に示す変数宣言部分11が生成される。
ステップS4において、着目頂点の文の間の制御の流れの情報に基づいて、プログラムの本文を生成する。これにより、図27に示すプログラム本体部分12が生成される。ステップS5において、着目頂点のデータフロー出力辺が表す変数を出力として返すためのプログラム部分を生成する。これにより、図27に示す出力変数のセット部分13が生成される。
このように、手続きプログラムとしては、頂点が表す文/文の集合を実行する手続きとする。また、入力変数を手続きの引数とし、出力変数を復帰値あるいは、出力変数を格納するアドレスを引数として受け取るような手続きを作成する。
次に手続き制御プログラムの生成について説明する。非特許文献2に記載される技術に基づいて、縮退したプログラム依存グラフから制御の流れを安全に再構成することができる。具体的には、縮退したプログラム依存グラフの制御依存部分木について、プログラムの実行順序関係を計算し、基本ブロックを求める。基本ブロックとは、分岐(IF、GOTO、LOOP等)や合流を含まない順番に実行される頂点の列のことを言う。各中間節点が表す制御構造と子頂点が表す「手続き」の呼び出しを行なうプログラムを生成することで、並列プログラムを生成することができる。「手続き」を実行する上で必要となる入力データのデータ転送および出力結果のデータ転送とそれらの待ち合わせを行なうコードも生成する。基本ブロック内の手続き呼び出しおよびデータ転送の依存関係に関しては、依存関係待ち合わせのメカニズムを用いて制御する。
本発明によるプログラムの実行は、図3に示されるのと同様に、手続要求側プロセッサ(制御プロセッサ)により制御プログラムを実行し、この制御プログラムが呼び出す各手続きの手続きプログラムを各手続実行側プロセッサにより実行する。各手続きプログラムは、前述のように、頂点が表す文/文の集合を実行する手続きである。手続き呼び出し及び依存関係の登録と手続きの実行とについては、図3に示した仕組みと同様であり、制御プロセッサにおいて手続き呼出しプログラム3が管理する各プロセッサ毎のキューに手続きと依存関係とを登録し、実行可能状態となった手続きを順次実行していく。
手続きの入力データは、制御プロセッサから実行するプロセッサに転送する。但し、先行する手続きの結果を利用する場合には、手続きを実行したプロセッサから後続の手続きを実行するプロセッサに対して直接データを転送することとする。これは、元の逐次プログラムにおける条件判定に相当する、制御プログラム上の条件判定結果によっては、複数データのうち適切なデータを選択することが必要となる場合がある。このようなデータ選択は、データ転送の依存関係として制御することになる。
図28は、手続き制御プログラムの生成方法を示すフローチャートである。ステップS1で、制御プログラムの変数と初期値代入文を生成する。ここで変数としては、データの受け渡しを行うための変数を生成する。また、遠隔手続き呼び出しおよびデータ転送の識別する変数、および、データ転送制御の変数を生成する。分散メモリ環境を想定しているため、手続きを実行するプロセッサ上のメモリ領域上の外部変数の宣言を生成することとなる。データ転送制御の変数は、各遠隔手続き呼び出しの入力変数、および、プリディケート頂点の入力変数について、それぞれ作成する。
次にステップS2で、求めた実行順序順に制御依存部分グラフを探索し、制御プログラムを生成する。プリディケート頂点については、その頂点が表す制御構造を生成する。そして、制御構造の本文として、当該頂点の下位の部分木の制御プログラムを生成する。基本ブロックについては依存関係に基づく非同期遠隔手続きおよびデータ転送を行う文を生成する。これについては以下に詳細に説明する。
更にステップS3で、終了値のデータ転送指示を生成する。最後にステップS4で、手続きの実行結果の待ち合わせを行う文を生成する。
図29は、制御プログラムを生成する処理のフローチャートを示す図である。図29に示す処理は、図28のステップS2の処理に相当する。図29の処理の入力は、実行順序関係が決定された縮退したプログラム依存グラフ及び基本ブロックの集合Bである。
ステップS1において、各初期定義頂点について以降の処理を繰り返すループを開始する。ここで初期定義頂点とは、変数の初期値が定まっている頂点のことをいう。
ステップS2で、初期定義頂点からプログラム・ブロック頂点へのフロー依存辺について、データ転送の予約を行なう。具体的には、アドレスを登録する処理と状態を変更する処理とを実行する。即ち、図8に示した関数def_data()によりデータ転送の予約をする。ただし、先行手続き呼び出しが存在しないため、転送元遠隔手続き呼び出し識別子fはφとする。
各初期定義頂点について以上の処理が繰り返し実行されると、その後、制御プログラム本体を生成する。
ステップS3で、プログラムの先頭を表すエントリ頂点vEntryの直下の子頂点vを要素とする基本ブロックの集合をB’とする。ステップS4において、B’の各要素Biについて、iの昇順に以降の処理を繰り返すループを開始する。ステップS5で、Biについての手続き制御プログラムを生成する。
図30は、基本ブロックの集合B’の要素Bi以下の手続き制御プログラムを生成する処理を示すフローチャートである。図30の処理は、図29のステップS5に相当する。図30に示す処理の入力は縮退したプログラム依存グラフPDG及び基本ブロック要素Biである。
図30のステップS1で、基本ブロックBiの要素(頂点)の種類を判定する。基本ブロックBiの要素である頂点の種類を判定することによって、基本ブロックBiがプログラム・ブロックの集合であるか、プレディケート頂点であるかが分かる。
ステップS1の判定の結果、基本ブロックBiがプログラム・ブロックの集合の場合は、ステップS2でプログラム・ブロックの制御プログラムを生成することとなる。ステップS1の判定の結果、基本ブロックBiがプレディケート頂点の場合は、ステップS3でプレディケートの制御プログラムを生成することとなる。
図31は、プログラム・ブロックの制御プログラムを生成する処理のフローチャートを示す図である。図31の処理は、図30のステップS2に相当する。
ステップS1で、Biの各頂点vを求めた実行順序順に探索する。ステップS2で、頂点vの基本ブロックを越える入力フロー依存辺(ブロック外からブロック内へのフロー依存辺)と、ループを繰り越すフロー依存辺について、データ転送指示と待合せを生成する。即ち、wait_for_def_and_move を用いて、データが未転送の場合に、データ転送の指示を行なう。また、「データ転送予約」とすることで、データが上書きされるまでは、データ再送は行なわない。
ステップS3で、頂点vの基本ブロックを越える出力フロー依存辺について、データ転送待合せを生成する。即ち、頂点vの遠隔手続き呼び出しにおいて、上書きするデータについて、後続の手続きへのデータ転送が完了しているかの待ち合わせを行なう。具体的には、wait_for_useを用いて、データを要求している手続きに対して、データ転送を待ち合わせる。
ステップS4で、頂点vの手続き呼び出しを生成する。ステップS5で、ステップS2のデータ転送と頂点vの依存関係を登録する。即ち、入力データ転送の後に頂点vの遠隔手続き呼び出しを実行すべく、入力データ転送とvの遠隔手続き呼び出しの依存関係を登録する。即ち、ブロックの境界を越えるデータ転送についてはregist_dependenceを用いて依存関係を登録する。ステップS5−1で、基本ブロックを越えないループを繰り越す出力フロー依存辺について、上書きするデータについてデータ転送行なってから手続きを実行するように、出力先変数へのデータ転送と頂点vの手続き呼び出しの間の依存関係を登録する。またステップS6で、Biに属する頂点からの頂点v へのループを繰り越さない各データ転送から手続きへの依存関係を登録する文を生成する。即ち、基本ブロック内であってループを繰り越さないものについては直接依存関係を登録する。
ステップS7で、頂点v からBiに属する頂点へのデータ転送に対してデータ転送指示と手続きからデータ転送指示への依存関係を登録する文を生成する。即ち、頂点vからブロック内の後続頂点へのループを繰り越さないフロー依存辺について、データ転送の指示を生成し、また頂点vの遠隔手続き実行後に実行すべく依存関係を登録する。
ステップS8で、頂点vの基本ブロックを越える出力フロー依存関係について、出力データ転送情報を登録する文を生成する。即ち、頂点vの基本ブロックを越える或いはループを繰り越すフロー依存辺に関して、出力データ転送情報の登録文def_data()を生成する。これにより転送元アドレスを設定し、転送状況を未転送とする。
ステップS9で、実行開始を指示する文を生成する。
図32は、プレディケートの制御プログラムを生成する処理のフローチャートを示す図である。図32の処理は、図30のステップS3に相当する。
ステップS1で、頂点vの入力フロー依存関係(自ループの繰越を除く)についてデータ転送指示(wait_for_def_and_move)と待合せ(wait)を生成する。即ち、条件式で参照するデータの転送を行なうために、自ループを繰り越すフロー依存辺以外の入力フロー依存辺について、wait_for_def_and_moveを用いて、データが未転送の場合に、データ転送の指示とその待ち合わせを行なう。
次にステップS2で、頂点vのプレディケートの種類を判定する。プレディケートがループである場合には、ステップS3に進む。プレディケートがif文である場合には、ステップS8に進む。
ステップS2の判定結果がループを示す場合には、ステップS3において、入力逐次プログラムにおいて相当するfor文或いはwhile文を生成する。次にステップS4において、頂点vへのL=Tの制御依存関係がある頂点uを要素とする基本ブロックの集合をB’とする。ステップS5において、B’の各要素Biについて、iの昇順に以降の処理を繰り返すループを開始する。ステップS6で、Biについての手続き制御プログラムを生成する。このステップS6は入れ子構造となっており、BiについてステップS6を実行することは、このBiについて図30全体のフローチャートを実行することに相当する。
ループの終了後、ステップS7で、頂点vへのループを繰り越す先行手続きの終了待ち合わせを生成する。これは、ループを繰り越して条件を判定するので、本文の末尾に、条件式への入力データ待ち合わせ(自ループを繰り越す入力フロー依存辺)を行なう文として、wait_for_def_and_moveと待ち合わせ(wait)を追加するものである。
ステップS2の判定結果がif文を示す場合には、ステップS8において、if文を生成する。次にステップS9で、then節を生成する。ステップS10で、頂点vへのL=Tの制御依存関係がある頂点uを要素とする基本ブロックの集合をB’とする。ステップS11において、B’の各要素Biについて、iの昇順に以降の処理を繰り返すループを開始する。ステップS12で、Biについての手続き制御プログラムを生成する。このステップS12は入れ子構造となっており、BiについてステップS12を実行することは、このBiについて図30全体のフローチャートを実行することに相当する。なおステップS11及びS12で生成された文が、then節の本文を構成することになる。
次にステップS13で、頂点vへのL=Fの制御依存関係がある頂点uを要素とする基本ブロックの集合をB’とする。ステップS14で、基本ブロックの集合B’が空集合であるか否かを判定し、空集合の場合には処理を終了する。基本ブロックの集合B’が空集合でない場合、ステップS15で、else節を生成する。ステップS16で、B’の各要素Biについて、iの昇順に以降の処理を繰り返すループを開始する。ステップS17で、Biについての手続き制御プログラムを生成する。このステップS17は入れ子構造となっており、BiについてステップS17を実行することは、このBiについて図30全体のフローチャートを実行することに相当する。なおステップS16及びS17で生成された文が、else節の本文を構成することになる。
以上の処理を実行することで、基本ブロックBi以下の手続き制御プログラムが生成される。
以下に、本発明の並列化プログラム生成方法により生成された手続きプログラム及び手続き制御プログラムについて、その構成及び動作を具体的な例を用いて説明する。
図33は、(a)入力逐次プログラムの部分、(b)対応する縮退プログラム依存グラフ、(c)生成された手続制御プログラムの部分を示す図である。(a)に示す入力逐次プログラムからプログラム依存グラフを生成し、頂点を結合して縮退することにより、(b)に示す縮退プログラム依存グラフが生成される。生成された手続き制御プログラムの一部分が(c)に示されており、制御変数pのwhile文の内部において、まずwait_for_def_and_move()により、手続きfの参照データxを待ち合わせ、xのデータ転送を指示する。次にwait_for_use()により、前回の手続fの結果を必要としている手続きgへのデータ転送を待ち合わせる。更にregist_dependence()により、xのデータ転送に依存して手続きfを実行することを登録する。また更に、def_data()により、手続きgの参照データについて転送元アドレス等を登録する。ディスパッチ命令dispatchにより、実行可能手続きである手続きを実行する。
制御変数pのwhile文の終了後に、wait_for_def_and_move()により、手続きgの参照データyを待ち合わせ、yのデータ転送を指示する。更にregist_dependence()により、yのデータ転送に依存して手続きgを実行することを登録する。
図34は、以上の手続き制御プログラムの動作を手続きプログラムの実行とともに示す模式図である。図34では、プロセッサPE0と、データ転送ユニットDTUと、プロセッサPE1と、プロセッサPE2とが用いられる。プロセッサPE0により手続き制御プログラムを実行する。
プロセッサPE0により1回目のwhileのループについて手続き制御51が実行される。これにより変数xがプロセッサPE1に転送される。プロセッサPE1は手続き「y=f(x)」を実行するが、この結果である変数yの値はこの時点では転送されない。
次にプロセッサPE0により2回目のwhileのループについて手続き制御52が実行される。このとき変数xは既に1回目のループで転送されており、その後変更されていないので、変数xの転送が実行されることはない。プロセッサPE1は手続き「y=f(x)」を実行するが、この結果である変数yの値はこの時点では転送されない。
次にプロセッサPE0によりwhileループ後の手続き制御53が実行される。これにより、手続きgの入力y(=f(x))の待ち合わせが指定され、yのデータ転送を指示する。最後にプロセッサPE0により手続き制御54が実行される。これにより手続きgの依存関係が登録され更に手続きの実行が指示される。手続きgの実行時に、初めて変数yがPE1からDTUを介してPE2に転送される。
図35は、図34での変数xの参照について更に詳しく説明する図である。プロセッサPE0による手続き制御51においてdef_data()を実行することにより、xの転送状況は「未転送」に設定される。またこの際、転送元遠隔手続き呼び出し識別子はφ(空集合)と指定される。その後手続き制御51においてwait_for_def_and_move()を実行すると、xの転送状況が「未転送」なので、手続きを待ち合わせてxのアドレス(&x)のデータを転送する。但しこの例では、手続きがφ(空集合)なので、手続き待ち合わせは行なわない。xの転送状況は「転送予約」に設定される。
その後、プロセッサPE0により手続き制御52が実行される。この手続き制御52においてwait_for_def_and_move()を実行すると、xの転送状況は「未転送」ではないので、転送処理は実行されない。
図36は、図34での変数yの参照について更に詳しく説明する図である。プロセッサPE0による手続き制御51においてwhileループ内でdef_data()を実行することにより、yの転送状況は「未転送」に設定され、転送元遠隔手続き呼び出し識別子は手続きfを示す値に設定され、転送元アドレスは手続きfの変数yのアドレスに設定される。
その後、プロセッサPE0により手続き制御52が実行される。この手続き制御52においてdef_data()を実行することにより、yの転送状況は「未転送」に設定され、転送元遠隔手続き呼び出し識別子は手続きfを示す値に設定され、転送元アドレスは手続きfの変数yのアドレスに設定される。
その後、プロセッサPE0により手続き制御53が実行される。この手続き制御53においてwait_for_def_and_move()を実行すると、yの転送状況(dtc_g_y->転送状況)は「未転送」であるので、手続きfを待ち合わせてからyの転送処理が指示される。
図37は、whileループqを繰り越すときの変数yのデータ転送待ち合わせを説明するための図である。まずプロセッサPE0により1回目のwhileqのループについて手続き制御61が実行される。これにより変数xがプロセッサPE1に転送される。プロセッサPE1は手続き「y=f(x)」を実行する。またdef_data()を実行することにより、yの転送状況は「未転送」に設定され、転送元遠隔手続き呼び出し識別子は手続きfを示す値に設定され、転送元アドレスは手続きfの変数yのアドレスに設定される。
次に、プロセッサPE0により手続き制御62が実行される。この手続き制御62においてwait_for_def_and_move()を実行すると、yの転送状況(dtc_g_y->転送状況)は「未転送」であるので、手続きfを待ち合わせてからyの転送処理が指示される。yの転送状況は「転送予約」に設定され、データ転送識別子は、手続きfの変数yから手続きgの変数yへのデータ転送の識別子の値に設定される。
次に、プロセッサPE0により手続き制御63が実行される。この手続き制御63においてregist_dependence()とdispatchを実行することにより、変数yのデータ転送してからの手続きgの実行が命令される。
変数yのデータ転送が実行中に、プロセッサPE0により手続き制御64が実行され、制御変数qのwhileの次回のループが実行される。即ち、例えば図4に示すようなプログラムの場合である。whileの次回のループにおいてwait_for_use()により、前回の手続fの結果を必要としている手続きgへのデータ転送を待ち合わせる。即ちyの転送状況が「転送予約」を示し且つ転送元手続き呼び出し識別子が手続きfを示すので、手続きfの変数yから手続きgの変数yへのデータ転送が終了するのを待つ。データ転送が終了すると、転送状況は「転送済」に設定される。その後、プロセッサPE0により手続き制御65が実行され、手続きfが実行される。
このようにして、ループを繰り越すときの変数yのデータ転送待ち合わせを実現することができる。
図38は、本発明による並列化プログラム生成方法を実行する装置の構成を示す図である。
図38に示されるように、本発明による並列化プログラム生成方法を実行する装置は、例えばパーソナルコンピュータやエンジニアリングワークステーション等のコンピュータにより実現される。図38の装置は、コンピュータ510と、コンピュータ510に接続されるディスプレイ装置520、通信装置523、及び入力装置よりなる。入力装置は、例えばキーボード521及びマウス522を含む。コンピュータ510は、CPU511、RAM512、ROM513、ハードディスク等の二次記憶装置514、可換媒体記憶装置515、及びインターフェース516を含む。
キーボード521及びマウス522は、ユーザとのインターフェースを提供するものであり、コンピュータ510を操作するための各種コマンドや要求されたデータに対するユーザ応答等が入力される。ディスプレイ装置520は、コンピュータ510で処理された結果等を表示すると共に、コンピュータ510を操作する際にユーザとの対話を可能にするために様々なデータ表示を行う。通信装置523は、遠隔地との通信を行なうためのものであり、例えばモデムやネットワークインターフェース等よりなる。
本発明による並列化プログラム生成方法は、コンピュータ510が実行可能なコンピュータプログラムとして提供される。このコンピュータプログラムは、可換媒体記憶装置515に装着可能な記憶媒体Mに記憶されており、記憶媒体Mから可換媒体記憶装置515を介して、RAM512或いは二次記憶装置514にロードされる。或いは、このコンピュータプログラムは、遠隔地にある記憶媒体(図示せず)に記憶されており、この記憶媒体から通信装置523及びインターフェース516を介して、RAM512或いは二次記憶装置514にロードされる。
キーボード521及び/又はマウス522を介してユーザからプログラム実行指示があると、CPU511は、記憶媒体M、遠隔地記憶媒体、或いは二次記憶装置514からプログラムをRAM512にロードする。CPU511は、RAM512の空き記憶空間をワークエリアとして使用して、RAM512にロードされたプログラムを実行し、適宜ユーザと対話しながら処理を進める。なおROM513は、コンピュータ510の基本動作を制御するための制御プログラムが格納されている。
上記コンピュータプログラム(並列化プログラム生成プログラム即ち並列化プログラム生成コンパイラ)を実行することにより、コンピュータ510が、上記各実施例で説明されたように並列化プログラム生成方法を実行する。
以上、本発明を実施例に基づいて説明したが、本発明は上記実施例に限定されるものではなく、特許請求の範囲に記載の範囲内で様々な変形が可能である。