(57)【要約】【課題】配列の要素のすべてがある領域内でローカルでない場合にも、配列圧縮効果が得られる圧縮方法を提供する。【解決手段】記憶装置に格納されているプログラムを読み出し、該プログラムにおけるループネスト内の配列の要素のうちで、プログラム全体から見て該ループネスト内でのみローカルな要素をスカラー変数に置き換える部分圧縮を行い、ローカルでない要素に対しては元の配列へのアクセスをプログラム内に挿入する。【選択図】      図１
2004213113.tif 000002
【特許請求の範囲】
【請求項１】
配列のサイズを減少させる配列圧縮方法において、
記憶装置に格納されているプログラムを読み出し、
該プログラムにおけるループネスト内の配列の要素のうちで、プログラム全体から見て該ループネスト内でのみローカルな要素をスカラー変数に置き換える部分圧縮を行い、
ローカルでない要素に対しては、元の配列へのアクセスをプログラム内に挿入することを特徴とする配列圧縮方法。
【請求項２】
前記部分圧縮の前に行われるループネスト列内の圧縮候補配列の探索において、
ループネスト列内の配列が最初に出現するループネストを求め、
該ループネストに対して、該配列が定義が先行する要素の多い定義先行の配列であれば、該配列をループネスト列内での圧縮の候補とすることを特徴とする請求項１記載の配列圧縮方法。
【請求項３】
前記ループネスト列内圧縮候補配列探索と、前記部分圧縮との間に行われるプログラム内圧縮候補配列探索において、
前記ループネスト列内で圧縮候補とされた配列がプログラム内の他のループネスト列内で圧縮候補とされてない時、該配列を圧縮の候補から除外することを特徴とする請求項２記載の配列圧縮方法。
【請求項４】
前記部分圧縮の前に行われるループネスト列の複数のサブ・ループネスト列への分割において、
前記圧縮候補の配列がループネスト内で定義先行であるような定義先行ループネストをサブ・ループネスト列の先頭とするように分割を行うことを特徴とする請求項１記載の配列圧縮方法。
【請求項５】
前記サブ・ループネスト列への分割と部分圧縮との間で行われるサブ・ループネスト列内のループネストの融合性チェックにおいて、
各ループネストの多次元並列化処理から得られる、各ループの変数の変化方向が順方向か逆方向かを示す回転方向の情報と、該ループ変数が圧縮候補の配列の添字中に出現する位置とに対応してサブ・ループネスト列内のループネストの融合のために回転方向を逆転すべきループを決定し、
各ループネスト内でのループの順序を示す情報と、該ループの変数が圧縮候補の配列の添字中に出現する位置とに対応してループの順序を反転すべきループネストを決定することを特徴とする請求項４記載の配列圧縮方法。
【請求項６】
プログラム内で配列のサイズを減少させる配列圧縮方法において、
記憶装置に格納されているプログラムを読み出し、
該プログラムにおけるループネスト列内の配列が最初に出現するループネストを求め、
該ループネストに対して、該配列が定義が先行する要素の多い定義先行の配列であれば該配列をループネスト列内での圧縮の候補とし、
該圧縮候補とされた配列のうちから圧縮を行うべき配列を選択して、該選択された配列の圧縮を行うことを特徴とする配列圧縮方法。
【請求項７】
前記配列圧縮の前に行われるプログラム内圧縮候補配列探索において、
前記ループネスト列内で圧縮候補とされた配列がプログラム内の他のループネスト列内で圧縮候補とされてない時、該配列を圧縮の候補から除外することを特徴とする請求項６記載の配列圧縮方法。
【請求項８】
前記配列圧縮の前に行われるループネスト列のサブ・ループネスト列への分割において、
前記圧縮候補の配列がループネスト内で定義先行であるような定義先行ループネストをサブループネスト列の先頭とするように分割を行うことを特徴とする請求項６記載の配列圧縮方法。
【請求項９】
前記サブ・ループネスト列への分割と配列圧縮との間に行われるサブ・ループネスト列内のループネストの融合性チェックにおいて、
各ループネストの多次元並列化処理から得られる、各ループの変数の変化方向が順方向か逆方向かを示す回転方向の情報と、該ループ変数が圧縮候補の配列の添字中に出現する位置とに対応してサブ・ループネスト列内のループネストの融合のために回転方向を逆転すべきループを決定し、
各ループネスト内でのループの順序を示す情報と、該ループの変数が圧縮候補の配列の添字中に出現する位置とに対応してループの順序を反転すべきループネストを決定することを特徴とする請求項８記載の配列圧縮方法。
【請求項１０】
プログラム内の配列のサイズを減少させるために計算機で使用されるプログラムにおいて、
記憶装置から対象となるプログラムを読み出す手順と、
該プログラムにおけるループネスト内の配列の要素のうちで、プログラム全体から見て該ループネスト内でのみローカルな要素をスカラ変数に置き換える部分圧縮を行う手順と、
ローカルでない要素に対しては、元の配列へのアクセスをプログラム内に挿入する手順とを計算機に実行させるためのプログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、プログラムにおいて多量のデータを扱うために利用される配列のサイズ、すなわち配列の要素の数を減少させる配列圧縮方式に関する。
【０００２】
【従来の技術】
数値計算プログラムなどのように、大量のデータを扱うプログラムを効率よく実行するためには、キャッシュなどを有効に利用することが必要である。そのために様々な手法が考案されてきた。配列圧縮という手法もその１つであり、これは配列のサイズを減らして、ローカリティを向上させる最適化の手法である。
【０００３】
配列の圧縮について説明する前に、本発明で用いる配列に関連する用語について説明する。図１４はループネストが列となっているループネスト列の例の説明図である。同図の先頭に、添字ＩおよびＪを持つ配列Ａについてのループネストが記述されている。
【０００４】
このループネストは、添字Ｊに関するループが外側、Ｉに関するループが内側となっている入れ子構造となっている。しかしながら以後の説明においては、入れ子構造となっていない１つのループだけのものについてもループネストと呼ぶことにする。
【０００５】
次に配列のローカリティ（局所性）について説明する。まず１つの配列Ａが領域Ｒ内でローカルであるということは、領域Ｒ内で定義、または参照されるＡの要素が全てＲ内でローカルであることを意味する。ここで領域とはプログラム全体の中の任意の一部であり、ループネストや、ループネスト列はそれぞれ１つの領域である。
【０００６】
また配列Ａの要素ｅが領域Ｒ内でローカルであるということは、第１にＲ内で参照されるｅの値は必ずその参照の前にＲ内で定義されているという条件と、第２にＲで定義されたｅの値はＲ内でしか参照されないという条件とを共に満たすことを意味する。
【０００７】
図１５は配列圧縮の従来例の説明図である。同図において上側で一次元の配列Ｔ（Ｉ）が定義され、その後参照されて配列Ａ（Ｉ）の定義が行われている。ここで配列Ｔ（Ｉ）の内容がプログラム全体の中の他の領域で参照されることがなければ、Ｔ（１）からＴ（Ｎ）までのＮ個の要素からなるこの配列は１つのスカラ変数Ｔとして下のように記述することができ、配列のサイズの減少が実現される。
【０００８】
このような配列圧縮の従来技術として次の文献がある。
【０００９】
【非特許文献１】
G.R.Gao他,“Collective Loop Fusion for Array Contraction”,ACAPS Technical Memo 41,Mcgill Univ.1992.
【００１０】
【発明が解決しようとする課題】
図１５で説明したようにある配列Ａの要素の全てが領域Ｒ内でローカルであれば、Ｒ内において配列Ａを圧縮できる可能性がある。
【００１１】
しかしながら一般にこの条件を満たす場合はそれほど多くはなく、従来の圧縮方式では配列圧縮の効果が得られる機会が少ないという問題点があった。
また前述の文献は配列圧縮に関する有名、かつ基本的な論文であるが、この論文の方式はネストの深さが１のケースにしか適用できず、ほとんど実用的な配列圧縮を行うことができないという問題点があった。
【００１２】
本発明の課題は、上述の問題点に鑑み、配列Ａの要素の全てが領域Ｒ内でローカルでなくとも、配列圧縮の効果を得ることができる配列圧縮方法を提供することである。
【００１３】
【課題を解決するための手段】
図１は本発明の配列圧縮方法、すなわち配列のサイズを減少させて、ローカリティを向上させる配列圧縮方法の原理的な機能ブロック図である。
【００１４】
図１において、１で記憶装置に格納されているプログラムが読み出され、２でプログラムにおけるループネスト内の配列の要素のうちで、プログラム全体から見てそのループネスト内でローカルな要素だけが圧縮されて、スカラ変数に置き換える部分圧縮が行われ、３でローカルでない要素に対して元の配列へのアクセスがプログラム内に挿入される。
【００１５】
発明の実施の形態においては、配列の部分圧縮の前に行われるループネスト列内の圧縮候補配列の探索において、ループネスト列内の１つの配列が最初に出現するループネストを求め、そのループネスト内でその配列が定義が先行する要素の多い定義先行の配列であれば、その配列をループネスト列内での圧縮候補とすることもでき、この場合ループネスト列内圧縮候補配列探索の後で行われるプログラム内圧縮候補探索において、前述の１つの配列がプログラム内の他のループネスト列内で圧縮候補とされてない時、その１つの配列を圧縮の候補から除外することもできる。
【００１６】
実施の形態においては、部分圧縮の前に行われるループネスト列の複数のサブ・ループネスト列への分割において、前記圧縮候補の配列がループネスト内で定義先行であるような定義先行ループネストをサブループネスト列の先頭とするように分割を行うこともできる。
【００１７】
更に実施の形態においては、サブ・ループネスト列への分割と部分圧縮との間で行われるサブ・ループネスト列内のループネストの融合性チェックにおいて、各ループネストの多次元並列化処理から得られ、各ループの変数の変化方向が順方向か逆方向かを示す回転方向の情報と、そのループ変数が圧縮候補配列の添字中に出現する位置とに対応して、サブ・ループネスト列内のループネストの融合のために回転方向を逆転すべきループを決定することも、また各ループネスト内でのループの順序を示す情報と、そのループの変数が圧縮候補配列の添字中に出現する位置とに対応して、ループの順序を反転すべきループネストを決定することもできる。
【００１８】
本発明の配列圧縮方法においては、記憶装置に格納されているプログラムが読み出され、そのプログラムにおけるループネスト列内の１つの配列が最初に出現するループネストが求められ、そのループネスト内でその１つの配列が定義が先行する要素の多い定義先行の配列であればその配列がループネスト列内での圧縮候補とされ、圧縮候補とされた配列のうちから圧縮を行うべき配列が選択され、選択された配列の圧縮が行われる。
【００１９】
この場合、発明の実施の形態においては、配列の圧縮の前に前述のループネスト列のサブ・ループネスト列への分割を行うこともでき、またサブ・ループネスト列への分割の後で、前述のサブ・ループネスト列内のループネストの融合性チェックとして、回転方向を逆転すべきループの決定とループの順序を反転すべきループネストの決定を行うこともできる。
【００２０】
本発明において、プログラム内の配列のサイズを減少させるために計算機で使用されるプログラムとして、記憶装置内から対象となるプログラムを読み出す手順と、そのプログラムにおけるループネスト内の配列の要素のうちで、プログラム全体から見てそのループネスト内でのみローカルな要素を、スカラ変数に置き換える部分圧縮を行う手順と、ローカルでない要素に対しては、元の配列へのアクセスをプログラム内に挿入する手順とを計算機に実行させるためのプログラムが用いられる。
【００２１】
以上のように本発明によれば、ある領域に対して定義先行である配列を対象として、配列の部分圧縮が行われる。
【００２２】
【発明の実施の形態】
まず本実施形態における配列の部分圧縮について、図２によって説明する。図２はあるプログラムの一部を示し、このプログラム内での配列Ｔ（Ｉ）の圧縮について考える。
【００２３】
図２の上部の右側と左側のループネストは、プログラムの実行時における条件によってそのどちらかが実行される。しかしながら、プログラムのその次の実行時には、条件の変化によって以前の実行時には実行されなかったループネストの処理の実行が行われる可能性がある。したがって、いずれのループネストの処理が実行される場合でも、プログラム全体として配列の要素に矛盾が生じないように配列の圧縮を行う必要がある。
【００２４】
上部の左側のループネストにおいては配列Ｔ（Ｉ）の全ての要素、すなわちＴ（１）からＴ（Ｎ）まではループネスト内でまず定義され、その値が参照されて使用される。
【００２５】
これに対して右側のループネストにおいては、配列Ｔ（Ｉ）の要素のうち、Ｔ（２）からＴ（Ｎ−１）まではループネスト内でまず定義されてその値が参照される。しかしながらＴ（１）およびＴ（Ｎ）の２つの要素については、まず例えばメモリに格納されている値が参照されて、ループネスト内で再度定義が行われる。
【００２６】
従ってそれぞれのループネスト列でローカルであるのは、配列Ｔ（Ｉ）の要素のうちＴ（２）からＴ（Ｎ−１）だけであり、Ｔ（１）とＴ（Ｎ）の要素はローカルでなく、このローカルでない要素の圧縮を行うことはできない。そこでその他の要素だけを圧縮する部分圧縮を行うことにすると、それぞれのループネストは下に示すような形に変形される。
【００２７】
左側のループネスト内の配列Ｔ（Ｉ）は、従来例の図１５におけると同様に１つの要素Ｔ１のみに圧縮されるが、Ｉ＝１およびＩ＝Ｎに対してはこのＴ１の値を配列Ｔ（Ｉ）の要素として、例えばメモリ内に格納しておく必要がある。
【００２８】
右側のループネストでは、配列Ｔ（Ｉ）が左側と同様に１つの要素Ｔ１に置き換えられるが、Ｉ＝１およびＩ＝Ｎに対しては、Ｔ１の値はＴ（Ｉ）の値を参照にすることによって得られ、また最後にＩ＝１およびＮに対しては、Ｔ１の値を配列Ｔ（Ｉ）の要素としてメモリなどに格納しておくことになる。
【００２９】
このように本実施形態ではある配列が、例えば２つのループネスト内に出現する場合には、その２つのループネストで共にローカルな要素のみ圧縮が行われる。図２の例では、Ｎが十分大きければ圧縮される要素、すなわちＴ（２）からＴ（Ｎ−１）の数は多くなり、配列の部分圧縮によって配列のローカリティの向上が実現される。
【００３０】
ループネスト内で配列の多くの要素がローカルであるということは、配列Ａの要素のうちの多くの要素が、そのループネストの内部でまず最初に定義され、定義された後に必要に応じて参照されることである。このまず最初に定義されるということを、本実施形態では定義先行の配列と呼び、また配列Ａの全ての要素または大半の要素がそのループネスト内で定義先行である時に、そのループネストを定義先行ループネストと呼ぶことにする。
【００３１】
図３は配列Ａに対応する定義先行ループネストの例を示す。（ａ）ではＡの各要素の定義のみが存在し、（ｂ）ではＡの全ての要素の定義が参照に先行し、（ｃ）ではＩ＝２からＩ＝Ｎ−１までの要素が定義先行であり、Ｎが十分大きければ配列Ａの大半の要素が定義先行であることになる。このように配列ＡがループネストＬに対して定義先行であることが、部分圧縮のための好ましい条件となる。
【００３２】
これに対して配列Ａの要素のうち、大半のものがループネストの中で最初に参照される場合、すなわち配列Ａがループネストに対して参照先行である場合には、その配列Ａの部分圧縮を行っても、図２で説明したように最後に、例えばメモリに格納すべき要素の数が多くなり、全体としての処理の効率化には必ずしも結びつかない。
【００３３】
図４はそのような参照先行ループネストの例である。同図（ａ）では全ての要素の参照のみが行われており、（ｂ）では全ての要素の参照が最初に行われ、（ｃ）ではＩ＝ＫとＩ＝Ｋ＋１の２つの要素のみについて定義が先行し、その他の大半の要素は参照先行となっている。
【００３４】
このように部分圧縮を行うためには、配列ＡがループネストＬに対して定義先行であることが好ましいが、単にその条件を満足するループネストを探索するだけでは配列圧縮を効果的に行えることはまれであり、多くの場合、複数のループネストを融合することによって初めて配列の圧縮が可能となることが多い。
【００３５】
図５はこのようなループネストの融合の例である。同図の左側でＴ（Ｉ）を定義するループネストと、定義された配列Ｔ（Ｉ）を参照して配列Ａ（Ｉ）を定義するループネストとの列において、右側のように２つのループネストを融合することにより、図１５で説明したように配列の圧縮が可能となる。
【００３６】
このように配列圧縮を効果的に行うためには、ループネスト列内の複数のループネストをどのように融合すべきかを決定する必要がある。このことは、結局１つのループネスト列を複数のサブ・ループネスト列に分割し、各サブ・ループネスト列の内部で配列を圧縮することに相当する。図６はこのサブ・ループネスト列への分割の説明図である。同図においては、ループネストＬn0からＬn3までのループネスト列が、ループネストＬn0からＬn2までのサブ・ループネスト列０と、ループネストＬn3だけのサブ・ループネスト列１に分割されている。
【００３７】
図７は以上の説明に対応した配列圧縮処理の全体フローチャートである。同図において処理が開始されると、まずステップＳ１でループネスト列抽出、すなわちプログラムの中からループネスト列を選び出す処理が実行され、ステップＳ２でループネスト列内圧縮候補探索、すなわち各ループネスト列の中で圧縮の候補となる配列の探索が行われる。この探索においては、後述するように、その配列が定義先行であるか否かをチェックすることによって、圧縮候補の探索が行われる。
【００３８】
続いてステップＳ３で、プログラム全体から見ても圧縮の候補となる配列の探索が行われる。ここではステップＳ２で各ループネスト列内で圧縮の候補となった配列のうちで、他のループネスト列内で圧縮の候補とならなかった配列が除外されて、プログラム全体での圧縮候補の探索が行われる。
【００３９】
ステップＳ４ではループネスト列のサブ・ループネスト列への分割が行われる。この処理では、後述するようにループネスト列内で配列Ａが定義先行であるループネストの前でループネスト列が分割され、そのループネストから始まるループネスト列が新たなサブ・ループネスト列とされる分割処理が行われる。
【００４０】
ステップＳ５でループネスト並列化の処理が行われる。この処理では、各ループネストの内部のループが並行して実行可能となるような変換が行われる。この並列化の処理は公知の技術であるが、これについても更に後述する。
【００４１】
ステップＳ６でサブ・ループネスト列の融合性チェックが行われる。すなわち、サブ・ループネスト列の内部の複数のループネストが１つのループネストに融合できるか否かがチェックされる。融合可能か否かをチェックするためにループの方向、すなわちループの変数の変化が順方向か逆方向かがチェックされ、必要に応じて方向を逆転すべきループが決定される。
【００４２】
また順序チェックとしてネスト、すなわち入れ子の内部のループの順序がチェックされ、必要に応じて順序の変換が行われる。更に並列性のチェックとして、融合の結果並列処理が不可能となって逐次処理を行われなければならなくなることがないかがチェックされ、これらのチェックによって融合不可能と判定された場合には融合も、また融合によって可能となる配列の圧縮も実行されない。
【００４３】
ステップＳ７では融合可能と判定されたそれぞれのサブ・ループネスト列の中のループネストが１つのループネストに融合され、最後にステップＳ８で圧縮すべきことが決定した配列が圧縮されて、処理を終了する。
【００４４】
続いて図７の各ステップの処理について更に詳細に説明する。図８はステップＳ２におけるループネスト列内圧縮候補探索処理の詳細フローチャートである。同図において処理が開始されと、まずステップＳ１１で全てのループネスト列の集合がＳＬとされ、ステップＳ１２で集合ＳＬからループネスト（ＬＮ）列が１つ取り出され、ステップＳ１３でＬＮ列が取り出せたか否かが判定され、取り出せていない場合には処理を終了する。
【００４５】
取り出せた場合には、ステップＳ１４でそのループネスト列、すなわちＬＮ列内の配列の集合がＳＡとされ、ステップＳ１５で集合ＳＡから１つの配列Ａが取り出され、ステップＳ１６で配列Ａが取り出せたか否かが判定され、取り出せなかった場合にはそのループネスト列に対する処理を終了し、次のループネスト列に対する処理がステップＳ１２から繰り返される。
【００４６】
ステップＳ１６で配列Ａが取り出せた場合には、ステップＳ１７でその配列Ａが非候補配列集合、すなわち圧縮候補でない配列の集合内にあるか否かが判定され、ある場合にはステップＳ２１で集合ＳＡから配列Ａが除かれてこの配列Ａに対する処理を終わり、次の配列に対する処理がステップＳ１５から繰り返される。
【００４７】
ステップＳ１７でＡが非候補配列集合内に存在しない場合には、ステップＳ１８で配列Ａが最初に出現するループネストＬＮが求められ、ステップＳ１９で配列ＡがＬＮに対して定義先行であるか否かが判定され、定義先行でない場合にはステップＳ２０で集合ＳＡから配列Ａが除かれ、配列Ａが非候補配列集合に入れられた後にステップＳ１５からの処理が繰り返され、またステップＳ１９で配列Ａが定義先行である場合には、ステップＳ２０の処理を実行することなく、ステップＳ１５以降の処理が繰り返される。
【００４８】
図９は図７のステップＳ３におけるプログラム内圧縮候補探索処理の詳細フローチャートである。同図において処理が開始されると、ステップＳ２５で全てのループネスト列の集合がＳＬとされ、ステップＳ２６で集合ＳＬから１つのループネスト列が取り出され、ステップＳ２７でループネスト列が取り出せたか否かが判定され、取り出せない場合には処理を終了する。
【００４９】
取り出せた場合には、ステップＳ２８でそのＬＮ列に対する集合ＳＡ、すなわち図８のステップＳ１４でＬＮ列に対して求められた配列からステップＳ２０,Ｓ２１で配列が除かれた結果の配列の集合内に非候補配列集合、すなわち圧縮対象とならない配列の集合内の配列があるか否かが判定され、そのような配列があれば集合ＳＡからそれが除かれ、ステップＳ２６以降の処理が繰り返される。
【００５０】
図１０は図７のステップＳ４におけるループネスト列分割処理の詳細フローチャートである。同図において処理が開始されると、ステップＳ３１で全てのループネスト列の集合がＳＬとされ、ステップＳ３２で集合ＳＬから１つのループネスト（ＬＮ）列が取り出され、ステップＳ３３でＬＮ列が取り出せたか否かが判定され、、取り出せなかった場合には処理を終了する。
【００５１】
ＬＮ列が取り出せた場合には、ステップＳ３４でそのＬＮ列に対応する集合ＳＡが空か否かが判定され、空の場合にはステップＳ３２で次のループネスト列を取り出す処理以降が繰り返される。
【００５２】
集合ＳＡが空でない場合には、ステップＳ３５でＳＡから１つの配列Ａが取り出され、ステップＳ３６で配列Ａが取り出されたか否かが判定され、取り出せなかった場合にはステップＳ３２以降の処理が繰り返される。
【００５３】
取り出せた場合には、ステップＳ３７で配列Ａが含まれるループネスト（ＬＮ）の集合ＦＡが求められ、ステップＳ３８で集合ＦＡから１つの（最も上の）ループネストが取り出されてそれがＬＡとされ、ステップＳ３９でＬＡが取り出せたか否かが判定され、取り出せなかった場合には、次の配列ＡをＳＡから取り出すステップＳ３５以降の処理が繰り返される。
【００５４】
ステップＳ３９でＬＡが取り出せた場合には、ステップＳ４０でそのループネストＬＡに対して配列Ａが定義先行であるか否かが判定され、定義先行である場合には、ステップＳ４１でそのループネストＬＡの前でループネスト列が切られ、ＬＡから新たなサブ・ループネスト列とされた後に、またＡが定義先行でない場合には、直ちに次に上の配列ＬＮを取り出すステップＳ３８以降の処理が繰り返される。
【００５５】
続いて図７のステップＳ５でループネスト並列化の処理が行われる。ループネスト並列化とは、例えば図１４で説明した先頭のループネストにおいてＪ＝１からＭに対応するそれぞれのループの処理を複数のプロセッサ、例えばＭ台のプロセッサに割り当てて並列的に実行可能とする処理である。このような並列化が多くの次元に対して可能となるような並列化が行われる。この多次元並列化が行われると、例えば２次元の配列でＩについての１からＮ，Ｊについての１からＭまでの処理をすべて並列に実行することが可能となる。
【００５６】
この並列化処理では、できるだけ多くのループが逆転・順序交換可能となるような変換が行われる。ここで逆転とはループの変数の変化の方向が順方向であれば逆方向に、逆方向であれば順方向となるようにすることであり、また順序交換とはループネストの内部でのループの順序を交換することである。このような変換が行われた後には最も外側のＮ個のループが全ての実行文を囲んで、任意の順序で交換可能な形式となる。このような並列化については次の文献がある。
【００５７】
【非特許文献２】
中田育男著「コンパイラの構成と最適化」p.409  朝倉書店
次にステップＳ６でサブ・ループネスト列の融合性チェックが行われる。この処理では、前述のように融合を行うために逆転すべきループを決定するループ方向チェック、順序を交換すべきループを決定するループ順序チェック、および融合の結果逐次ループ化されないことをチェックする並列性チェックの３つが行われる。これらのチェックによって配列圧縮のために融合が必要であるにも拘わらず融合可能とならない場合には、ステップＳ７におけるサブ・ループネスト列融合およびステップＳ８の配列圧縮はそのサブ・ループネスト列内のループネストに対しては行われない。
【００５８】
この融合性チェックについて図１１のループネスト列の例を用いて更に説明する。Ｎ次元並列化されたループネストＬn において、その最外Ｎ個のループをｌ＝（ｌ1 ，・・・，ｌN ），ループ変数をｌv ＝（ｌv1，・・・・，ｌvN）とする。ｌi（１＜ｉ＜Ｎ）がｄｏａｌｌ並列化可能なら、ｌiは順方向および逆方向の双方で回転させることが可能であり、パイプライン並列化可能なら、どちらか一方のみでしか回転できない。ここで、ループ回転方向ベクタを
ｌｄvLn ＝（ｅ1 ，・・・，ｅN ）
と定義する。ただし、
【００５９】
【数１】
2004213113.tif 000003
【００６０】
である。
ここでｄｏａｌｌ並列化とは、前述のように例えばＪ＝１からＭまでの処理をＭ台のプロセッサに割り当てて並列実行させる場合にもプロセッサ間の同期が全く不要の条件で並列化することであり、パイプライン並列化とは、例えばＩ＝１についてＪ＝１〜Ｍの並列処理が終わってから、Ｉ＝２についての並列処理に移るような制限のある並列化である。
【００６１】
またＬn 中のＭ次元配列Ａに対し、部分データ依存ベクタ
ｐｄｖA:Ln＝（ｐｄｖA:Ln（１），・・・，ｐｄｖA:Ln（Ｍ））
を定義する。ただし、その各要素ｐｄｖA:Ln（ｉ）は、
・ループ変数ｌvj（１＜ｉ＜Ｎ）が配列Ａのｉ次元目の添字にしか出現せず、ループネスト中の全てのＡのｉ次元目の添字が同じで、ｉ次元目の添字には他のループ変数が出現しない場合、添字中のｌvjの係数が正ならｐｄｖA:Ln（ｉ）＝ｊ，負ならｐｄｖA:Ln（ｉ）＝−ｊ
・上記以外の場合には、ｐｄｖA:Ln（ｉ）＝０
である。
【００６２】
さて、本発明の手法では、各ループネストの並列化されたループどうしを融合する。２つのループネストＬn1，Ｌn2中にＭ次元配列Ａのみが存在する場合を考える。
【００６３】
ｐｄｖA:Ln1 （ｉ）＝ｉ1 ，ｐｄｖA:Ln1 （ｊ）＝ｊ1
ｐｄｖA:Ln2 （ｉ）＝ｉ2 ，ｐｄｖA:Ln2 （ｊ）＝ｊ2 （ｉ≠ｊ）とすると、以下が成り立つ。
【００６４】
（１）ｉ1 ＝０かつｉ2 ≠０ならば、Ｌn2中のｉ2 ループは融合の対象とならない。
（２）ｉ1 ≠０かつｉ2 ＝０ならば、Ｌn1中のｉ1 ループは融合の対象とならない。
【００６５】
（３）ｉ1 ≠０かつｉ2 ≠０の場合、ｉ1 とｉ2 の符号を等しくできれば、ｉ1 ループとｉ2 ループとを融合できる。
（４）ｉ1 とｉ2 ，ｊ1 とｊ2 の符号を等しくでき、それらが全て０でない場合、｜ｉ1 ｜と｜ｊ1 ｜との大小関係と｜ｉ2 ｜と｜ｊ2 ｜との大小関係が異なるならば、ｉ1 とｊ1 、あるいはｉ2 とｊ2 とをループ交換すれば、ｉ1 とｉ2 ，ｊ1 ，ｊ2 とを共に融合できる。
【００６６】
図１１のループＬn1においてＪ，Ｉについての２つのループがともにｄｏａｌｌ並列化可能であるとして、そのループ回転方向ベクタは（±１，±２）となる。
【００６７】
またＪはループ変数の順序で１、配列の添字として２次元、Ｉは順序で２、添字として１次元の変数であり、またｄｏａｌｌ並列化可能なことから符号として±を用いてＬn1の部分データ依存ベクタは（±２，±１）となる。
【００６８】
同様にして、
ｌｄｖLn1 ＝ｌｄｖLn2 ＝（±１，±２）
ｐｄｖA:Ln1 ＝（±２，±１），ｐｄｖA:Ln2 ＝（±２，±１）
である。Ｉ，Ｊループを共に融合する場合を考える。もし、Ｌn2のＩ，Ｊループの回転方向が共に逆転していれば、
ｐｄｖA:Ln1 ＝（±２，±１），ｐｄｖA:Ln2 ＝  外１
【００６９】
【外１】
2004213113.tif 000004
【００７０】
となる。２つのｐｄｖの要素の符号が逆転していることは、融合するためには、どちらかのループネストの各ループを逆転させる必要があることを示している。また、Ｌn2のループの入れ子の順番が逆になっていれば、
ｐｄｖA:Ln1 ＝（±２，±１），ｐｄｖA:Ln2 ＝（±１，±２）
となる。２つのｐｄｖの要素の順序が逆転していることは、融合するためには、どちらかのループネストをループ交換する必要があることを示している。
【００７１】
以上の処理によってサブ・ループネスト列の融合のためにループの逆転、順序交換などが行われ、ステップＳ７でサブ・ループネスト列の中のループネストが１つのループネストに融合され、図７のステップＳ８で圧縮の候補となっていた配列のうちで最終的に圧縮することが決定した配列の圧縮が行われる。
【００７２】
図１２はステップＳ８で行われる配列の部分圧縮の例である。同図で（ａ）には３つのループネスト列ＬＳ1 ，ＬＳ2 ，およびＬＳ3 がある。配列Ａはプログラム内でこれら３つのループネスト列以外には出現しないものとする。
【００７３】
図１２（ａ）は、同図（ｂ）のように変換できる。ＬＳ1 では（Ｓ１），（Ｓ２）で配列ＡがＡ１に置き換えられ、（Ｓ３）においてＬＳ2 やＬＳ3 による参照の可能性を考慮して、Ａ（１）とＡ（Ｎ）との値が配列Ａに書き戻されている。
【００７４】
ＬＳ2 では（Ｓ０）において、ＬＳ2 以外で定義されたＡ（１）の値がＡ（Ｉ）からロードされ、Ａ２（１）とされている。ＬＳ2 ではＡ（１）の値を更新しないため、（Ｓ３）においてＡ２（Ｎ）の値だけがＡ（Ｎ）に書き戻されている。ＬＳ3 はＬＳ2 と同様にして変換されている。
【００７５】
図１２（ｂ）のＡ１，Ａ２，およびＡ３は各ループネスト列内でローカルな配列となるため、それぞれ（ｃ）に示すようにスカラ変数に圧縮できる。このように一部の要素が参照先行的であっても、配列圧縮を行うことができる。この圧縮が部分圧縮であり、従来の配列圧縮を従来圧縮と呼ぶことにする。
【００７６】
図１２（ｃ）の各ループネスト列において、（Ｓ０）や（Ｓ３）があまり実行されなければ、例えばメモリ内の配列へのアクセスが減って、スカラ変数に対するアクセスがほとんどとなり、性能向上が見込まれる。すなわち部分圧縮により性能を向上させるためには、各ループネスト列内における参照先行的な要素をできるだけ少なくすることが必要である。参照先行的な要素がどの位であれば性能向上が見込めるかは一概にはいえないが、全ての要素の５〜１０％程度以下であれば、かなりの性能向上が見込めると判断して、部分圧縮を行うことにする。
【００７７】
但し図７のステップＳ８で行われる圧縮は部分圧縮に限定されず、従来圧縮を含むこともできる。ある配列が１つのループネスト列内でローカルであれば、その配列に対しては従来圧縮を適用できることは当然である。
【００７８】
部分圧縮を全く行うことがないという前提に立つ場合には、配列の圧縮方式は図７と異なる実現方式となると考えられるが、部分圧縮と従来圧縮とを並用する場合には図７で説明した実現方式が有効である。仮にステップＳ８で従来圧縮しか実行できない場合に、最初から部分圧縮を実行しないことを前提とする方式とのいずれが有効であるかは実現方式に依存すると考えられる。
【００７９】
以上説明した配列圧縮方式は、あるプログラムが作成され、そのプログラムが例えばあるコンピュータの記憶装置に格納された後に、同じコンピュータによってプログラムとして実行されることができる。図１３はそのようなプログラムのコンピュータへのローディングを説明する図である。
【００８０】
図１３においてコンピュータシステムは中央処理装置（ＣＰＵ）１０、リードオンリメモリ（ＲＯＭ）１１、ランダムアクセスメモリ（ＲＡＭ）１２、通信インタフェース１３、記憶装置１４、入出力装置１５、可搬型記憶媒体の読み取り装置１６、およびこれらの全てが接続されたバス１７によって構成されている。
【００８１】
記憶装置１４としてはハードディスク、磁気ディスクなど様々な形式の記憶装置を使用することができ、このような記憶装置１４、またはＲＯＭ１１に図７〜図１０のフローチャートに示されたプログラムや、本発明の特許請求の範囲の請求項１０のプログラムなどが格納され、そのようなプログラムがＣＰＵ１０によって実行されることにより、本実施形態における配列圧縮が可能となる。
【００８２】
このようなプログラムは、プログラム提供者１８側からネットワーク１９、および通信インタフェース１３を介して、例えば記憶装置１４に格納されることも、また市販され、流通している可搬型記憶媒体２０に格納され、読み取り装置１６にセットされて、ＣＰＵ１０によって実行されることも可能である。可搬型記憶媒体２０としてはＣＤ−ＲＯＭ、フレキシブルディスク、光ディスク、光磁気ディスクなど様々な形式の記憶媒体を使用することができ、このような記憶媒体に格納されたプログラムが読み取り装置１６によって読み取られることにより、例えば図７におけるループネスト列抽出から配列圧縮までの処理が可能となる。
【００８３】
【発明の効果】
以上詳細に説明したように、本発明によれば配列の圧縮方式として定義先行要素が多い配列に対する部分圧縮を行うことによって、配列のサイズを縮小し、使用メモリ量を削減し、かつローカリティを向上させることができる。特にループの融合を組み合わせることによって、圧縮を適用できる機会が増え、圧縮の効果が大きくなり、コンピュータの処理性能向上に寄与するところが大きい。
【図面の簡単な説明】
【図１】本発明の配列圧縮方式の原理的な機能ブロック図である。
【図２】配列の部分圧縮方法の説明図である。
【図３】定義先行ループネストの例を示す図である。
【図４】参照先行ループネストの例を示す図である。
【図５】ループネストの融合例の説明図である。
【図６】ループネスト列の分割の説明図である。
【図７】配列圧縮処理の全体フローチャートである。
【図８】ループネスト列内圧縮候補探索処理のフローチャートである。
【図９】プログラム内圧縮候補探索処理のフローチャートである。
【図１０】ループネスト列分割処理のフローチャートである。
【図１１】融合性チェックの対象としてのループネスト列を示す図である。
【図１２】配列部分圧縮の例を説明する図である。
【図１３】本発明におけるプログラムのコンピュータへのローディングを説明する図である。
【図１４】ループネストとループネスト列の説明図である。
【図１５】配列圧縮の従来方式の説明図である。
【符号の説明】
１０      中央処理装置（ＣＰＵ）
１１      リードオンリメモリ（ＲＯＭ）
１２      ランダムアクセスメモリ（ＲＡＭ）
１４      記憶装置
１９      ネットワーク
２０      可搬型記憶媒体
【図１】
2004213113.tif 000005
【図２】
2004213113.tif 000006
【図３】
2004213113.tif 000007
【図４】
2004213113.tif 000008
【図５】
2004213113.tif 000009
【図６】
2004213113.tif 000010
【図７】
2004213113.tif 000011
【図８】
2004213113.tif 000012
【図９】
2004213113.tif 000013
【図１０】
2004213113.tif 000014
【図１１】
2004213113.tif 000015
【図１２】
2004213113.tif 000016
【図１３】
2004213113.tif 000017
【図１４】
2004213113.tif 000018
【図１５】
2004213113.tif 000019