(57)【特許請求の範囲】
【請求項１】
バリア同期機構を備えた共有メモリ型マルチプロセッサに与える目的コードを生成するための高級言語の翻訳を行うコンパイラにおけるループ並列化方法において、前記コンパイラとしてのプロセッサは、ループ繰り返しにまたがったデータ依存関係の存在する多重ループに対して、当該多重ループからパイプライン的に並列実行可能なループを抽出し当該ループの分割を行った後、当該ループをパイプライン的に並列実行させるために、当該多重ループの前後にバリア同期を発行するループを生成し、前記分割したループの直後にバリア同期を発行する文を生成することを特徴とするループ並列化方法。
【請求項２】
前記分割したループが内側ループである場合、前記プロセッサは、外側ループをブロック化し、前記分割したループが外側ループである場合、内側ループをブロック化することを特徴とする請求項１記載のループ並列化方法。
【請求項３】
請求項１または２記載のループ並列化方法を実現するプログラムを格納したことを特徴とする記録媒体。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、バリア同期を利用したループ並列化方法に係り、特に、バリア同期機構を備えたマルチプロセッサに対する目的コードを生成するために使用して好適なコンパイラにおけるループ並列化方法に関する。
【０００２】
【従来の技術】
同期制御としてバリア同期を利用する共有メモリ型のマルチプロセッサ上で効率的に並列実行を行うような目的コードを生成するための従来技術によるループ並列化技術として、例えば、「スーバーコンパイラ」(Hans Zima、Barbara Chapman 共著、村岡洋一訳、オーム社）p276−p297等に記載された技術が知られている。
【０００３】
従来技術によるループ並列化は、ループ繰り返しにまたがるデータ依存（以下、これをループ運搬依存と呼ぶ）が存在しないＤＯＡＬＬループを対象として並列化を行うものである。そして、従来技術は、並列化したＤＯＡＬＬループ間に依存関係が存在する場合、ＤＯＡＬＬループ間にバリア同期を実行する文を挿入することによって並列実行が正しく行われることを保証している。
【０００４】
図７は本発明によるループ並列化方法により並列化された目的コードを並列に実行することが可能な従来技術によるマルチプロセッサの構成と実行イメージとを説明する図であり、以下、図７を参照して目的コードの並列実行ついて説明する。
【０００５】
図７に示すマルチプロセッサは、単一ノードとして機能するものであり、１台のマスタープロセッサ６１と、複数例えば８台のスレーブプロセッサ６２とによって構成され、各プロセッサが、個々にキャッシュをもち、また、全てのプロセッサがメモリを共有している。図７に示すマルチプロセッサは、前述のような構成の下で、単一プログラムの処理の高速化を図るためにＳＩＤ−ＳＭＰ方式と呼ばれる並列実行方式が採用されている。以下、この方式について説明する。
【０００６】
図７において、プログラムは、最初にマスタープロセッサ６１上で実行される。同時に、プログラム実行の先頭で、マスタープロセッサ６１は、マスタープロセッサ６１上で実行するプログラムを親スレッドとしてスレーブプロセッサ数分の子スレッドを生成する。
【０００７】
生成された子スレッドは、プログラムが終了するまで各スレーブプロセッサ６２に固定して割り付けられる。従って、スレッドの生成、削減のためのオーバーヘッドは、プログラムの最初と最後とにのみ発生する。プログラムは、コンパイラによって、予め逐次実行部分と並列実行部分とに分割される。逐次実行部分は、マスタープロセッサ６１によってのみ実行され、この部分の実行中は、他のプロセッサは実行待ちのスピンループを実行する。プログラムの実行が並列実行部分に到達すると、マスタープロセッサ６１と共に、全てのスレーブプロセッサ６２が並列実行部分の実行を開始する。全てのプロセッサの並列実行部分の実行が終了すると、マスタープロセッサ６１は後続の逐次実行部分の実行を開始し、スレーブプロセッサ６１は再び実行待ちのスピンループに入る。
【０００８】
前述の方式は、複数の子スレッドを、特定のプロセッサ上で固定的に待機させておくことによって、並列実行の起動、終結のためのオーバーヘッド時間を最小限に抑えようとするものである。
【０００９】
前述において、スレーブプロセッサの並列実行中にプロセッサ間で同期をとりたい場合がある。このとき、同期の方法としてバリア同期が使用されるのが一般的である。バリア同期は、全てのプロセッサが同期点に到達するまで、先に同期点に到達した他の全てのプロセッサが待機することによって同期をとるための方式であり、専用のハードウエア命令によって実現することができる。
【００１０】
一方、自動並列化コンパイラが並列化の対象とするのはループである。そして、並列化の対象となるループは、任意のループではなく、ループ実行前にループ長が計算できるループであ、例えば、ＦＯＲＴＲＡＮのＤＯループがこれに相当する。コンパイラは、これらのループを解析し、並列実行可能か否かを判定し、並列実行可能と判定したループに対して、そのループのイタレーションを分割して、分割されたループを各プロセッサが実行するようなコードを生成する。
【００１１】
並列実行されるループのイタレーションをどのように分割して各プロセッサに割り付けるかは、マルチプロセッサにおけるスケジューリング問題といわれる。このようなスケジューリング方式としては、動的スケジューリング方式と静的スケジューリング方式との２つが考えられる。
【００１２】
動的スケジューリング方式は、実行時に動的に割り付け先のプロセッサを決定するので、各プロセッサの負荷を均等に近くできるという利点があるが、実行時にプロセッサへの割り付けを行うためのオーバーヘッドが大きくなりすぎる傾向がある。これに対して、静的スケジューリング方式は、コンパイラが静的に割り付け先のプロセッサを決定するため、実行時のオーバーヘッドは少なくて済むという利点を有している。特に、ＤＯループの並列化は、単純な分割でも負荷を均等に近くできる場合が多いと考えられ、図７に説明したマルチプロセッサも、スケジューリング方式として、コンパイラによる静的分割方式が採用されている。
【００１３】
図８は並列化可能なＤＯループの例と、それを静的分割によって並列実行用に変換したコードとを示す図であり、以下、これについて説明する。
【００１４】
ＤＯループの静的分割の方法として、各種の分割方法が知られているが、基本的にはブロック分割を行う方法が使用される。ブロック分割されたＤＯループのそれぞれは、各プロセッサにより１つのループがブロック長分の連続したイタレーションとして実行される。ブロック長は、ループ長をプロセッサの総数で割ることによって求めることができる。
【００１５】
図８に示す並列化後のループにおけるＴの計算がブロック長を求めるものである。この計算式において、Ｔはブロック長、ＰＲＯＣ＿ＰＮはプロセッサの総数、ＣＥＬＩは割り切れないときに切り上げを行う指示である。各プロセッサは、自分のプロセッサの識別番号、図８の例ではＰＲＯＣ＿ＩＤを持っているので、そのプロセッサ番号とブロック長とから自分の担当するイタレーションの下限Ｌ、上限Ｕを計算することができる。
【００１６】
図８に示したような並列実行用のコードは、各プロセッサ上にロードされて同一のものが並列に実行される。但し、その中で参照される変数は全てのプロセッサで共有されるグローバルなものと、各プロセッサに固有の領域に割り当てられるローカルなものとに分かれる。基本的に、元のプログラム中に現れる変数はグローバルで、Ｔ，Ｌ，Ｕのように並列化後に生成される変数はローカルになる。ループ制御変数、すなわち、ＤＯループの実行を制御する変数、図８の例におけるＩは、並列化時には、ローカルな変数になる。そうしないと、同一領域に別々のプロセッサからの書き込みが生じてしまう。図８に示す例では、元のループ制御変数と区別するため並列化後のループ制御変数を％Ｉとしてある。
【００１７】
【発明が解決しようとする課題】
一般に、マルチプロセッサの実行性能を向上させるためには、多重ループから効率的に並列性を抽出する技術が重要になる。しかし、バリア同期を利用する前述した従来技術は、多重ループ内にＤＯＡＬＬループがない場合、ループ分配等のループ変換技術を使ってＤＯＡＬＬループを作り出すことができない限り、並列化を行うことが困難であるという問題点を有している。
【００１８】
本発明の目的は、前述した従来技術の問題点を解決し、ＤＯＡＬＬループを含まない多重ループに対しても、並列性を抽出可能な場合にはバリア同期を利用して並列化を行い、マルチプロセッサ上で効率的な実行性能が得られるような目的コードを生成することを可能にしたコンパイラにおけるループ並列化方法を提供することにある。
【００１９】
【課題を解決するための手段】
本発明によれば前記目的は、バリア同期機構を備えた共有メモリ型マルチプロセッサに与える目的コードを生成するための高級言語の翻訳を行うコンパイラにおけるループ並列化方法において、前記コンパイラとしてのプロセッサは、ループ繰り返しにまたがったデータ依存関係の存在する多重ループに対して、当該多重ループからパイプライン的に並列実行可能なループを抽出し当該ループの分割を行った後、当該ループをパイプライン的に並列実行させるために、当該多重ループの前後にバリア同期を発行するループを生成し、前記分割したループの直後にバリア同期を発行する文を生成することにより達成される。
【００２０】
また、前記目的は、前記分割したループが内側ループである場合、外側ループをブロック化し、前記分割したループが外側ループである場合、内側ループをブロック化することにより達成される。
【００２１】
【発明の実施の形態】
以下、本発明によるバリア同期を利用したループ並列化方法の一実施形態を図面により詳細に説明する。
【００２２】
図１は本発明によるループ並列化を行うコンパイラの構成を示す図、図２は図１に示すコンパイラの動作を説明するフローチャート、図３はＦＯＲＴＲＡＮ言語で記述されたＤＯループの例を示す図、図４は図３に示すＤＯループの並列分割を行った後のＤＯループを説明する図、図５は図４に示すＤＯループにバリア同期文を挿入した後のＤＯループを説明する図、図６は図５に示すＤＯループにブロック化を適用した後のＤＯループを説明する図である。図１において、１１はソースプログラム、１２はコンパイラ、１３は並列化変換部、１４はＤＯＡＬＬ型並列化変換部、１５はパイプライン型並列化変換部、１６は目的コード生成部、１７は目的プログラム、１８はプログラム格納媒体である。
【００２３】
本発明によるループ並列化を行うコンパイラ１２は、ＦＯＲＴＲＡＮ等の逐次型の高級言語で記述されたソースプログラム１１を入力として、マルチプロセッサ上で実行可能な目的コードを生成し目的プログラム１７として出力するものであり、並列化変換部１３と目的コード生成部１６とにより構成される。並列化変換部１３は、並列化の判定及び変換を実施する機能を持ち、プログラム中のループを認識し、これらの各ループに対して並列化が可能か否かの判定を行い、並列化可能と判定した場合に、入力されたソースプログラムを並列実行可能なループに変換する。
【００２４】
並列化変換部１３は、従来型のＤＯＡＬＬ型の並列化を行うＤＯＡＬＬ型並列化変換部１４と、本発明によるパイプライン型の並列化を行うパイプライン型並列化変換部１５とにより構成される。そして、並列化変換部１３は、入力されたソースプログラムの各ループに対して、最初にＤＯＡＬＬ型の並列化を試み、これが適用できないループに対してパイプライン型の並列化の適用を試みる。
【００２５】
なお、コンパイラ１２における処理を実行するコンパイラプログラムは、記録媒体１８に格納されている。
【００２６】
次に、図２に示すフローを参照してコンパイラ１２における処理動作を説明する。
【００２７】
（１）入力されるソースプログラム内の各ループネストに対してデータ依存の解析を行う（ステップ２０１）。
【００２８】
（２）データ依存の解析からＤＯＡＬＬ型並列化が適用可能か否かをチェックし、ＤＯＡＬＬ型並列化が適用可能な場合、ＤＯＡＬＬ型並列化変換部１４に並列化を実行させる（ステップ２０２、２０３）。
【００２９】
（３）ステップ２０２で、ＤＯＡＬＬ型並列化が適用不可能であると判定された場合、パイプライン型並列化が適用可能か否かをチェックし、パイプライン型並列化が適用可能な場合、パイプライン型並列化変換部１５に並列化を実行させる（ステップ２０４、２０５）。
【００３０】
（４）ステップ２０４で、パイプライン型並列化が適用不可能であると判定された場合、並列化を行わず、ステップ２０１の処理に戻って、次のループネストの解析からの処理を続ける。なお、並列化されないループは、逐次実行されることになる（ステップ２０６）。
【００３１】
次に、ソースプログラムの例として、図３に示すプログラムを考え、パイプライン型の並列化の概要を説明する。
【００３２】
図３に示す例は、ＦＯＲＴＲＡＮ言語で記述されたＤＯループであり、このＤＯループは、外側ループ２１に対しても、内側ループ２２に対しても配列Ａに関してループ運搬依存が存在する。このようなループは、まず、内側ループを分割してマルチプロセッサ上の各プロセッサに割り当てられる。プロセッサ番号をＰ１，Ｐ２，・・・，Ｐｎとすると、内側ループのイタレーション［１：Ｎ］が分割されて、順番にプロセッサＰ１，Ｐ２，・・・，Ｐｎに割り当てられる。
【００３３】
このとき、各プロセッサに割り当てられた内側ループのイタレーションを、プロセッサＰｋに対して［Ｌｋ：Ｕｋ］（但し、Ｌｋは、イタレーションの下限値、Ｕｋはイタレーションの上限値）とする。これに、外側ループイタレーション［１：Ｎ］を考慮に入れると、結局、各プロセッサは、プロセッサ番号Ｐｋとするとき、［１：Ｎ，Ｌｋ：Ｕｋ］のイタレーションを実行することになる。
【００３４】
ここで、外側ループのイタレーションをＭとするとき、イタレーション［Ｍ，Ｌｋ：Ｕｋ］からイタレーション［Ｍ，Ｌｋ＋１：Ｕｋ＋１］への依存が存在するため、イタレーション［Ｍ，Ｌｋ：Ｕｋ］の実行が完了してからでないと、イタレーション［Ｍ，Ｌｋ＋１：Ｕｋ＋１］の実行を開始することはできない。逆に、これ以外には、異なるプロセッサに割り当てられたイタレーション間には依存関係は存在しない。このような場合、パイプライン的な並列化を適用することができる。
【００３５】
バリア同期を利用したパイプライン的な並列化の処理は、プロセッサ番号の小さいものから順番にループの実行を開始することにより行われる。まず、プロセッサＰ１がループの実行を開始し、プロセッサＰ１は、外側ループの最初のイタレーションの実行を終了したとき、バリア同期を発行し、プロセッサＰ２がループの実行を開始する。次に、プロセッサＰ１が外側ループの２番目のイタレーションの実行を終了し、プロセッサＰ２が外側ループの最初のイタレーションの実行を終了したとき、バリア同期を発行し、プロセッサＰ３がループの実行を開始する。
【００３６】
以下、同様にしてバリア同期によって同期をとりながらプロセッサは順番にループの実行を開始し、ループの実行を行うプロセッサが１台ずつ増えてゆき、やがて、全てのプロセッサによって並列実行が行われるようになる。このときも、外側ループの１イタレーションの実行終了毎にバリア同期が発行される。ループの実行の終了は、必然的にループ開始と同様にプロセッサ番号が小さいものから完了し、プロセッサＰ１がループの実行を終了した後、ループの実行を行うプロセッサは１台ずつ減ってゆき、やがて、全てのプロセッサがループの実行を終了する。
【００３７】
本発明の実施形態においては、前述したようなバリア同期を利用したパイプライン的な並列化を実現するために、以下のような方針に従って目的コードを生成する。すなわち、
まず、ループ実行の直前に（プロセッサ番号−１）回分のバリア同期を発行するループを生成する。
次に、内側ループを分割し各プロセッサに割り当て、分割したループの直後にバリア同期を発行する文を生成する。
最後に、ループ実行の直後に（プロセッサ総数−プロセッサ番号）回分バリア同期を発行するループを生成する。
【００３８】
前述した説明におけるパイプライン的な並列化は、パイプラインの１ステージ、すなわち、バリア同期の発行の間の実行が外側ループの１イタレーションに相当するが、外側ループ長が充分に長いことがわかっている、または、予測されるとき、このパイプラインの１ステージで外側ループの複数のイタレーションを実行するようにすることによってバリア同期の発行回数を削減することができる。これを、ブロック化と呼び、バリア同期の発行回数を削減することが可能となり、実行時間の削減が期待できる。
【００３９】
前述したように、図３に示したＦＯＲＴＲＡＮプログラムで記述されたＤＯループは、外側ループ、内側ループの両方に対してループ運搬依存が存在するためＤＯＡＬＬ型の並列化を適用することができない。従って、パイプライン型の並列化が適用される。前述した方針に従って図３に示すＤＯループを分割したＤＯループが図４に示されており、以下、これについて説明する。
【００４０】
最初に、内側ループのイタレーションをマルチプロセッサ上のプロセッサ数だけ均等に分割して各プロセッサに順番に割り当てる。各プロセッサに割り当てられる内側ループのループ長をＢ、プロセッサ総数ＰＮとすると、Ｂ＝［Ｎ／ＰＮ］となる。ここで、［  ］は割り切れなかった場合、整数への切り上げを示すものである。また、各ループが実行する内側ループのイタレーションの下限値をＬ、上限値をＵとすると、Ｌ＝Ｂ×（Ｐ−１）＋１、Ｕ＝ＭＩＮ（Ｌ＋Ｂ−１，Ｎ）となる。この式において、Ｐはプロセッサ番号（Ｐ＝１，２，・・・，ＰＮ）である。
【００４１】
前述した変換によって、各プロセッサは、自プロセッサ番号からループの上下限値を計算して自分に割り当てられたループを実行することが可能になる。そして、自分に割り当てられたループを計算するために、各プロセッサに与えるＤＯループは、前述した分割ループのループ長の計算式３１、分割ループの下限値計算式３２、分割ループの上限値計算式３３及び分割された内側ループ３４の情報を含んでいる。
【００４２】
さらに、図４に示す分割したループを各プロセッサがパイプライン的に並列実行するためにバリア同期を発行するバリア同期文が挿入される。バリア同期文は、図５に示すように、図４に示したループの直前に挿入されるバリア同期によるプロローグループ４１、直後に挿入されるバリア同期によるエピローグループ４３と、分割したループの直後の位置に挿入されるバリア同期文４２とにより構成される。プロローグループ４１は、（Ｐ−１）回繰り返えされ、エピローグループ４３は、（ＰＮ−Ｐ）回繰り返えされる。
【００４３】
この結果、マルチプロセッサ上の各プロセッサは、自プロセッサ番号より１つ若いプロセッサ番号のプロセッサが分割されたＤＯループの１回を終了するまでプロローグループ４１を実行し、その後に自プロセッサでのＤＯループの処理を開始することになる。そして、マルチプロセッサは、若番のプロセッサから順に処理を開始して全てのプロセッサが協調してパイプライン的な並列実行を行うことが可能となる。また、各プロセッサでのＤＯループの処理は、若番のプロセッサから順に終了することになるが、エピローグループ４３を実行することにより、全プロセッサが同時に処理を終了することになる。
【００４４】
前述した本発明の実施形態は、内側ループを分割し、分割されたＤＯループをマルチプロセッサを構成する各プロセッサに割り当てるとして説明したが、本発明は、外側ループを分割し、分割されたＤＯループをマルチプロセッサを構成する各プロセッサに割り当てるように構成してもよい。
【００４５】
また、前述で説明した実施形態により各プロセッサに割り当てられるループにおける多重ループ内でのバリア同期文４２の発行回数は外側ループ長と等しくＮ回となるが、外側ループにブロック化を適用することによってバリア同期の実行回数を削減することができる。
【００４６】
外側ループにブロック化を適用して得ることができるループの例が図６に示されている。このループは、図５に示すループに対して、外側ループをブロック化することによりループ５１とループ５２とからなる二重ループに変換したものである。ループ５２は、ブロック化されたループ長Ｔのループであり、ループ５３は、その実行の制御ループになる。このとき、バリア同期文は、ブロック化されたループの直後の位置にバリア同期文５３として挿入される。この結果、バリア同期文５３の発行は、ブロック化を行わない場合にＮ回であったものを、ブロック化を適用することにより［Ｎ／Ｔ］回とすることができる。
【００４７】
前述では内側ループを分割し、外側ループをブロック化するとして説明したが、本発明は、外側ループを分割し、内側ループをブロック化することもでき、同様な効果を得ることができる。
【００４８】
【発明の効果】
以上説明したように本発明によれば、ＤＯＡＬＬループを含まない多重ループに対しても、並列性を抽出可能な場合にはバリア同期を利用して並列化を行い、マルチプロセッサ上で効率的な実行性能が得られるような目的コードを生成することができる。
【図面の簡単な説明】
【図１】本発明によるループ並列化を行うコンパイラの構成を示す図である。
【図２】図１に示すコンパイラの動作を説明するフローチャートである。
【図３】ＦＯＲＴＲＡＮ言語で記述されたＤＯループの例を示す図である。
【図４】図３に示すＤＯループの並列分割を行った後のＤＯループを説明する図である。
【図５】図４に示すＤＯループにバリア同期文を挿入した後のＤＯループを説明する図である。
【図６】図５に示すＤＯループにブロック化を適用した後のＤＯループを説明する図である。
【図７】本発明によるループ並列化方法により並列化された目的コードを並列に実行することが可能な従来技術によるマルチプロセッサの構成と実行イメージとを説明する図である。
【図８】並列化可能なＤＯループの例と、それを静的分割によって並列実行用に変換したコードとを示す図である。
【符号の説明】
１１  ソースプログラム
１２  コンパイラ
１３  並列化変換部
１４  ＤＯＡＬＬ型並列化変換部
１５  パイプライン型並列化変換部
１６  目的コード生成部
１７  目的プログラム
１８  プログラム格納媒体
【図１】
0003729644.tif 000002
【図２】
0003729644.tif 000003
【図３】
0003729644.tif 000004
【図４】
0003729644.tif 000005
【図５】
0003729644.tif 000006
【図６】
0003729644.tif 000007
【図７】
0003729644.tif 000008
【図８】
0003729644.tif 000009