プロセッサによって実行可能なコードの生成方法、記憶領域の管理方法及びコード生成プログラム
【課題】ソフトウェアによる簡単なコヒーレンシ制御を提供する。
【解決手段】マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを、コンパイラによって生成する方法であって、プロセッサによって実行されるプログラムを解析し、前記プログラムに含まれる各タスクの実行に必要なデータを解析し、前記解析の結果に基づいて、前記プログラムを前記各タスクに分割した場合に、前記分割されたタスクによって使用されるデータの境界がメモリの管理単位と整合するか否かを判定し、前記タスクによって使用されるデータの境界がメモリの管理単位と整合しないと判定された場合、データが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を用いて、当該境界を含む管理単位に格納されたデータを演算するコードを生成することを特徴とするコードの生成方法。
【解決手段】マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを、コンパイラによって生成する方法であって、プロセッサによって実行されるプログラムを解析し、前記プログラムに含まれる各タスクの実行に必要なデータを解析し、前記解析の結果に基づいて、前記プログラムを前記各タスクに分割した場合に、前記分割されたタスクによって使用されるデータの境界がメモリの管理単位と整合するか否かを判定し、前記タスクによって使用されるデータの境界がメモリの管理単位と整合しないと判定された場合、データが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を用いて、当該境界を含む管理単位に格納されたデータを演算するコードを生成することを特徴とするコードの生成方法。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、複数のプロセシングエレメントによって構成されるマルチプロセッサにおけるメモリの管理方法に関し、特に、コンパイラが取得した情報に基づいて、共有メモリに格納されたデータの一貫性(コヒーレンシ)を保つように制御する方法に関する。
【背景技術】
【0002】
複数のプロセシングエレメントを集積したマルチプロセッサが、各マイクロプロセッサメーカによって次々に発表されている。スーパーコンピュータ、サーバ、デスクトップコンピュータ及びPCサーバ分野の他、情報家電及び装置組み込みの分野(例えば、携帯電話機、ゲーム機、カーナビゲーションシステム、デジタルテレビ受像機、HDD/DVDレコーダ・プレーヤ等)においても、マイクロプロセッサのマルチコア化の動きが見られる。
【0003】
マルチプロセッサは、複数のプロセシングエレメント、内部結合網及び集中共有メモリを備え、各プロセシングエレメントは、プロセッサ及びキャッシュメモリを備え、独立に演算処理を行うものである。このような構成のマルチプロセッサは、集中共有メモリを主記憶として使用し、複数のプロセッシングエレメントが、集中共有メモリに格納された同一のデータをアクセスする主記憶共有型プロセッサとして使用される。
【0004】
このとき、共有データ間のコヒーレンシを保つために、あるプロセッサがキャッシュメモリ上の共有データをアクセスしている場合、他のプロセッサが当該共有データを集中共有メモリからキャッシュメモリへのアクセスを禁止するコヒーレンシ制御が必要となっていた。
【0005】
ここで、コヒーレンシとは、ある時刻において、メモリのあるアドレスに格納された値を、全てのプロセッサが同一の値としてアクセスできることであり、主記憶共有型マルチプロセッサにおいて、各プロセッサからアクセスされるメモリの内容が同一であることを保証するための制御である。コヒーレンシを保つための機能には、ハードウェアによってメモリアクセスを制御するコヒーレントキャッシュがある。
【0006】
コヒーレンシ制御において解決しなければならない第1の問題はデータの陳腐化(Stale Data)であり、第2の問題はフォルスシェアリング(False Sharing)である。
【0007】
図22は、コヒーレンシ制御における第1の問題点(ステイルデータ)を説明する図である。
【0008】
まず、グローバル変数a、b、cが宣言され(2200)、共有メモリに変数a=0,b=0,c=1が格納された(2201)。
【0009】
その後、あるプロセシングエレメント(PE0)のキャッシュメモリに共有データ(a=0、b=0、c=1)が格納されており(2202)、他のプロセシングエレメント(PE1)のキャッシュメモリにも同じ共有データが格納されている(2203)場合、PE0で当該共有データが更新(a=0→1)されても、PE1のキャッシュ上の共有データは更新されていない古いデータ(a=0)である(2205)。この状態で、PE1で当該共有データが更新(c=a)されると、変数cは正しいaの値を反映することなく0に更新されてしまう(2206)。
【0010】
このため、コヒーレンシ制御がされていれば、a=1、b=0、c=1であるはずの変数が、a=0、b=0、c=0となる。このため、PE0のキャッシュメモリに格納されているデータと、PE1のキャッシュメモリに格納されているデータとが不一致となる。このため、PE1が誤った動作をしてしまう。
【0011】
図23は、コヒーレンシ制御における第2の問題点(フォルスシェアリング)を説明する図である。
【0012】
まず、グローバル変数a、bが宣言され(2300)、変数a=0、b=0が共有メモリに格納された(2301)。この変数a及びbは、共有メモリの同じキャッシュライン上に格納されている。また、共有メモリは、ライン単位でアクセスされる。
【0013】
その後、あるプロセシングエレメント(PE0)のキャッシュメモリに格納された共有データが更新(a=0→1)され(2302)、他のプロセシングエレメント(PE1)のキャッシュメモリに格納された共有データが更新(b=0→2)された(2303)。すなわち各プロセッシングエレメントが、同一のライン上に格納された異なる変数を更新した。この場合、PE0が先に共有メモリにデータを書き戻せば、後にデータを書き戻したPE1のデータが共有メモリに格納される(2304)。一方、PE1が先に共有メモリにデータを書き戻せば、後にデータを書き戻したPE0のデータが共有メモリに格納される(2305)。
【0014】
コヒーレンシ制御がされている場合、共有メモリにはa=1、b=2が格納されるが、コヒーレンシ制御がされない場合、最終的にどのデータが共有メモリに格納されるかは定まらない。すなわち、ライン吐き出しタイミングによりメモリの内容が異なり、いずれにせよプロセッシングエレメントは誤った動作をしてしまう。
【0015】
このような共有メモリとキャッシュメモリとの間での不一致が生じる問題点を解決するために、各プロセッシングエレメント及び共有資源(内部結合網、共有メモリ等)にコヒーレンシ制御部を設けることによって、メモリに格納されたデータのコヒーレンシを保つ。
【0016】
具体的には、あるプロセシングエレメント(PE0)がデータxを共有メモリから読み出した後に、PE0がデータxを共有メモリから読み出して、それを更新し、データxの所有権を破棄するまで、他のプロセシングエレメント(PE1)による共有メモリのデータxへの書き込みは許可されない。
【0017】
このような所有権制御によって、データの陳腐化(Stale Data)及びフォルスシェアリング(False Sharing)のコヒーレンシ制御の問題を解決することができる。
【先行技術文献】
【特許文献】
【0018】
【特許文献1】特開2004−30362号公報
【特許文献2】特開平9−44403号公報
【発明の概要】
【発明が解決しようとする課題】
【0019】
しかし、ハードウェアによってメモリアクセスを所有権制御するコヒーレントキャッシュでは、ハードウェアのコストのために、プロセッサ数の増加によって、マルチプロセッサのコストが上昇する。また、ハードウェアによってメモリアクセスを制御することによって、メモリアクセスが遅くなる。
【0020】
さらに、ハードウェアによるコヒーレンシ制御では、イベント毎に全てのプロセッサ、メモリ及びバス制御機構に信号を送るので、実行時のオーバーヘッドが生じる。このオーバーヘッドは、マルチプロセッサに含まれるプロセッサ数に応じて増加する。このため、プロセッサ数が増加した場合、コヒーレンシ制御のための通信でバスが埋まってしまい、プロセッサの動作を妨げる。
【0021】
このため、より簡単なハードウェア構成によるコヒーレンシ制御、特にソフトウェアによるコヒーレンシ制御が求められている。
【課題を解決するための手段】
【0022】
本発明のコンパイラは、プログラムを解析して得られるコントロールフロー及びデータ依存関係の情報を用いて、ソフトウェアによる明示的なキャッシュ操作コードを生成する。また、異なるプロセシングエレメントによって使用される変数が、同じキャッシュラインに載らないように配置する。
【発明の効果】
【0023】
本発明によれば、ソフトウェアによる制御によって、コヒーレンシ制御のためのハードウェアが不要となり、ハードウェアを簡素化できる。このため、低コストかつ低消費電力のマルチプロセッサを実現できる。
【図面の簡単な説明】
【0024】
【図1】本発明の実施の形態のマルチプロセッサの構成図である。
【図2】本発明の実施の形態のマルチプロセッサのキャッシュメモリの各ラインがとりうる状態を説明する図である。
【図3A】本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【図3B】本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【図4】本発明の実施の形態のフォルスシェアリングの発生を避ける方法の概要を説明する図である。
【図5A】一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図5B】一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図6A】本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図6B】本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図7A】本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図7B】本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8B】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8C】本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が集中共有メモリに設けられた場合の例を示す。
【図8D】本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリに設けられた場合の例を示す。
【図9A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図9B】図9Aに示す変形例におけるノンキャッシャブル領域が集中共有メモリに設けられた場合の例を示す。
【図9C】図9Aに示す変形例におけるノンキャッシャブル領域が分散共有メモリに設けられた場合の例を示す。
【図10A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図10B】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図11】本発明の第4の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図12A】多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図12B】多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図13A】第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【図13B】第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【図14A】第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【図14B】第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【図15A】第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【図15B】第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【図16】第4の実施の形態を2次元配列変数に適用した例を説明する図である。
【図17A】本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【図17B】本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【図17C】本発明の実施の形態のフォルスシェアリングを検出するためのコードの例を説明する図ある。
【図18】本発明の実施の形態の並列化コンパイラによるソフトウェアコヒーレンシ制御コードを生成する処理の概要を説明する図である。
【図19】本発明の実施の形態のコンパイラによって実行される処理のフローチャートである。
【図20A】本発明の実施の形態のフォルスシェアリング回避処理のフローチャートである。
【図20B】本発明の実施の形態のフォルスシェアリング回避処理のフローチャートである。
【図21】本発明の実施の形態のキャッシュ操作指示の挿入処理のフローチャートである。
【図22】コヒーレンシ制御における第1の問題点(ステイルデータ)を説明する図である。
【図23】コヒーレンシ制御における第2の問題点(フォルスシェアリング)を説明する図である。
【発明を実施するための形態】
【0025】
図1は、本発明の実施の形態のマルチプロセッサの構成図である。
【0026】
本発明の実施形態のマルチプロセッサは、複数のプロセシングエレメント(PE0、PE1、…、PEn)100、110、120、内部結合網150、及び集中共有メモリ160を備える。
【0027】
プロセシングエレメント100は、演算処理をするプロセッサ101、データを一時的に格納するキャッシュメモリ102、分散共有メモリ(DSM)103及びデータ転送コントローラを備え、独立に動作する。
【0028】
プロセッサ101は、整数演算及び浮動小数点演算が可能なものであればよく、その機能は特に限定されない。例えば、データのロード及びストアのアーキテクチャが単純なシングルイッシューRISCアーキテクチャのCPUを用いてもよい。また、スーパースカラプロセッサ、VLIWプロセッサ等も用いてもよい。
【0029】
キャッシュメモリ102は、集中共有メモリ160からプロセッサ101によって読み込まれたデータを一時的に格納するメモリである。プロセッサ101は、キャッシュメモリ102に格納されたデータを用いて演算処理をする。プロセッサ101による演算処理が終了すると、キャッシュメモリ102に格納されたデータは集中共有メモリ160に書き戻される。このキャッシュメモリ102と集中共有メモリ160との間では、ライン毎にデータが読み書きされる。このラインは、キャッシュメモリ102に格納されたデータの管理単位である。
【0030】
なお、プロセッシングエレメント100は、キャッシュメモリ102を二次キャッシュとして使用し、キャッシュメモリ102の他に一次キャッシュを備えてもよい。この場合、一次キャッシュと二次キャッシュ(キャッシュメモリ102)とは、コヒーレンシ制御がされてもよい。すなわち、本発明の実施の形態のマルチプロセッサでは、主記憶として機能する集中共有メモリ160と最外側のキャッシュメモリ102との間でデータの一致を保つコヒーレンシ機能を有さない。
【0031】
分散共有メモリ103は、格納されたデータを他のプロセシングエレメントから直接読み書きすることができるメモリである。なお、分散共有メモリ103がデュアルポートメモリで構成されていると、プロセッサ101とデータ転送コントローラとが競合することなく分散共有メモリにアクセスすることができる。なお、分散共有メモリ103は、本実施の形態のマルチプロセッサに必須の構成ではない。
【0032】
データ転送コントローラは、プロセッシングエレメントに備わるメモリに格納されたデータをプロセッシングエレメント間で転送する。
【0033】
さらに、プロセシングエレメント100は、図示した構成の他、ローカルプログラムメモリ、ローカルデータメモリ、ネットワークインターフェイス及び電力制御レジスタを備えてもよい。
【0034】
なお、プロセシングエレメント110、120も、プロセシングエレメント100と同じ構成を有する。
【0035】
内部結合網150は、既存の接続技術(クロスバースイッチ、バス、マルチステージネットワーク等)によって実現され、複数のプロセシングエレメント100等及び集中共有メモリ160を接続する。
【0036】
集中共有メモリ160(CSM)は、システム中の全プロセシングエレメント100等によって共有されるデータが格納される主記憶として機能し、各プロセシングエレメント100等からアクセス可能なメモリである。
【0037】
なお、本実施の形態のマルチプロセッサは、キャッシュメモリ102等と集中共有メモリ160との間でデータの一致を保つための、ハードウェアによるコヒーレンシ機能を有さない。
【0038】
<ステイルデータの解決>
まず、第1の課題であるステイルデータの発生を避ける方法について説明する。
【0039】
本発明の実施の形態のマルチプロセッサは、前述したように、キャッシュメモリ102等と集中共有メモリ160との間でデータの一致を保つための、ハードウェアによるコヒーレンシ機能を有さない。このため、あるプロセッシングエレメントがキャッシュメモリ上でデータを更新した場合、このデータ更新は他のプロセッシングエレメントに通知されない。また、更新されたデータが書き戻されるまで、更新されたデータは集中共有メモリ160にも反映されない。
【0040】
このため、本発明の実施の形態のコンパイラは、プログラムを解析した結果(データコントロールフロー、データ依存関係)に基づいて、ソフトウェアによる明示的なキャッシュ操作コードを生成する。
【0041】
生成されるキャッシュ操作コードは、その命令が実行されるプロセッシングエレメントのキャッシュメモリに格納されたデータを操作する命令だけであり、ハードウェアによるコヒーレンシプロトコルにおけるキャッシュ操作要求のような、他プロセッシングエレメントのキャッシュメモリに格納されたデータの状態を操作する命令ではない。生成されるキャッシュ操作コードは、ライトバック、セルフインバリデート、パージの3種類がある。
【0042】
ライトバック(writeback)は、キャッシュメモリ102に格納されたデータを集中共有メモリ160に書き戻すための命令である。キャッシュメモリ102上でデータが更新され、集中共有メモリ160上の対応するアドレスに格納されるデータと異なる場合、ラインの状態はダーティとなり、キャッシュメモリ102に格納されたデータを、集中共有メモリ160に書き戻す必要がある。
【0043】
なお、キャッシュメモリ102のラインリプレースに伴うデータの書き戻し(auto−writeback)によっても、集中共有メモリ160へデータが書き戻される。
【0044】
セルフインバリデート(self−invalidate)は、キャッシュメモリ102のラインを無効化するための命令である。セルフインバリデートされ、インバリデート状態になったデータは、キャッシュメモリに格納されていても、再度集中共有メモリ160から読み込むまで使用することができない。
【0045】
パージ(purge)は、キャッシュメモリ102のラインに格納されたデータを書き戻した(ライトバック)後、セルフインバリデート実行するための命令である。
【0046】
また、各プロセッシングエレメントで実行されるタスク間で通信が発生する箇所にキャッシュ操作コードが挿入される。
【0047】
さらに、コンパイラは、異なるプロセッシングエレメントが同一ラインのデータを保持している場合、異なるプロセッシングエレメントに格納された同一ラインのデータを同時に更新しないように制御する。
【0048】
図2は、本発明の実施の形態のマルチプロセッサのキャッシュメモリ102の各ラインがとりうる状態を説明する図である。
【0049】
キャッシュメモリ102は、ライン毎に、Modified、Valid、Stale、Invalidの4状態をとる。
【0050】
Modifiedは、キャッシュメモリ102に格納されたデータが更新されたダーティデータで、集中共有メモリ160上の対応するアドレスに格納されるデータと異なっている状態である。この場合、ライトバックによって、キャッシュメモリ102に格納されたデータを集中共有メモリ160に書き戻す必要がある。
【0051】
Validは、キャッシュメモリ102に格納されたデータが集中共有メモリ160上の対応するアドレスに格納されるデータと一致しているクリーン状態である。
【0052】
Staleは、キャッシュメモリ102に格納されたデータと同期すべきデータが他のプロセッシングエレメントによって書き換えられたが、まだ当該更新データは集中共有メモリ160に書き戻されていないため、当該キャッシュデータは集中共有メモリ160上の対応するアドレスに格納されるデータとが一致しているクリーン状態である。
【0053】
Invalidは、キャッシュメモリ102に格納されたデータと一致していないデータである可能性がある状態である。
【0054】
前述した4状態は、キャッシュメモリ102へのアクセス、及び、キャッシュ操作によって遷移する。
【0055】
キャッシュメモリ102へのアクセスには、プロセッサ101による集中共有メモリ160からのデータの読み込み(read)、プロセッサ101によるキャッシュメモリ102へのデータの書き込み(write)がある。
【0056】
本発明の実施の形態のコンパイラは、複数のプロセッシングエレメントのキャッシュメモリに格納された同一ラインのデータが、同時にModifiedとならないように制御する。また、本実施の形態のコンパイラは、Staleのデータを読み書きしないように制御する。
【0057】
図3A及び図3Bは、本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【0058】
本発明の実施の形態のコンパイラは、プロセッシングエレメントをまたがるデータ依存が存在する場合、データ依存のエッジでデータを同期する。例えば、コンパイラがプログラムの解析によって検出すべきデータ依存のエッジは、フロー依存によって生じるdef−useの関係である。
【0059】
例えば、図3Aに示すように、PE0がタスクブロック1(SB1)で変数Aを定義した(300)後、PE1がタスクブロック3(SB3)で変数Aを使用する場合、図3Bに示すように、PE0による変数Aの更新によって、PE1は変数Aが格納されているラインの状態をinvalidateへ変更する(302)。また、PE0が変数Aを集中共有メモリに書き戻した(301)後に、PE1が変数Aを使用する。
【0060】
より具体的には、コンパイラは、PE0が更新した変数Aを、他のプロセッシングエレメント(PE1)で使用する前に、ライトバック命令(301)を挿入する。この場合、次に自プロセシングエレメント(PE0)が変数Aが使用する場合は、ライトバック命令を挿入せず、他のプロセッシングエレメント(PE1)が変数Aを使用する前にライトバック命令を挿入すればよい。
【0061】
さらに、コンパイラは、フラグ変数を用いたプロセッシングエレメント間のデータ同期のために、同期の送信側(PE0)は、同期フラグ変数(sync_flg)に同期を示す値を書き込む命令(302)、及び、その同期フラグ変数が格納されているキャッシュメモリのラインを集中共有メモリに書き戻す命令(303)を挿入する。
【0062】
一方、PE1について、コンパイラは、他のプロセシングエレメント(PE0)によって更新された変数Aを使用する前にセルフインバリデート命令(304)を挿入する。なお、セルフインバリデート命令(304)が挿入される箇所(セルフインバリデートのタイミング)は、変数Aを使用する直前が望ましい。
【0063】
さらに、コンパイラは、同期フラグ変数(sync_flg)のインバリデート及び読み込みを繰り返し、同期フラグ変数の値が同期を示す値に更新されるまでビジーウェイト状態で待機する命令(305)を挿入する。
【0064】
PE1は、変数Aがインバリデートされており、キャッシュメモリ上の変数Aを使用できないため、変数Aを集中共有メモリ160からキャッシュメモリにロードし、PE0で更新された変数Aを取得する。
【0065】
以上、def−useの関係について説明したが、出力依存によって生じるdef−defの関係、use−defによる逆依存の関係、use−useによる入力依存の関係でも同様のことが生じうる。
【0066】
このように、本実施の形態のコンパイラは、タスク間のフロー依存及び出力依存を解析した結果に応じてキャッシュ操作命令を挿入するので、コヒーレンシ制御をすることなく、ステイルデータを消費することがない。
【0067】
<フォルスシェアリングの解決>
次に、第2の課題であるフォルスシェアリングの発生を避けるための方法について説明する。
【0068】
図4は、本発明の実施の形態のフォルスシェアリングの発生を避ける方法の概要を説明する図である。
【0069】
本実施の形態では、各プロセシングエレメントによって使用される変数が、同じキャッシュラインに載らないように、各変数がキャッシュラインの先頭に配置される(アラインメント)を行う。なお、変数のアライメントは、配列変数の宣言において指定しても、別に設定ファイル等に記述してもよい。
【0070】
まず、図23で前述したと同様に、グローバル変数a、bが宣言され(400)、変数a=0、b=0が集中共有メモリ160に格納された。しかし、本発明の実施の形態では、図23で前述したと異なり、宣言されたグローバル変数a、bは集中共有メモリ160のキャッシュラインの先頭に配置されるので、異なるライン上に格納される。
【0071】
その後、あるプロセシングエレメント(PE0)のキャッシュ上の共有データが更新(a=0→1)され(401)、他のプロセシングエレメント(PE1)のキャッシュ上の共有データが更新(b=0→2)された(402)。しかし、各プロセッシングエレメントは、異なるライン上に格納された異なる変数を更新したので、各プロセシングエレメントがいかなるタイミングでキャッシュメモリに格納されたデータを集中共有メモリ160に書き戻しても(404、405)、正しいデータ(a=1、b=2)が集中共有メモリ160格納される。
【0072】
次に、一次元配列を扱う場合について説明する。
【0073】
図5A及び図5Bは、一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【0074】
まず、図5Bに示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(500)。本実施の形態ではキャッシュメモリの1ラインが16バイトであり、1ラインに4個の変数が格納できる場合を考える。このため、図5Aに示すように、キャッシュメモリの第1ライン511にはa[0]からa[3]が格納されており、第2ライン512にはa[4]からa[7]が格納されており、第5ライン515にはa[16]からa[19]が格納されている。
【0075】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ102上で処理し(501)、プロセッシングエレメント(PE1)110が変数a[i](18≦i<36)をキャッシュメモリ112上で処理し(502)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻す。
【0076】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。PE0によって処理されるa[16]及びa[17]と、PE1によって処理されるa[18]及びa[19]とが第5ライン515上に存在することから、このライン上でPE0によるアクセスとPE1によるアクセスとが競合しフォルスシェアリングが発生する。
【0077】
図6A及び図6Bは、本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0078】
第1の実施の形態の方法では、図6Aに示すように、グローバル変数aの各要素を集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置することによって、各要素を異なるラインに配置する。このため、キャッシュラインの境界で処理が分割される。
【0079】
まず、図6Bに示すように、グローバル変数aが宣言され、変数aに含まれる36個の配列変数の各要素が集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(600)。
【0080】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)を処理し(601)、プロセッシングエレメント(PE1)110が変数a[i](18≦i<36)を処理し(602)、PE0及びPE1が処理の結果を集中共有メモリ160に書き戻す。しかし、図5Aを用いて前述した場合と異なり、図6Bに示すように、PE0とPE1とは集中共有メモリ160の同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0081】
なお、本実施の形態では、1ラインは4個の変数が格納できる容量を有するが、1ラインに1個の変数しか格納されていないので、キャッシュメモリの利用効率が低下する。このため、本実施の形態は、配列変数の要素の数が少ない場合に有効である。また、同一のプロセッシングエレメントが、配列変数の異なる添字の要素(a(i)、a(i+1))にアクセスするような間接メモリアクセスをする場合にも有効である。
【0082】
図7A及び図7Bは、本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0083】
フォルスシェアリングは、図5Aを用いて前述したように、異なるプロセッシングエレメントによって処理されたデータがキャッシュメモリの1ライン上に格納されることによって発生する。このため、本実施の形態では、図7Aに示すように、キャッシュメモリのラインの境界によって、各プロセッシングエレメントが処理するデータを分け、複数のプロセッシングエレメントによって処理されるデータがキャッシュメモリの1ライン上に格納されないようにする。
【0084】
まず、図7Bに示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(700)。
【0085】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<16)を処理し(701)、プロセッシングエレメント(PE1)110が変数a[i](16≦i<36)を処理する(702)。その後、PE0が処理の結果をキャッシュメモリ102から集中共有メモリ160に書き戻し、PE1が処理の結果をキャッシュメモリ112から集中共有メモリ160に書き戻す。
【0086】
本実施の形態では、1ラインは4個の変数が格納できる容量を有するので、各プロセッシングエレメントが、キャッシュラインサイズである4の倍数の配列変数の要素を処理するようにしている。このため、図7Aに示すように、PE0のアクセス範囲とPE1のアクセス範囲とはキャッシュメモリのラインの境界で分けられ、PE0とPE1とはキャッシュメモリの同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0087】
なお、本実施の形態ではPE0に16個、PE1に20個の配列変数の処理を割り当てたが、キャッシュラインサイズ(1ラインに格納できる配列変数の要素数)の倍数になるように分ければ、PE0に20個、PE1に16個の配列変数の処理を割り当てても、よい。また、各プロセッシングエレメントの処理能力の比に従って数の配列変数の処理を割り当ててもよい。
【0088】
なお、本実施の形態では、キャッシュラインサイズ、配列変数の要素の数及びプロセッシングエレメントの数によっては、各プロセッシングエレメントに割り当てられる配列変数の要素の数が等しくならず、プロセッシングエレメントの処理負荷の不均衡が生じる場合がある。このため、本実施の形態は、配列サイズが十分に大きく、不均衡が配列サイズに比べて無視できるほど小さい場合に有効である。
【0089】
図8A及び図8Bは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0090】
第3の実施の形態では、処理の境界においてノンキャッシャブル領域を用いることによって、フォルスシェアリングの発生を避ける。
【0091】
まず、図8Bに示すように、グローバル変数a及び変数ncbufが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置され、配列変数4個のサイズの変数ncbufがノンキャッシャブル領域に設けられる(800)。
【0092】
ノンキャッシャブル領域とは、プロセッシングエレメントが当該領域に格納されたデータをメモリから読み込んだ場合に、当該読み込まれたデータを各プロセッシングエレメントのキャッシュメモリにロードしないで使用される領域である。ノンキャッシャブル領域は、メモリの領域(アドレス)又は特定の変数をノンキャッシャブルに指定することによって、通常のキャッシャブル領域と区別される。このノンキャッシャブルの指定は、所定の設定ファイルによって予め定めておいてもよいし、変数を宣言する命令によって定めてもよい。
【0093】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](18、19)をncbuf[i](i=2、3)を用いてノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0094】
PE0は、その後又は処理803と並行して、PE1で処理された変数ncbuf[i](i=2、3)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。このデータ依存によって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0095】
その後、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻す。
【0096】
このように、第3の実施の形態では、図8Aに示すように、PE1がノンキャッシャブルバッファを用いて演算した結果をPE0のキャッシュメモリの変数に反映する。すなわち、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、一方のプロセシングエレメント(PE1)はキャッシュメモリ内に設けられたノンキャッシャブル領域に当該ライン上のデータを格納し、他方のプロセシングエレメント(PE0)はノンキャッシャブル領域のデータを集中共有メモリに格納するので、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0097】
なお、ライン811〜814に格納されたデータはPE0のみによって使用され、ライン811〜814に格納されたデータはPE0のみによって使用されるので、ライン811〜814及びライン816〜819をキャッシュメモリ上でローカライズしてもよい。ローカライズされたデータは、主記憶に書き戻されず、次にPE0が使用するまでキャッシュメモリ上に保持される。同様に、ライン811〜814に格納されるべきデータ及びライン816〜819に格納されるべきデータをローカルメモリに格納してもよい。
【0098】
すなわち、第5ライン815のみがキャッシュメモリ上(キャッシャブル領域上)にあればよく、そのほかの領域(ライン811〜814、ライン816〜819)はキャッシャブル領域上に存在していなくてもよい。
【0099】
なお、本実施の形態ではメモリ上にノンキャッシャブル領域を設ける必要があるが、ノンキャッシャブル領域は、集中共有メモリ、分散共有メモリ等の何れのメモリに設けてもよい。また、本実施の形態では、ノンキャッシャブル領域からキャッシュメモリにデータをコピーする処理のオーバーヘッドが生じる。しかし、ノンキャッシャブルのバッファとして分散共有メモリを利用することによって、低オーバーヘッドでデータの転送を実現することができる。
【0100】
この第3の実施の形態の方法は、前述した第2の実施の形態の方法によっては分割が不可能な場合や、配列が拡張できない場合に有効である。
【0101】
図8Cは、本発明の第3の実施の形態においてノンキャッシャブル領域が集中共有メモリ160に設けられた場合の例を示す。図8Cに示す例では、集中共有メモリ160の一部の領域がノンキャッシャブル領域に指定されている。
【0102】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を、ncbuf[i](i=2、3)を用いて集中共有メモリ160に設けられたノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0103】
その後、PE1で処理された変数ncbuf[i](i=2、3)を集中共有メモリ160のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0104】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0105】
図8Dは、本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリ103に設けられた場合の例を示す。図8Dに示す例では、分散共有メモリ103の一部の領域がノンキャッシャブル領域に指定されている。
【0106】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を、ncbuf[i](i=2、3)を用いてPE0の分散共有メモリ103に設けられたノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0107】
その後、PE1で処理された変数ncbuf[i](i=2、3)を分散共有メモリ103のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0108】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0109】
図9Aは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0110】
図9Aで説明する変形例は、前述した例と異なり、各プロセシングエレメントが自己のメモリ上で演算し、その演算結果をノンキャッシャブル領域に転送することによって、フォルスシェアリングの発生を避ける。このため、他のメモリ、プロセシングエレメント等へのアクセスを減らし、処理を高速化することができる。
【0111】
まず、図9Aに示すように、グローバル変数a及び変数ncbuf及びlocalbuf_pe1が宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される。また、配列変数4個のサイズの変数ncbufがノンキャッシャブル領域に設けられ、配列変数4個のサイズの変数localbuf_pe1がノンキャッシャブル領域に設けられる(900)。なお、変数Localbuf_pe1はプロセッシングエレメント(PE1)110のみで使用されるので、ローカル変数でよい。
【0112】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)をlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3)をncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0113】
PE0は、その後又は処理904と並行して、PE1で処理された変数ncbuf[i](i=2、3)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。このデータ依存によって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0114】
その後、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻す。
【0115】
図9Bは、本発明の第3の実施の形態においてノンキャッシャブル領域が集中共有メモリ160に設けられ、演算領域(localbuf_pe1)がPE1のメモリに設けられた場合の例を示す。この演算領域が設けられるPE1のメモリは、ローカルメモリでも、分散共有メモリでも、キャッシュメモリでもよい。
【0116】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)を、PE1のメモリ上に設けられたlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3))を集中共有メモリ160に設けられたノンキャッシャブル領域上のncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0117】
その後、PE1で処理された変数ncbuf[i](i=2、3)を集中共有メモリ160のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0118】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0119】
図9Cは、本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリ103に設けられ、演算領域(localbuf_pe1)がPE1のメモリに設けられた場合の例を示す。図9Cに示す例では、分散共有メモリ103の一部の領域がノンキャッシャブル領域に指定されている。また、演算領域が設けられるPE1のメモリは、ローカルメモリでも、分散共有メモリでも、キャッシュメモリでもよい。
【0120】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)を、PE1のメモリ上に設けられたlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3))をPE0の分散共有メモリ103に設けられたノンキャッシャブル領域上のncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0121】
その後、PE1で処理された変数ncbuf[i](i=2、3)を分散共有メモリ103のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0122】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0123】
図9A〜図9Cに記載した変形例によると、自プロセシングエレメント上のメモリで境界部分の変数を演算するので、バスを介した他のプロセシングエレメントやメモリへのデータの転送が減り、処理を高速化することができる。
【0124】
図10A及び図10Bは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0125】
まず、図10Bに示すように、グローバル変数a、ncbuf_pe0、ncbuf_pe1が宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置され、配列変数4個分のサイズの変数ncbuf_pe0及び変数ncbuf_pe1がノンキャッシャブル領域に設けられる(1000)。この変数ncbuf_pe0は、PE0の分散共有メモリに配置され、変数ncbuf_pe1は、PE1の分散共有メモリに配置される。
【0126】
本実施の形態では、プロセッシングエレメント(PE0)100がi=0からi=17の変数aを処理し、プロセッシングエレメント(PE1)110がi=18からi=35の変数aを処理する。
【0127】
具体的には、プロセッシングエレメント(PE0)100が変数a[i](0≦i<16)をキャッシュメモリ上で処理した(1001)。また、PE0が変数a[i](i=16、17)を分散共有メモリ上のncbuf_pe0において処理し、処理の結果をPE1の分散共有メモリのncbuf_pe1に書き込む(1002)。
【0128】
これと並行して又は前後して、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を分散共有メモリ上のncbuf_pe1において処理し、処理の結果をPE0の分散共有メモリのncbuf_pe0に書き込む(1004)。また、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(1005)。
【0129】
また、PE0は、変数ncbuf_pe0[i](0≦i<4)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](16≦i<20)に書き込む(1003)。なお、処理の結果のncbuf_pe0への書き込み(1004)からncbuf_pe0のa[i]への書き込み(1003)へのデータ依存によって、PE1によって処理された変数a[i](i=18、19)がncbuf_pe0[i]に格納されている。このため、ステップ1003では、PE0によって処理された変数a[i](i=16、17)及びPE1によって処理された変数a[i](i=18、19)がPE0のキャッシュメモリ上に書き込まれる。
【0130】
その後、PE0及びPE1が処理の結果を集中共有メモリ160に書き戻す。しかし、図5Aを用いて前述した場合と異なり、PE0とPE1との境界領域の変数a[i](16≦i<20)には同じデータが格納されているので、何れのプロセッシングエレメントがデータを書き戻しても、集中共有メモリ160に格納されるデータは変わらない。
【0131】
すなわち、第3の実施の形態では、各プロセシングエレメントは、PE0がアクセスする集中共有メモリの領域とPE1がアクセスする集中共有メモリの領域との境界部分は、分散共有メモリ上のデータを使用して計算をする。
【0132】
なお、PE0のncbuf_pe0と、PE1のncbuf_pe1とは、互いに書き込まれることによって、同じ値が格納されている。このため、PE0が、変数ncbuf_pe0を集中共有メモリに書き込んだ場合、変数ncbuf_pe1のi=2、3も集中共有メモリに書き込まれており、ncbuf_pe0又はncbuf_pe1のいずれかが集中共有メモリに書き込まれることによって、他方のデータも集中共有メモリに書き込まれる。
【0133】
このように、第3の実施の形態では、図10Aに示すように、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、両方のプロセシングエレメントの分散共有メモリ内に設けられたノンキャッシャブル領域に当該ライン上のデータを格納し、両方のノンキャッシャブル領域のデータをコピーすることによって、両ノンキャッシャブル領域のデータが一致し、何れのデータを書き戻しても、フォルスシェアリングは発生しない。
【0134】
なお、本実施の形態では分散共有メモリ上にノンキャッシャブル領域を設ける必要があり、分散共有メモリ間でデータをコピーする処理のオーバーヘッドが生じる。
【0135】
図11は、本発明の第4の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0136】
第4の実施の形態では、ローカル変数を用いることによって、フォルスシェアリングの発生を避ける。
【0137】
まず、図11に示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1100)。
【0138】
その後、プロセシングエレメント0(PE0)100が、ローカル変数local_aを宣言し(1101)、変数a[i](0≦i<18)をローカル変数において処理し(1102)、ローカル変数local_a[i](0≦i<18)をグルーバル変数a[i](0≦i<18)へ書き込む(1103)。
【0139】
これと並行して又は前後して、プロセシングエレメント1(PE1)110が、ローカル変数local_aを宣言し(1104)、変数a[i](18≦i<36)をローカル変数において処理し(1105)、i=18からi=35のローカル変数local_a[i](18≦i<36)をグルーバル変数a[i](18≦i<36)に書き込む(1106)。
【0140】
ステップ1106には、ステップ1103からのデータ依存が設定されているので、ステップ1106のlocal_a[i]をa[i]に書き込む前に、a[i](i=16、17)を集中共有メモリ160からロードする。このため、ステップ1006では、PE0で更新されたa[16]及びa[17]を、a[18]及びa[19]と共に集中共有メモリに書き戻す。
【0141】
このように、第4の実施の形態では、図11に示すように、複数のプロセシングエレメントがローカル変数を用いてデータを更新し、各プロセシングエレメントがローカル変数をグローバル変数に書き戻す。このため、第4の実施の形態では、フォルスシェアリングは発生しない。
【0142】
なお、本実施の形態ではプロセシングエレメント間でデータをコピーする処理のオーバーヘッドが生じる。
【0143】
次に、多次元配列を扱う場合について説明する。
【0144】
図12A及び図12Bは、多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【0145】
まず、図12Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1200)。キャッシュメモリの1ラインには4個の変数が格納できる。このため、図12Aに示すように、キャッシュメモリの第1ライン1211にはa[0][0]からa[0][3]が存在し、第2ライン1212にはa[0][4]からa[1][1]が存在し、第5ライン1215にはa[2][4]、a[2][5]、a[3][0]、a[3][1]が存在する。
【0146】
その後、プロセッシングエレメント(PE0)100が変数a[i][j]](0≦i<3、0≦j<6)をキャッシュメモリ102上で処理し(1201)、プロセッシングエレメント(PE1)110が変数a[i][j]](3≦i<6、0≦j<6)をキャッシュメモリ112上で処理し(1202)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻す。
【0147】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。また、前述したように、キャッシュラインの境界でループを分割できれば、フォルスシェアリングは発生しない。しかし、PE0によって処理されるa[2][4]及びa[2][5]と、PE1によって処理されるa[3][0]及びa[3][1]とが第5ライン1215上に存在することから、このライン上でPE0によるアクセスとPE1によるアクセスとが競合しフォルスシェアリングが発生する。
【0148】
図13A及び図13Bは、第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【0149】
第1の実施の形態では、キャッシュラインの境界でループを分割するために、配列変数の各要素を外側ループのパラメータ毎に異なるラインに配置する。
【0150】
まず、図13Bに示すように、6×10の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1300)。この配列の各変数a[i][j]は、外側ループのパラメータ毎に異なるラインに配置される。
【0151】
本実施の形態では、キャッシュメモリの1ラインには4個の変数が格納でき、必要な変数は6×6の配列であるので、ラインサイズ(4個)の余分な変数を設けて、6×10の配列変数を定義した。
【0152】
なお、ラインサイズ−1個の余分な変数を設ければよい。
【0153】
さらに、一般化すると、余分な配列変数の数の最低値は、下式が0以上となるSの最低値によって与えられる。
【0154】
余分な配列変数の数の最低値=S(4)の倍数−jmax
S:ラインサイズ
jmax:配列変数の外側ループより一つ内側のループの数(6)
【0155】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<3、0≦j<6)をキャッシュメモリ102上で処理し(1301)、プロセッシングエレメント(PE1)110が変数a[i][j](3≦i<6、0≦j<6)をキャッシュメモリ112上で処理し(1302)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻した。
【0156】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。しかし、図12を用いて前述した場合と異なり、図13Bに示すように、PE0とPE1とはキャッシュメモリの同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0157】
なお、本実施の形態では、余分な変数が確保されるので、キャッシュメモリの利用効率が低下する。このため、本実施の形態は、配列変数の要素の数が少ないい場合、具体的には、下式を満たす場合に有効である。
【0158】
図14A及び図14Bは、第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【0159】
第2の実施の形態では、キャッシュメモリのラインの区切りによって、各プロセッシングエレメントが処理するデータを分け、複数のプロセッシングエレメントによって処理されたデータがキャッシュメモリの1ライン上に格納されないようにする。
【0160】
まず、図14Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1400)。
【0161】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<4、0≦j<6)をキャッシュメモリ102上で処理し(1401)、プロセッシングエレメント(PE1)110が変数a[i][j](4≦i<6、0≦j<6)をキャッシュメモリ112上で処理する(1402)。その後、PE0が処理の結果をキャッシュメモリ102から集中共有メモリ160に書き戻し、PE1が処理の結果をキャッシュメモリ112から集中共有メモリ160に書き戻す。
【0162】
本実施の形態では、図14Aに示すように、1ラインは4個の変数が格納できる容量を有するが、a[3][6]と、a[4][0]とは異なるライン上に存在する。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0163】
なお、本実施の形態ではPE0に24個、PE1に12個の配列変数の処理を割り当てたが、キャッシュラインサイズの倍数になるように分ければ、PE0に12個、PE1に24個の配列変数の処理を割り当てても、よい。また、各プロセッシングエレメントの処理能力の比に従って数の配列変数の処理を割り当ててもよい。
【0164】
なお、本実施の形態では、対象の次元以下の配列変数の要素のサイズがラインサイズの倍数となればループ分割が可能である。この場合、配列変数の要素の数及びプロセッシングエレメントの数によって割り当てられる配列変数の数が等しくならず、プロセッシングエレメントの処理負荷の不均衡が生じる場合がある。このため、本実施の形態は、配列サイズが十分に大きく、不均衡が配列サイズに比べて無視できるほど小さい場合に有効である。
【0165】
図15A及び図15Bは、第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【0166】
第3の実施の形態では、ノンキャッシャブル領域を用いて、フォルスシェアリングの発生を避ける。
【0167】
まず、図15Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される。また、1×6の1次元の配列変数nc_buf2が宣言され、変数nc_buf2が変数6個(内側ループの数)のサイズのノンキャッシャブル領域が設けられる(1500)。
【0168】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<3、0≦j<6)をキャッシュメモリ上で処理し(1501)、プロセッシングエレメント(PE1)110が変数a[3][j](0≦j<6)をnc_buf2[0][j](0≦j<6)を用いてノンキャッシャブル領域上で処理し(1502)、PE1が変数a[i][j](4≦i<6、0≦j<6)をキャッシュメモリ上で処理する(1503)。
【0169】
PE0は、その後又は処理1503と並行して、PE1で処理された変数nc_buf2[0][j](0≦j<6)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[3][j](0≦j<6)に書き込む(1504)。これによって、PE1によってnc_buf2[0][j](0≦j<6)を用いて処理された変数a[3][j](0≦j<6)がPE0に転送される。
【0170】
その後、PE0が変数a[i][j](0≦i<4、0≦j<6)を集中共有メモリ160に書き戻し、PE1が変数a[i][j](4≦i<6、0≦j<6)を集中共有メモリ160に書き戻す。
【0171】
このように、第3の実施の形態では、図15Aに示すように、PE1がノンキャッシャブルバッファを用いて演算した結果をPE0のキャッシュメモリの変数に反映する。すなわち、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、一方のプロセシングエレメント(PE1)はノンキャッシャブル領域に当該ライン上のデータを格納し、他方のプロセシングエレメント(PE0)はノンキャッシャブル領域のデータを集中共有メモリのキャッシャブル領域に格納するので、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0172】
なお、本実施の形態ではメモリ上にノンキャッシャブル領域を設ける必要があるが、ノンキャッシャブル領域は、集中共有メモリ、分散共有メモリ等の何れのメモリに設けてもよい。また、本実施の形態では、ノンキャッシャブル領域からキャッシュメモリにデータをコピーする処理のオーバーヘッドが生じる。しかし、ノンキャッシャブルのバッファとして分散共有メモリを利用することによって、低オーバーヘッドでデータの転送を実現することができる。
【0173】
図16は、第4の実施の形態を2次元配列変数に適用した例を説明する図である。
【0174】
まず、図16に示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1600)。
【0175】
その後、プロセシングエレメント0(PE0)100が、6×6の2次元配列のローカル変数local_aを宣言し(1601)、変数a[i][j](0≦i<3、0≦j<6)をローカル変数local_a[i][j]を用いて処理し(1602)、ローカル変数local_a[i][j](0≦i<3、0≦j<6)をグルーバル変数a[i][j](0≦i<3、0≦j<6)へ書き込む(1603)。
【0176】
これと並行して又は前後して、プロセシングエレメント1(PE1)110が、6×6の2次元配列のローカル変数local_aを宣言し(1604)、変数a[i][j](3≦i<6、0≦j<6)をローカル変数local_a[i][j]を用いて処理し(1605)、ローカル変数local_a[i][j](3≦i<6、0≦j<6)をグルーバル変数a[i][j](3≦i<6、0≦j<6)へ書き込む(1606)。
【0177】
ステップ1606には、ステップ1103からのデータ依存が設定されているので、ステップ1606のlocal_a[i][j]をa[i][j]に書き込む前に、a[2][4]、a[2][5]を集中共有メモリ160からロードする。このため、ステップ1006では、PE0で更新されたa[2][4]及びa[2][5]を、a[3][0]及びa[3][1]と共に集中共有メモリに書き戻す。
【0178】
このように、第4の実施の形態では、図16に示すように、複数のプロセシングエレメントがローカル変数を用いてデータを更新し、各プロセシングエレメントがローカル変数をグローバル変数に書き戻す。このため、第4の実施の形態では、フォルスシェアリングは発生しない。
【0179】
なお、本実施の形態ではプロセシングエレメント間でデータをコピーする処理のオーバーヘッドが生じる。
【0180】
以上説明した実施の形態及び変形例は、プログラムのコンパイル時に一つ又は複数を組み合わせて用いることができる。
【0181】
次に、コンパイラが、フォルスシェアリングを回避するために最適な方法を選択する手順について説明する。
【0182】
図17Aは、本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【0183】
ステップ1710のタスクは、変数iを制御変数とするループであり、ループ分割により生成する部分タスクをそれぞれ別々のプロセッシングエレメントにスケジューリングすることにより並列処理を行う。このタスクを最大分割数でループ分割を行う場合、つまりiループの1イタレーション分の処理を一つの部分タスクとなるようにループ分割した場合に生成される各部分タスクでは、2次元の配列変数Aについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があるということがデータアクセス範囲解析により解析される。同様にステップ1720のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を使用する可能性があり、ステップ1730のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を使用する可能性があり、ステップ1740のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があり、ステップ1750のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があることが解析される。ここで、各タスクを最大分割数で分割した場合のアクセス範囲を考慮しているのは、任意の分割パターンでタスク分割を行った場合に、フォルスシェアリングが発生する可能性があるかどうかを解析するためである。
【0184】
各タスクの各部分タスクにおけるデータのアクセス範囲から、フォルスシェアリングが発生する可能性のある箇所とその要因となる配列変数およびその配列次元を解析する。具体的には、前述の部分タスクにおけるデータアクセス範囲において、分割元のタスクにおけるループ制御変数が含まれている次元のうち最も下位の次元において、その下位次元の部分配列サイズをキャッシュメモリのラインサイズで除したときに余りが発生する場合、フォルスシェアリングが発生する可能性があると判断できる。その場合、当該配列の更新を行うタスクの分割後の各部分タスクの間、あるいは当該配列の更新を行うタスクの分割後の各部分タスクとその配列を使用するタスクの分割後の各部分タスクの間でフォルスシェアリングが発生する可能性がある。
【0185】
なお、変数をメモリへ格納する方法がプログラム言語によって異なるので、どの添字を1次元目とするかは、変数のメモリへの格納方法によって異なる。すなわち、メモリの連続した領域に格納される配列変数の要素で変化する添字と最内周ループを構成する添字とが異なる場合、コンパイラは、必要に応じて、計算順序を変えるインターチェンジを行ってもよい。
【0186】
また、配列変数が集中共有メモリ160のラインの先頭にアラインされていない場合、上記の条件にかかわらずフォルスシェアリングが発生する可能性があると解析される。
【0187】
図17Bは、本発明の実施の形態のループ分割後の処理を示すマクロタスクグラフである。本例では各タスクの分割数を3としているが、この分割数は任意に設定することが可能である。
【0188】
図17B中、実線(1本線)は、プログラム上のデータ依存を示し、2重線は、フォルスシェアリングが発生する可能性がある箇所を示す。
【0189】
なお、フォルスシェアリングを検出するコードの例を図17Cに示す。
【0190】
図18は、本発明の実施の形態の並列化コンパイラによるソフトウェアコヒーレンシ制御コードを生成する処理の概要を説明する図である。
【0191】
まず、コンパイルすべきプログラム2001が並列化コンパイラ2002に入力される。入力されるプログラム2001は、C、Fortran等の言語で記述された逐次プログラムである。
【0192】
並列化コンパイラ2002は、入力された逐次プログラムを並列化し、ノンコヒーレントキャッシュで実行するための制御コードが挿入された並列APIプログラム2003を生成する。生成される並列APIプログラム2003は、コヒーレンシ機能を持たないキャッシュメモリを用いてプログラムを実行するための指示(API)を含む並列プログラム形式である。
【0193】
生成された並列APIプログラム2003は、コード生成コンパイラ2004に入力される。コード生成コンパイラ2004は、コヒーレンシ機能を持たないキャッシュメモリを用いてプログラムを実行するための指示(API)を解釈しながら、プログラムを機械語命令(実行形式プログラム)2005に変換する。この実行形式プログラム2005にも、ノンコヒーレントキャッシュでプログラムを実行するための命令が含まれる。
【0194】
図19は、本発明の実施の形態のコンパイラによって実行される処理のフローチャートである。
【0195】
まず、コンパイラは、コンパイルすべきプログラムの字句を解析し、プログラムの構文を解析する(2101)。
【0196】
構文の解析結果に基づいて、階層的なタスク、すなわち、プログラムの階層的マクロタスクによる表現を生成する(2102)。
【0197】
その後、生成されたタスク間の依存関係(制御フロー)を解析し(2103)、タスク間のデータ依存を解析し(2104)、各タスクによってアクセスされるデータの範囲を解析する(2105)。
【0198】
その後、プログラムの解析結果を使用して、プログラムが最も早く実行できる条件を解析し(2106)、最早実行条件の解析結果を使用して、並列処理区間やタスクが割り当てられるプロセッサ数を決定し、マクロタスクグラフを生成する。
【0199】
その後、マクロタスクグラフにおけるデータ依存関係から、図17A、図17B、図17Cを用いて説明した方法によってフォルスシェアリングを検出し、フォルスシェアリングが検出された箇所及びフォルスシェアリングが検出された変数を含むフォルスシェアリング情報を生成する(2107)。
【0200】
その後、生成されたフォルスシェアリング情報に基づいて、フォルスシェアリングが検出された箇所毎に、フォルスシェアリングを回避する方法が決定され、決定された方法に従って命令が挿入され、フォルスシェアリングが回避された並列プログラムが生成される(2108)。このフォルスシェアリング回避処理については、図20A及び図20Bを用いて詳述する。
【0201】
その後、各タスクの実行順序を決定するタスクスケジューリングを実行し(2109)、ステイルデータに対処するためのキャッシュ操作指示を挿入する(2110)。これによって、コヒーレンシ制御機能つき並列プログラムが生成される。このキャッシュ操作指示の挿入処理については、図21を用いて詳述する。
【0202】
図20A及び図20Bは、本発明の実施の形態のフォルスシェアリング回避処理のフローチャートであり、コンパイル処理(図19)のステップ2108から呼び出される。
【0203】
図20A及び図20Bに示すフォルスシェアリング回避処理は、ステップ2107で検出されたフォルスシェアリング情報を入力とし、同じ配列に対して発生する各フォルスシェアリングについて以下の処理を行う。
【0204】
このフォルスシェアリング回避処理は、データレイアウト変換及びリストラクチャリングに大別され、図20Aにデータレイアウト変換処理を示し、図20Bにリストラクチャリング処理を示す。
【0205】
まず、処理の対象となる配列変数が変換可能であるか否かを判定する(2121)。例えば、この配列変数がコンパイルされるプログラム中で閉じている場合、具体的には、コンパイルされるプログラム中で宣言されており、かつ、このプログラム外で定義される関数の引数とならない場合、データレイアウトの変換によりプログラムが予期せぬ動作をする可能性がないので、配列変数が変換可能であると判定する。
【0206】
その結果、配列が変換不可能であると判定された場合、配列の拡張又はパディング等のデータレイアウトの変換が困難であるため、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0207】
一方、配列が変換可能であると判定された場合、配列の最速変化次元の要素間でフォルスシェアリングが発生するか否かを判定する(2122)。具体的には、N次元配列において、最速変化次元を1次元目、最遅変化次元をN次元目と定義する。最速変化次元とは、添字が連続的に変化する配列の次元である。例えば、N次元配列がループによって処理される場合、ループの最内周が最速変化次元となり、ループの最外周が最遅変化次元となる。すなわち、最速変化次元のデータはメモリ上の連続した領域に配置される。
【0208】
その結果、最速変化次元の要素間でフォルスシェアリングが発生すると判定された場合、配列の拡張が可能か否かを判定する(2123)。ステップ2123では、配列を拡張してもキャッシュ利用効率の低下に起因する性能の低下が小さいか否かを判定する。例えば、配列サイズが十分に小さい場合、図6Aに示すように配列を拡張しても、キャッシュ利用効率の低下に起因する性能低下が小さいことから、配列の拡張が可能であると判定する。具体的には、下式(1)を満たす場合、配列サイズが十分に小さいので、配列の拡張が可能であると判定することができる。
【0209】
Sa1≦S×N ・・・(1)
Sa1:対象の配列の1次元目の宣言サイズ
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0210】
その結果、配列の拡張が可能であると判定された場合、プログラム中に図6Bに示すコードを挿入することによって、図6Aに示すように、配列を拡張する。一方、配列の拡張が困難であると判定された場合、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0211】
一方、ステップ2122で、最速変化次元以外の次元の要素間でフォルスシェアリングが発生すると判定された場合、配列のパディングが可能か否かを判定する(2125)。ステップ2125では、配列をパディングしてもキャッシュ利用効率の低下に起因する性能の低下が小さいか否かを判定する。例えば、配列サイズが十分い大きい場合、図13Aに示すように配列をパディングしてもキャッシュ利用効率の低下に起因する性能低下が小さいことから、配列のパディングが可能であると判定する。具体的には、下式(2)を満たす場合、配列サイズが十分に小さいので、配列のパディングが可能であると判定することができる。
【0212】
Sa2≧S×N ・・・(2)
Sa2:対象の配列変数でフォルスシェアリングが発生する次元以下の部分配列サイズ
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0213】
その結果、配列の拡張が可能であると判定された場合、図13Bに示すコードをプログラム中に挿入することによって、図13Aに示すように、配列を拡張する。一方、配列の拡張が困難であると判定された場合、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0214】
図20Bに示すリストラクチャリング処理では、検出されたフォルスシェアリング情報のうち、データレイアウト変換で対処できなかったフォルスシェアリングに対して、以下の処理を行う。
【0215】
まず、各プロセッサによる処理の境界領域のみでフォルスシェアリングが発生するか否かを判定する(2131)。具体的には、処理の対象となる配列へのアクセスが連続アクセスになっているか否かを判定する。例えば、並列化後に各プロセッサがアクセスする領域が重複している場合(PE0がi、i+2、i+4…とアクセスし、PE1がi+1、i+3、i+5…とアクセスする場合)、処理の対象となる配列へのアクセスは連続アクセスとならないことから、境界領域以外でもフォルスシェアリングが発生する。
【0216】
その結果、境界領域以外でもフォルスシェアリングが発生すると判定された場合、ステップ2139へ進む。
【0217】
一方、境界領域のみでフォルスシェアリングが発生すると判定された場合、フォルスシェアリングが発生すると判定された場所がループによる並列処理であるか否かを判定する(2132)。
【0218】
その結果、ループによる並列処理以外でフォルスシェアリングが発生すると判定された場合、ステップ2139へ進む。
【0219】
一方、ループによる並列処理においてフォルスシェアリングが発生すると判定された場合、キャッシュラインの境界でループを分割できるか否かを判定する(2133)。
【0220】
その結果、キャッシュラインの境界でループを分割できないと判定された場合、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2138)。
【0221】
一方、キャッシュラインの境界でループを分割できると判定された場合、ループの分割に起因する負荷の不均衡による性能低下が小さいか否かを判定する(2134)。例えば、ループ回転数が十分に大きい場合、ループの分割に起因する負荷の不均衡による影響は小さいと判定できる。具体的には、下式(3)を満たす場合、ループ回転数が十分に大きいので、負荷の不均衡による影響は小さいと判定することができる。
【0222】
R≧S×N ・・・(3)
R:ループ回転数
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0223】
また、各プロセッサにタスクを均等に分割した場合、分割されたタスクによって使用されるデータ量(アクセス範囲)の最大値と最小値との差をラインサイズと比較し、この差がラインサイズより小さい場合に負荷不均衡による影響が小さいと判定してもよい。
【0224】
その結果、ループの分割による負荷の不均衡による影響が大きいと判定された場合、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2138)。なお、図10A、図10Bに示す方法を用いてもよく、多次元配列の場合は図15A、図15Bに示す方法を用いる。
【0225】
一方、ループの分割による負荷の不均衡による影響は小さいと判定された場合、キャッシュラインの境界のみでループを分割できるか否かを判定する(2135)。例えば、配列変数の要素a[i]及びa[i+1]に同じループ内でアクセスされる場合、キャッシュラインの境界のみでループを分割することはできない。
【0226】
その結果、キャッシュラインの境界のみでループを分割できると判定された場合、図7Bに示すコードをプログラム中に挿入することによって、図7Aに示すように、キャッシュラインの境界でループを分割する(2136)。なお、多次元配列の場合は図15A、図15Bに示す方法を用いる。
【0227】
一方、配列変数a[i]及びa[i+1]に同じループ内でアクセスされる場合、キャッシュラインの境界のみではループを分割できない場合、キャッシュラインの境界でループを分割できる箇所(例えば、a[i]が分割される箇所)には、図7Bに示すコードをプログラム中に挿入する。さらに、キャッシュラインの境界でループを分割できない箇所(例えば、a[i+1]が分割される箇所)には、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2137)。
【0228】
例えば、a[i]は、キャッシュラインの境界でループを分割し、a[i+1]については、バッファを用いてプロセッシングエレメント間で通信するとよい。この場合、a[i]のアクセス回数とa[i+1]のアクセス回数とを比較し、アクセス回数が多い配列変数の要素の添字について、キャッシュラインの境界でループを分割して、バッファに格納されたデータの通信のオーバーヘッドを少なくするとよい。
【0229】
一方、ステップ2139では、各プロセッシングエレメントにおける演算に用いられるプライベート変数からグローバル変数へのコピー処理のオーバーヘッドが小さいか否かを判定する。具体的には、ループ中で実行される計算の処理量が十分に大きい場合、コピー処理のオーバーヘッドは無視できる程度の小さい。例えば、単に他の変数のデータをaへ代入(コピー)する場合、ループ中で実行される計算の処理量は小さいが、ループ中で四則演算や関数による計算結果をaへ代入している場合、ループ中で実行される計算の処理量は大きくなる。
【0230】
その結果、変数のコピー処理のオーバーヘッドが小さいと判定された場合、図11に示すコード(多次元配列の場合は図16に示すコード)をプログラム中に挿入することによって、各プロセッシングエレメントにおいて定義されたプライベート変数を用いて演算をし、演算の結果をプライベート変数からグローバル変数へコピーする(2140)。
【0231】
一方、変数のコピー処理のオーバーヘッドが大きいと判定された場合、各プロセッシングエレメントによる演算の結果を、逐次、集中共有メモリ160に書き込む(2141)。
【0232】
図21は、本発明の実施の形態のキャッシュ操作指示の挿入処理のフローチャートである。
【0233】
まず、並列化フェイズにおけるタスクグラフのスケジューリング結果において、異なるプロセッサに割り当てられたタスク間のデータ依存を解析する(2151)。
【0234】
解析されたデータの依存関係が、フロー依存又は出力依存であるか否かを判定する(2152)。その結果、解析されたデータの依存関係がフロー依存又は出力依存である場合、キャッシュ操作指示を挿入する。
【0235】
具体的には、図3Bを用いて前述したように、データを生産する側のプロセシングエレメントが、データを更新後にライトバック命令によって主記憶(集中共有メモリ160)に更新されたデータを書き戻すキャッシュ操作指示と、データを消費する側のプロセシングエレメントが、データを消費する前にセルフインバリデート命令によって主記憶からデータを読み込むキャッシュ操作指示と生成し、生成されたキャッシュ操作指示をプログラム中に挿入する。このとき、生産側のプロセシングエレメントによるデータの更新の終了はフラグによって消費側のプロセシングエレメントに通知され、消費側のプロセシングエレメントはフラグの更新によってデータの更新を知り、更新されたデータを主記憶から読み込むように制御される。コンパイラは、このフラグによる制御命令を生成し、生成された制御命令をプログラム中に挿入する。
【0236】
一方、解析されたデータの依存関係がフロー依存でも出力依存でもない場合、キャッシュ操作指示の挿入処理を終了する。
【0237】
以上説明したように、本発明の実施の形態によると、ソフトウェアによる制御によって、コヒーレンシ制御のためのハードウェアが不要となり、ハードウェアを簡素化できる。このため、低コストかつ低消費電力のマルチプロセッサを実現できる。また、コンパイラの最適化によって、スケーラブルな性能向上が可能となる。
【0238】
特許請求の範囲に記載した以外の本発明の観点の代表的なものとして、次のものがあげられる。
【0239】
(1)複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備えるマルチプロセッサシステムであって、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントは、
前記主記憶装置から読み込んだデータを前記キャッシュメモリに一時的に格納し、
使用が終了したデータを前記キャッシュメモリから、前記キャッシュメモリの管理単位に従って、前記主記憶装置に書き戻し、
前記プログラムを分割して生成される各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納することを特徴とするマルチプロセッサシステム。
【0240】
(2)前記プロセッシングエレメントは、少なくとも第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記第1のプロセッシングエレメントは、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算し、
前記第2のプロセッシングエレメントは、
前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記ノンキャッシャブル領域で演算し、
前記ノンキャッシャブル領域で演算した結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送することを特徴とする(1)に記載のマルチプロセッサシステム。
【0241】
(3)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記各プロセッシングエレメントは、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算し、
前記第1のプロセッシングエレメントは、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込むことを特徴とする(1)に記載のマルチプロセッサシステム。
【0242】
(4)異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻し、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化することを特徴とする(1)から(3)のいずれか一つに記載のマルチプロセッサシステム。
【0243】
(5)マルチプロセッサシステムに備わるプロセッサにおいて演算処理を実行させるプログラムであって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリの管理単位に従ってデータが転送され、
前記プログラムは、各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順を含むことを特徴とするプログラム。
【0244】
(6)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算する手順と、
前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順と、
前記第2のプロセッシングエレメントが、前記ノンキャッシャブル領域に格納された演算結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送する手順とを含むことを特徴とする(5)に記載のプログラム。
【0245】
(7)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算する手順と、
前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込む手順とを含むことを特徴とする(5)に記載のプログラム。
【0246】
(8)異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻す手順と、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化する手順とを含むことを特徴とする(5)から(7)のいずれか一つに記載のプログラム。
【符号の説明】
【0247】
100、110、120 プロセシングエレメント
101、111、121 プロセッサ
102、112、122 キャッシュメモリ
150 内部結合網
160 集中共有メモリ(主記憶)
【技術分野】
【0001】
本発明は、複数のプロセシングエレメントによって構成されるマルチプロセッサにおけるメモリの管理方法に関し、特に、コンパイラが取得した情報に基づいて、共有メモリに格納されたデータの一貫性(コヒーレンシ)を保つように制御する方法に関する。
【背景技術】
【0002】
複数のプロセシングエレメントを集積したマルチプロセッサが、各マイクロプロセッサメーカによって次々に発表されている。スーパーコンピュータ、サーバ、デスクトップコンピュータ及びPCサーバ分野の他、情報家電及び装置組み込みの分野(例えば、携帯電話機、ゲーム機、カーナビゲーションシステム、デジタルテレビ受像機、HDD/DVDレコーダ・プレーヤ等)においても、マイクロプロセッサのマルチコア化の動きが見られる。
【0003】
マルチプロセッサは、複数のプロセシングエレメント、内部結合網及び集中共有メモリを備え、各プロセシングエレメントは、プロセッサ及びキャッシュメモリを備え、独立に演算処理を行うものである。このような構成のマルチプロセッサは、集中共有メモリを主記憶として使用し、複数のプロセッシングエレメントが、集中共有メモリに格納された同一のデータをアクセスする主記憶共有型プロセッサとして使用される。
【0004】
このとき、共有データ間のコヒーレンシを保つために、あるプロセッサがキャッシュメモリ上の共有データをアクセスしている場合、他のプロセッサが当該共有データを集中共有メモリからキャッシュメモリへのアクセスを禁止するコヒーレンシ制御が必要となっていた。
【0005】
ここで、コヒーレンシとは、ある時刻において、メモリのあるアドレスに格納された値を、全てのプロセッサが同一の値としてアクセスできることであり、主記憶共有型マルチプロセッサにおいて、各プロセッサからアクセスされるメモリの内容が同一であることを保証するための制御である。コヒーレンシを保つための機能には、ハードウェアによってメモリアクセスを制御するコヒーレントキャッシュがある。
【0006】
コヒーレンシ制御において解決しなければならない第1の問題はデータの陳腐化(Stale Data)であり、第2の問題はフォルスシェアリング(False Sharing)である。
【0007】
図22は、コヒーレンシ制御における第1の問題点(ステイルデータ)を説明する図である。
【0008】
まず、グローバル変数a、b、cが宣言され(2200)、共有メモリに変数a=0,b=0,c=1が格納された(2201)。
【0009】
その後、あるプロセシングエレメント(PE0)のキャッシュメモリに共有データ(a=0、b=0、c=1)が格納されており(2202)、他のプロセシングエレメント(PE1)のキャッシュメモリにも同じ共有データが格納されている(2203)場合、PE0で当該共有データが更新(a=0→1)されても、PE1のキャッシュ上の共有データは更新されていない古いデータ(a=0)である(2205)。この状態で、PE1で当該共有データが更新(c=a)されると、変数cは正しいaの値を反映することなく0に更新されてしまう(2206)。
【0010】
このため、コヒーレンシ制御がされていれば、a=1、b=0、c=1であるはずの変数が、a=0、b=0、c=0となる。このため、PE0のキャッシュメモリに格納されているデータと、PE1のキャッシュメモリに格納されているデータとが不一致となる。このため、PE1が誤った動作をしてしまう。
【0011】
図23は、コヒーレンシ制御における第2の問題点(フォルスシェアリング)を説明する図である。
【0012】
まず、グローバル変数a、bが宣言され(2300)、変数a=0、b=0が共有メモリに格納された(2301)。この変数a及びbは、共有メモリの同じキャッシュライン上に格納されている。また、共有メモリは、ライン単位でアクセスされる。
【0013】
その後、あるプロセシングエレメント(PE0)のキャッシュメモリに格納された共有データが更新(a=0→1)され(2302)、他のプロセシングエレメント(PE1)のキャッシュメモリに格納された共有データが更新(b=0→2)された(2303)。すなわち各プロセッシングエレメントが、同一のライン上に格納された異なる変数を更新した。この場合、PE0が先に共有メモリにデータを書き戻せば、後にデータを書き戻したPE1のデータが共有メモリに格納される(2304)。一方、PE1が先に共有メモリにデータを書き戻せば、後にデータを書き戻したPE0のデータが共有メモリに格納される(2305)。
【0014】
コヒーレンシ制御がされている場合、共有メモリにはa=1、b=2が格納されるが、コヒーレンシ制御がされない場合、最終的にどのデータが共有メモリに格納されるかは定まらない。すなわち、ライン吐き出しタイミングによりメモリの内容が異なり、いずれにせよプロセッシングエレメントは誤った動作をしてしまう。
【0015】
このような共有メモリとキャッシュメモリとの間での不一致が生じる問題点を解決するために、各プロセッシングエレメント及び共有資源(内部結合網、共有メモリ等)にコヒーレンシ制御部を設けることによって、メモリに格納されたデータのコヒーレンシを保つ。
【0016】
具体的には、あるプロセシングエレメント(PE0)がデータxを共有メモリから読み出した後に、PE0がデータxを共有メモリから読み出して、それを更新し、データxの所有権を破棄するまで、他のプロセシングエレメント(PE1)による共有メモリのデータxへの書き込みは許可されない。
【0017】
このような所有権制御によって、データの陳腐化(Stale Data)及びフォルスシェアリング(False Sharing)のコヒーレンシ制御の問題を解決することができる。
【先行技術文献】
【特許文献】
【0018】
【特許文献1】特開2004−30362号公報
【特許文献2】特開平9−44403号公報
【発明の概要】
【発明が解決しようとする課題】
【0019】
しかし、ハードウェアによってメモリアクセスを所有権制御するコヒーレントキャッシュでは、ハードウェアのコストのために、プロセッサ数の増加によって、マルチプロセッサのコストが上昇する。また、ハードウェアによってメモリアクセスを制御することによって、メモリアクセスが遅くなる。
【0020】
さらに、ハードウェアによるコヒーレンシ制御では、イベント毎に全てのプロセッサ、メモリ及びバス制御機構に信号を送るので、実行時のオーバーヘッドが生じる。このオーバーヘッドは、マルチプロセッサに含まれるプロセッサ数に応じて増加する。このため、プロセッサ数が増加した場合、コヒーレンシ制御のための通信でバスが埋まってしまい、プロセッサの動作を妨げる。
【0021】
このため、より簡単なハードウェア構成によるコヒーレンシ制御、特にソフトウェアによるコヒーレンシ制御が求められている。
【課題を解決するための手段】
【0022】
本発明のコンパイラは、プログラムを解析して得られるコントロールフロー及びデータ依存関係の情報を用いて、ソフトウェアによる明示的なキャッシュ操作コードを生成する。また、異なるプロセシングエレメントによって使用される変数が、同じキャッシュラインに載らないように配置する。
【発明の効果】
【0023】
本発明によれば、ソフトウェアによる制御によって、コヒーレンシ制御のためのハードウェアが不要となり、ハードウェアを簡素化できる。このため、低コストかつ低消費電力のマルチプロセッサを実現できる。
【図面の簡単な説明】
【0024】
【図1】本発明の実施の形態のマルチプロセッサの構成図である。
【図2】本発明の実施の形態のマルチプロセッサのキャッシュメモリの各ラインがとりうる状態を説明する図である。
【図3A】本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【図3B】本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【図4】本発明の実施の形態のフォルスシェアリングの発生を避ける方法の概要を説明する図である。
【図5A】一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図5B】一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図6A】本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図6B】本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図7A】本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図7B】本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8B】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【図8C】本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が集中共有メモリに設けられた場合の例を示す。
【図8D】本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリに設けられた場合の例を示す。
【図9A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図9B】図9Aに示す変形例におけるノンキャッシャブル領域が集中共有メモリに設けられた場合の例を示す。
【図9C】図9Aに示す変形例におけるノンキャッシャブル領域が分散共有メモリに設けられた場合の例を示す。
【図10A】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図10B】本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図11】本発明の第4の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【図12A】多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図12B】多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【図13A】第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【図13B】第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【図14A】第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【図14B】第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【図15A】第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【図15B】第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【図16】第4の実施の形態を2次元配列変数に適用した例を説明する図である。
【図17A】本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【図17B】本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【図17C】本発明の実施の形態のフォルスシェアリングを検出するためのコードの例を説明する図ある。
【図18】本発明の実施の形態の並列化コンパイラによるソフトウェアコヒーレンシ制御コードを生成する処理の概要を説明する図である。
【図19】本発明の実施の形態のコンパイラによって実行される処理のフローチャートである。
【図20A】本発明の実施の形態のフォルスシェアリング回避処理のフローチャートである。
【図20B】本発明の実施の形態のフォルスシェアリング回避処理のフローチャートである。
【図21】本発明の実施の形態のキャッシュ操作指示の挿入処理のフローチャートである。
【図22】コヒーレンシ制御における第1の問題点(ステイルデータ)を説明する図である。
【図23】コヒーレンシ制御における第2の問題点(フォルスシェアリング)を説明する図である。
【発明を実施するための形態】
【0025】
図1は、本発明の実施の形態のマルチプロセッサの構成図である。
【0026】
本発明の実施形態のマルチプロセッサは、複数のプロセシングエレメント(PE0、PE1、…、PEn)100、110、120、内部結合網150、及び集中共有メモリ160を備える。
【0027】
プロセシングエレメント100は、演算処理をするプロセッサ101、データを一時的に格納するキャッシュメモリ102、分散共有メモリ(DSM)103及びデータ転送コントローラを備え、独立に動作する。
【0028】
プロセッサ101は、整数演算及び浮動小数点演算が可能なものであればよく、その機能は特に限定されない。例えば、データのロード及びストアのアーキテクチャが単純なシングルイッシューRISCアーキテクチャのCPUを用いてもよい。また、スーパースカラプロセッサ、VLIWプロセッサ等も用いてもよい。
【0029】
キャッシュメモリ102は、集中共有メモリ160からプロセッサ101によって読み込まれたデータを一時的に格納するメモリである。プロセッサ101は、キャッシュメモリ102に格納されたデータを用いて演算処理をする。プロセッサ101による演算処理が終了すると、キャッシュメモリ102に格納されたデータは集中共有メモリ160に書き戻される。このキャッシュメモリ102と集中共有メモリ160との間では、ライン毎にデータが読み書きされる。このラインは、キャッシュメモリ102に格納されたデータの管理単位である。
【0030】
なお、プロセッシングエレメント100は、キャッシュメモリ102を二次キャッシュとして使用し、キャッシュメモリ102の他に一次キャッシュを備えてもよい。この場合、一次キャッシュと二次キャッシュ(キャッシュメモリ102)とは、コヒーレンシ制御がされてもよい。すなわち、本発明の実施の形態のマルチプロセッサでは、主記憶として機能する集中共有メモリ160と最外側のキャッシュメモリ102との間でデータの一致を保つコヒーレンシ機能を有さない。
【0031】
分散共有メモリ103は、格納されたデータを他のプロセシングエレメントから直接読み書きすることができるメモリである。なお、分散共有メモリ103がデュアルポートメモリで構成されていると、プロセッサ101とデータ転送コントローラとが競合することなく分散共有メモリにアクセスすることができる。なお、分散共有メモリ103は、本実施の形態のマルチプロセッサに必須の構成ではない。
【0032】
データ転送コントローラは、プロセッシングエレメントに備わるメモリに格納されたデータをプロセッシングエレメント間で転送する。
【0033】
さらに、プロセシングエレメント100は、図示した構成の他、ローカルプログラムメモリ、ローカルデータメモリ、ネットワークインターフェイス及び電力制御レジスタを備えてもよい。
【0034】
なお、プロセシングエレメント110、120も、プロセシングエレメント100と同じ構成を有する。
【0035】
内部結合網150は、既存の接続技術(クロスバースイッチ、バス、マルチステージネットワーク等)によって実現され、複数のプロセシングエレメント100等及び集中共有メモリ160を接続する。
【0036】
集中共有メモリ160(CSM)は、システム中の全プロセシングエレメント100等によって共有されるデータが格納される主記憶として機能し、各プロセシングエレメント100等からアクセス可能なメモリである。
【0037】
なお、本実施の形態のマルチプロセッサは、キャッシュメモリ102等と集中共有メモリ160との間でデータの一致を保つための、ハードウェアによるコヒーレンシ機能を有さない。
【0038】
<ステイルデータの解決>
まず、第1の課題であるステイルデータの発生を避ける方法について説明する。
【0039】
本発明の実施の形態のマルチプロセッサは、前述したように、キャッシュメモリ102等と集中共有メモリ160との間でデータの一致を保つための、ハードウェアによるコヒーレンシ機能を有さない。このため、あるプロセッシングエレメントがキャッシュメモリ上でデータを更新した場合、このデータ更新は他のプロセッシングエレメントに通知されない。また、更新されたデータが書き戻されるまで、更新されたデータは集中共有メモリ160にも反映されない。
【0040】
このため、本発明の実施の形態のコンパイラは、プログラムを解析した結果(データコントロールフロー、データ依存関係)に基づいて、ソフトウェアによる明示的なキャッシュ操作コードを生成する。
【0041】
生成されるキャッシュ操作コードは、その命令が実行されるプロセッシングエレメントのキャッシュメモリに格納されたデータを操作する命令だけであり、ハードウェアによるコヒーレンシプロトコルにおけるキャッシュ操作要求のような、他プロセッシングエレメントのキャッシュメモリに格納されたデータの状態を操作する命令ではない。生成されるキャッシュ操作コードは、ライトバック、セルフインバリデート、パージの3種類がある。
【0042】
ライトバック(writeback)は、キャッシュメモリ102に格納されたデータを集中共有メモリ160に書き戻すための命令である。キャッシュメモリ102上でデータが更新され、集中共有メモリ160上の対応するアドレスに格納されるデータと異なる場合、ラインの状態はダーティとなり、キャッシュメモリ102に格納されたデータを、集中共有メモリ160に書き戻す必要がある。
【0043】
なお、キャッシュメモリ102のラインリプレースに伴うデータの書き戻し(auto−writeback)によっても、集中共有メモリ160へデータが書き戻される。
【0044】
セルフインバリデート(self−invalidate)は、キャッシュメモリ102のラインを無効化するための命令である。セルフインバリデートされ、インバリデート状態になったデータは、キャッシュメモリに格納されていても、再度集中共有メモリ160から読み込むまで使用することができない。
【0045】
パージ(purge)は、キャッシュメモリ102のラインに格納されたデータを書き戻した(ライトバック)後、セルフインバリデート実行するための命令である。
【0046】
また、各プロセッシングエレメントで実行されるタスク間で通信が発生する箇所にキャッシュ操作コードが挿入される。
【0047】
さらに、コンパイラは、異なるプロセッシングエレメントが同一ラインのデータを保持している場合、異なるプロセッシングエレメントに格納された同一ラインのデータを同時に更新しないように制御する。
【0048】
図2は、本発明の実施の形態のマルチプロセッサのキャッシュメモリ102の各ラインがとりうる状態を説明する図である。
【0049】
キャッシュメモリ102は、ライン毎に、Modified、Valid、Stale、Invalidの4状態をとる。
【0050】
Modifiedは、キャッシュメモリ102に格納されたデータが更新されたダーティデータで、集中共有メモリ160上の対応するアドレスに格納されるデータと異なっている状態である。この場合、ライトバックによって、キャッシュメモリ102に格納されたデータを集中共有メモリ160に書き戻す必要がある。
【0051】
Validは、キャッシュメモリ102に格納されたデータが集中共有メモリ160上の対応するアドレスに格納されるデータと一致しているクリーン状態である。
【0052】
Staleは、キャッシュメモリ102に格納されたデータと同期すべきデータが他のプロセッシングエレメントによって書き換えられたが、まだ当該更新データは集中共有メモリ160に書き戻されていないため、当該キャッシュデータは集中共有メモリ160上の対応するアドレスに格納されるデータとが一致しているクリーン状態である。
【0053】
Invalidは、キャッシュメモリ102に格納されたデータと一致していないデータである可能性がある状態である。
【0054】
前述した4状態は、キャッシュメモリ102へのアクセス、及び、キャッシュ操作によって遷移する。
【0055】
キャッシュメモリ102へのアクセスには、プロセッサ101による集中共有メモリ160からのデータの読み込み(read)、プロセッサ101によるキャッシュメモリ102へのデータの書き込み(write)がある。
【0056】
本発明の実施の形態のコンパイラは、複数のプロセッシングエレメントのキャッシュメモリに格納された同一ラインのデータが、同時にModifiedとならないように制御する。また、本実施の形態のコンパイラは、Staleのデータを読み書きしないように制御する。
【0057】
図3A及び図3Bは、本発明の実施の形態のステイルデータの消費を避ける方法を説明する図である。
【0058】
本発明の実施の形態のコンパイラは、プロセッシングエレメントをまたがるデータ依存が存在する場合、データ依存のエッジでデータを同期する。例えば、コンパイラがプログラムの解析によって検出すべきデータ依存のエッジは、フロー依存によって生じるdef−useの関係である。
【0059】
例えば、図3Aに示すように、PE0がタスクブロック1(SB1)で変数Aを定義した(300)後、PE1がタスクブロック3(SB3)で変数Aを使用する場合、図3Bに示すように、PE0による変数Aの更新によって、PE1は変数Aが格納されているラインの状態をinvalidateへ変更する(302)。また、PE0が変数Aを集中共有メモリに書き戻した(301)後に、PE1が変数Aを使用する。
【0060】
より具体的には、コンパイラは、PE0が更新した変数Aを、他のプロセッシングエレメント(PE1)で使用する前に、ライトバック命令(301)を挿入する。この場合、次に自プロセシングエレメント(PE0)が変数Aが使用する場合は、ライトバック命令を挿入せず、他のプロセッシングエレメント(PE1)が変数Aを使用する前にライトバック命令を挿入すればよい。
【0061】
さらに、コンパイラは、フラグ変数を用いたプロセッシングエレメント間のデータ同期のために、同期の送信側(PE0)は、同期フラグ変数(sync_flg)に同期を示す値を書き込む命令(302)、及び、その同期フラグ変数が格納されているキャッシュメモリのラインを集中共有メモリに書き戻す命令(303)を挿入する。
【0062】
一方、PE1について、コンパイラは、他のプロセシングエレメント(PE0)によって更新された変数Aを使用する前にセルフインバリデート命令(304)を挿入する。なお、セルフインバリデート命令(304)が挿入される箇所(セルフインバリデートのタイミング)は、変数Aを使用する直前が望ましい。
【0063】
さらに、コンパイラは、同期フラグ変数(sync_flg)のインバリデート及び読み込みを繰り返し、同期フラグ変数の値が同期を示す値に更新されるまでビジーウェイト状態で待機する命令(305)を挿入する。
【0064】
PE1は、変数Aがインバリデートされており、キャッシュメモリ上の変数Aを使用できないため、変数Aを集中共有メモリ160からキャッシュメモリにロードし、PE0で更新された変数Aを取得する。
【0065】
以上、def−useの関係について説明したが、出力依存によって生じるdef−defの関係、use−defによる逆依存の関係、use−useによる入力依存の関係でも同様のことが生じうる。
【0066】
このように、本実施の形態のコンパイラは、タスク間のフロー依存及び出力依存を解析した結果に応じてキャッシュ操作命令を挿入するので、コヒーレンシ制御をすることなく、ステイルデータを消費することがない。
【0067】
<フォルスシェアリングの解決>
次に、第2の課題であるフォルスシェアリングの発生を避けるための方法について説明する。
【0068】
図4は、本発明の実施の形態のフォルスシェアリングの発生を避ける方法の概要を説明する図である。
【0069】
本実施の形態では、各プロセシングエレメントによって使用される変数が、同じキャッシュラインに載らないように、各変数がキャッシュラインの先頭に配置される(アラインメント)を行う。なお、変数のアライメントは、配列変数の宣言において指定しても、別に設定ファイル等に記述してもよい。
【0070】
まず、図23で前述したと同様に、グローバル変数a、bが宣言され(400)、変数a=0、b=0が集中共有メモリ160に格納された。しかし、本発明の実施の形態では、図23で前述したと異なり、宣言されたグローバル変数a、bは集中共有メモリ160のキャッシュラインの先頭に配置されるので、異なるライン上に格納される。
【0071】
その後、あるプロセシングエレメント(PE0)のキャッシュ上の共有データが更新(a=0→1)され(401)、他のプロセシングエレメント(PE1)のキャッシュ上の共有データが更新(b=0→2)された(402)。しかし、各プロセッシングエレメントは、異なるライン上に格納された異なる変数を更新したので、各プロセシングエレメントがいかなるタイミングでキャッシュメモリに格納されたデータを集中共有メモリ160に書き戻しても(404、405)、正しいデータ(a=1、b=2)が集中共有メモリ160格納される。
【0072】
次に、一次元配列を扱う場合について説明する。
【0073】
図5A及び図5Bは、一次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【0074】
まず、図5Bに示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(500)。本実施の形態ではキャッシュメモリの1ラインが16バイトであり、1ラインに4個の変数が格納できる場合を考える。このため、図5Aに示すように、キャッシュメモリの第1ライン511にはa[0]からa[3]が格納されており、第2ライン512にはa[4]からa[7]が格納されており、第5ライン515にはa[16]からa[19]が格納されている。
【0075】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ102上で処理し(501)、プロセッシングエレメント(PE1)110が変数a[i](18≦i<36)をキャッシュメモリ112上で処理し(502)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻す。
【0076】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。PE0によって処理されるa[16]及びa[17]と、PE1によって処理されるa[18]及びa[19]とが第5ライン515上に存在することから、このライン上でPE0によるアクセスとPE1によるアクセスとが競合しフォルスシェアリングが発生する。
【0077】
図6A及び図6Bは、本発明の第1の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0078】
第1の実施の形態の方法では、図6Aに示すように、グローバル変数aの各要素を集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置することによって、各要素を異なるラインに配置する。このため、キャッシュラインの境界で処理が分割される。
【0079】
まず、図6Bに示すように、グローバル変数aが宣言され、変数aに含まれる36個の配列変数の各要素が集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(600)。
【0080】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)を処理し(601)、プロセッシングエレメント(PE1)110が変数a[i](18≦i<36)を処理し(602)、PE0及びPE1が処理の結果を集中共有メモリ160に書き戻す。しかし、図5Aを用いて前述した場合と異なり、図6Bに示すように、PE0とPE1とは集中共有メモリ160の同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0081】
なお、本実施の形態では、1ラインは4個の変数が格納できる容量を有するが、1ラインに1個の変数しか格納されていないので、キャッシュメモリの利用効率が低下する。このため、本実施の形態は、配列変数の要素の数が少ない場合に有効である。また、同一のプロセッシングエレメントが、配列変数の異なる添字の要素(a(i)、a(i+1))にアクセスするような間接メモリアクセスをする場合にも有効である。
【0082】
図7A及び図7Bは、本発明の第2の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0083】
フォルスシェアリングは、図5Aを用いて前述したように、異なるプロセッシングエレメントによって処理されたデータがキャッシュメモリの1ライン上に格納されることによって発生する。このため、本実施の形態では、図7Aに示すように、キャッシュメモリのラインの境界によって、各プロセッシングエレメントが処理するデータを分け、複数のプロセッシングエレメントによって処理されるデータがキャッシュメモリの1ライン上に格納されないようにする。
【0084】
まず、図7Bに示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(700)。
【0085】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<16)を処理し(701)、プロセッシングエレメント(PE1)110が変数a[i](16≦i<36)を処理する(702)。その後、PE0が処理の結果をキャッシュメモリ102から集中共有メモリ160に書き戻し、PE1が処理の結果をキャッシュメモリ112から集中共有メモリ160に書き戻す。
【0086】
本実施の形態では、1ラインは4個の変数が格納できる容量を有するので、各プロセッシングエレメントが、キャッシュラインサイズである4の倍数の配列変数の要素を処理するようにしている。このため、図7Aに示すように、PE0のアクセス範囲とPE1のアクセス範囲とはキャッシュメモリのラインの境界で分けられ、PE0とPE1とはキャッシュメモリの同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0087】
なお、本実施の形態ではPE0に16個、PE1に20個の配列変数の処理を割り当てたが、キャッシュラインサイズ(1ラインに格納できる配列変数の要素数)の倍数になるように分ければ、PE0に20個、PE1に16個の配列変数の処理を割り当てても、よい。また、各プロセッシングエレメントの処理能力の比に従って数の配列変数の処理を割り当ててもよい。
【0088】
なお、本実施の形態では、キャッシュラインサイズ、配列変数の要素の数及びプロセッシングエレメントの数によっては、各プロセッシングエレメントに割り当てられる配列変数の要素の数が等しくならず、プロセッシングエレメントの処理負荷の不均衡が生じる場合がある。このため、本実施の形態は、配列サイズが十分に大きく、不均衡が配列サイズに比べて無視できるほど小さい場合に有効である。
【0089】
図8A及び図8Bは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法を説明する図である。
【0090】
第3の実施の形態では、処理の境界においてノンキャッシャブル領域を用いることによって、フォルスシェアリングの発生を避ける。
【0091】
まず、図8Bに示すように、グローバル変数a及び変数ncbufが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置され、配列変数4個のサイズの変数ncbufがノンキャッシャブル領域に設けられる(800)。
【0092】
ノンキャッシャブル領域とは、プロセッシングエレメントが当該領域に格納されたデータをメモリから読み込んだ場合に、当該読み込まれたデータを各プロセッシングエレメントのキャッシュメモリにロードしないで使用される領域である。ノンキャッシャブル領域は、メモリの領域(アドレス)又は特定の変数をノンキャッシャブルに指定することによって、通常のキャッシャブル領域と区別される。このノンキャッシャブルの指定は、所定の設定ファイルによって予め定めておいてもよいし、変数を宣言する命令によって定めてもよい。
【0093】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](18、19)をncbuf[i](i=2、3)を用いてノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0094】
PE0は、その後又は処理803と並行して、PE1で処理された変数ncbuf[i](i=2、3)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。このデータ依存によって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0095】
その後、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻す。
【0096】
このように、第3の実施の形態では、図8Aに示すように、PE1がノンキャッシャブルバッファを用いて演算した結果をPE0のキャッシュメモリの変数に反映する。すなわち、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、一方のプロセシングエレメント(PE1)はキャッシュメモリ内に設けられたノンキャッシャブル領域に当該ライン上のデータを格納し、他方のプロセシングエレメント(PE0)はノンキャッシャブル領域のデータを集中共有メモリに格納するので、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0097】
なお、ライン811〜814に格納されたデータはPE0のみによって使用され、ライン811〜814に格納されたデータはPE0のみによって使用されるので、ライン811〜814及びライン816〜819をキャッシュメモリ上でローカライズしてもよい。ローカライズされたデータは、主記憶に書き戻されず、次にPE0が使用するまでキャッシュメモリ上に保持される。同様に、ライン811〜814に格納されるべきデータ及びライン816〜819に格納されるべきデータをローカルメモリに格納してもよい。
【0098】
すなわち、第5ライン815のみがキャッシュメモリ上(キャッシャブル領域上)にあればよく、そのほかの領域(ライン811〜814、ライン816〜819)はキャッシャブル領域上に存在していなくてもよい。
【0099】
なお、本実施の形態ではメモリ上にノンキャッシャブル領域を設ける必要があるが、ノンキャッシャブル領域は、集中共有メモリ、分散共有メモリ等の何れのメモリに設けてもよい。また、本実施の形態では、ノンキャッシャブル領域からキャッシュメモリにデータをコピーする処理のオーバーヘッドが生じる。しかし、ノンキャッシャブルのバッファとして分散共有メモリを利用することによって、低オーバーヘッドでデータの転送を実現することができる。
【0100】
この第3の実施の形態の方法は、前述した第2の実施の形態の方法によっては分割が不可能な場合や、配列が拡張できない場合に有効である。
【0101】
図8Cは、本発明の第3の実施の形態においてノンキャッシャブル領域が集中共有メモリ160に設けられた場合の例を示す。図8Cに示す例では、集中共有メモリ160の一部の領域がノンキャッシャブル領域に指定されている。
【0102】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を、ncbuf[i](i=2、3)を用いて集中共有メモリ160に設けられたノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0103】
その後、PE1で処理された変数ncbuf[i](i=2、3)を集中共有メモリ160のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0104】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0105】
図8Dは、本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリ103に設けられた場合の例を示す。図8Dに示す例では、分散共有メモリ103の一部の領域がノンキャッシャブル領域に指定されている。
【0106】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(801)、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を、ncbuf[i](i=2、3)を用いてPE0の分散共有メモリ103に設けられたノンキャッシャブル領域上で処理し(802)、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(803)。
【0107】
その後、PE1で処理された変数ncbuf[i](i=2、3)を分散共有メモリ103のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(804)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0108】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0109】
図9Aは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0110】
図9Aで説明する変形例は、前述した例と異なり、各プロセシングエレメントが自己のメモリ上で演算し、その演算結果をノンキャッシャブル領域に転送することによって、フォルスシェアリングの発生を避ける。このため、他のメモリ、プロセシングエレメント等へのアクセスを減らし、処理を高速化することができる。
【0111】
まず、図9Aに示すように、グローバル変数a及び変数ncbuf及びlocalbuf_pe1が宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される。また、配列変数4個のサイズの変数ncbufがノンキャッシャブル領域に設けられ、配列変数4個のサイズの変数localbuf_pe1がノンキャッシャブル領域に設けられる(900)。なお、変数Localbuf_pe1はプロセッシングエレメント(PE1)110のみで使用されるので、ローカル変数でよい。
【0112】
その後、プロセッシングエレメント(PE0)100が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)をlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3)をncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0113】
PE0は、その後又は処理904と並行して、PE1で処理された変数ncbuf[i](i=2、3)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。このデータ依存によって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0114】
その後、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻す。
【0115】
図9Bは、本発明の第3の実施の形態においてノンキャッシャブル領域が集中共有メモリ160に設けられ、演算領域(localbuf_pe1)がPE1のメモリに設けられた場合の例を示す。この演算領域が設けられるPE1のメモリは、ローカルメモリでも、分散共有メモリでも、キャッシュメモリでもよい。
【0116】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)を、PE1のメモリ上に設けられたlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3))を集中共有メモリ160に設けられたノンキャッシャブル領域上のncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0117】
その後、PE1で処理された変数ncbuf[i](i=2、3)を集中共有メモリ160のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0118】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0119】
図9Cは、本発明の第3の実施の形態の方法におけるノンキャッシャブル領域が分散共有メモリ103に設けられ、演算領域(localbuf_pe1)がPE1のメモリに設けられた場合の例を示す。図9Cに示す例では、分散共有メモリ103の一部の領域がノンキャッシャブル領域に指定されている。また、演算領域が設けられるPE1のメモリは、ローカルメモリでも、分散共有メモリでも、キャッシュメモリでもよい。
【0120】
PE0が変数a[i](0≦i<18)をキャッシュメモリ上で処理し(901)、PE1が変数a[i](18、19)を、PE1のメモリ上に設けられたlocalbuf_pe1[i](i=2、3)を用いて処理し(902)、処理の結果(localbuf_pe1[i](i=2、3))をPE0の分散共有メモリ103に設けられたノンキャッシャブル領域上のncbuf[i](i=2、3)に書き込む(903)。その後、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(904)。
【0121】
その後、PE1で処理された変数ncbuf[i](i=2、3)を分散共有メモリ103のノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](i=18、19)に書き込む(905)。これによって、PE1によって処理された変数a[i](i=18、19)がPE0に転送される。
【0122】
このため、PE0が変数a[i](0≦i<20)を集中共有メモリ160に書き戻し、PE1が変数a[i](20≦i<36)を集中共有メモリ160に書き戻しても、フォルスシェアリングは発生しない。
【0123】
図9A〜図9Cに記載した変形例によると、自プロセシングエレメント上のメモリで境界部分の変数を演算するので、バスを介した他のプロセシングエレメントやメモリへのデータの転送が減り、処理を高速化することができる。
【0124】
図10A及び図10Bは、本発明の第3の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0125】
まず、図10Bに示すように、グローバル変数a、ncbuf_pe0、ncbuf_pe1が宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置され、配列変数4個分のサイズの変数ncbuf_pe0及び変数ncbuf_pe1がノンキャッシャブル領域に設けられる(1000)。この変数ncbuf_pe0は、PE0の分散共有メモリに配置され、変数ncbuf_pe1は、PE1の分散共有メモリに配置される。
【0126】
本実施の形態では、プロセッシングエレメント(PE0)100がi=0からi=17の変数aを処理し、プロセッシングエレメント(PE1)110がi=18からi=35の変数aを処理する。
【0127】
具体的には、プロセッシングエレメント(PE0)100が変数a[i](0≦i<16)をキャッシュメモリ上で処理した(1001)。また、PE0が変数a[i](i=16、17)を分散共有メモリ上のncbuf_pe0において処理し、処理の結果をPE1の分散共有メモリのncbuf_pe1に書き込む(1002)。
【0128】
これと並行して又は前後して、プロセッシングエレメント(PE1)110が変数a[i](i=18、19)を分散共有メモリ上のncbuf_pe1において処理し、処理の結果をPE0の分散共有メモリのncbuf_pe0に書き込む(1004)。また、PE1が変数a[i](20≦i<36)をキャッシュメモリ上で処理する(1005)。
【0129】
また、PE0は、変数ncbuf_pe0[i](0≦i<4)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[i](16≦i<20)に書き込む(1003)。なお、処理の結果のncbuf_pe0への書き込み(1004)からncbuf_pe0のa[i]への書き込み(1003)へのデータ依存によって、PE1によって処理された変数a[i](i=18、19)がncbuf_pe0[i]に格納されている。このため、ステップ1003では、PE0によって処理された変数a[i](i=16、17)及びPE1によって処理された変数a[i](i=18、19)がPE0のキャッシュメモリ上に書き込まれる。
【0130】
その後、PE0及びPE1が処理の結果を集中共有メモリ160に書き戻す。しかし、図5Aを用いて前述した場合と異なり、PE0とPE1との境界領域の変数a[i](16≦i<20)には同じデータが格納されているので、何れのプロセッシングエレメントがデータを書き戻しても、集中共有メモリ160に格納されるデータは変わらない。
【0131】
すなわち、第3の実施の形態では、各プロセシングエレメントは、PE0がアクセスする集中共有メモリの領域とPE1がアクセスする集中共有メモリの領域との境界部分は、分散共有メモリ上のデータを使用して計算をする。
【0132】
なお、PE0のncbuf_pe0と、PE1のncbuf_pe1とは、互いに書き込まれることによって、同じ値が格納されている。このため、PE0が、変数ncbuf_pe0を集中共有メモリに書き込んだ場合、変数ncbuf_pe1のi=2、3も集中共有メモリに書き込まれており、ncbuf_pe0又はncbuf_pe1のいずれかが集中共有メモリに書き込まれることによって、他方のデータも集中共有メモリに書き込まれる。
【0133】
このように、第3の実施の形態では、図10Aに示すように、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、両方のプロセシングエレメントの分散共有メモリ内に設けられたノンキャッシャブル領域に当該ライン上のデータを格納し、両方のノンキャッシャブル領域のデータをコピーすることによって、両ノンキャッシャブル領域のデータが一致し、何れのデータを書き戻しても、フォルスシェアリングは発生しない。
【0134】
なお、本実施の形態では分散共有メモリ上にノンキャッシャブル領域を設ける必要があり、分散共有メモリ間でデータをコピーする処理のオーバーヘッドが生じる。
【0135】
図11は、本発明の第4の実施の形態のフォルスシェアリングの発生を避ける方法の変形例を説明する図である。
【0136】
第4の実施の形態では、ローカル変数を用いることによって、フォルスシェアリングの発生を避ける。
【0137】
まず、図11に示すように、グローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1100)。
【0138】
その後、プロセシングエレメント0(PE0)100が、ローカル変数local_aを宣言し(1101)、変数a[i](0≦i<18)をローカル変数において処理し(1102)、ローカル変数local_a[i](0≦i<18)をグルーバル変数a[i](0≦i<18)へ書き込む(1103)。
【0139】
これと並行して又は前後して、プロセシングエレメント1(PE1)110が、ローカル変数local_aを宣言し(1104)、変数a[i](18≦i<36)をローカル変数において処理し(1105)、i=18からi=35のローカル変数local_a[i](18≦i<36)をグルーバル変数a[i](18≦i<36)に書き込む(1106)。
【0140】
ステップ1106には、ステップ1103からのデータ依存が設定されているので、ステップ1106のlocal_a[i]をa[i]に書き込む前に、a[i](i=16、17)を集中共有メモリ160からロードする。このため、ステップ1006では、PE0で更新されたa[16]及びa[17]を、a[18]及びa[19]と共に集中共有メモリに書き戻す。
【0141】
このように、第4の実施の形態では、図11に示すように、複数のプロセシングエレメントがローカル変数を用いてデータを更新し、各プロセシングエレメントがローカル変数をグローバル変数に書き戻す。このため、第4の実施の形態では、フォルスシェアリングは発生しない。
【0142】
なお、本実施の形態ではプロセシングエレメント間でデータをコピーする処理のオーバーヘッドが生じる。
【0143】
次に、多次元配列を扱う場合について説明する。
【0144】
図12A及び図12Bは、多次元配列を扱う場合、配列変数の要素間でフォルスシェアリングが発生する例を説明する図である。
【0145】
まず、図12Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1200)。キャッシュメモリの1ラインには4個の変数が格納できる。このため、図12Aに示すように、キャッシュメモリの第1ライン1211にはa[0][0]からa[0][3]が存在し、第2ライン1212にはa[0][4]からa[1][1]が存在し、第5ライン1215にはa[2][4]、a[2][5]、a[3][0]、a[3][1]が存在する。
【0146】
その後、プロセッシングエレメント(PE0)100が変数a[i][j]](0≦i<3、0≦j<6)をキャッシュメモリ102上で処理し(1201)、プロセッシングエレメント(PE1)110が変数a[i][j]](3≦i<6、0≦j<6)をキャッシュメモリ112上で処理し(1202)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻す。
【0147】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。また、前述したように、キャッシュラインの境界でループを分割できれば、フォルスシェアリングは発生しない。しかし、PE0によって処理されるa[2][4]及びa[2][5]と、PE1によって処理されるa[3][0]及びa[3][1]とが第5ライン1215上に存在することから、このライン上でPE0によるアクセスとPE1によるアクセスとが競合しフォルスシェアリングが発生する。
【0148】
図13A及び図13Bは、第1の実施の形態を2次元配列変数に適用した例を説明する図である。
【0149】
第1の実施の形態では、キャッシュラインの境界でループを分割するために、配列変数の各要素を外側ループのパラメータ毎に異なるラインに配置する。
【0150】
まず、図13Bに示すように、6×10の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1300)。この配列の各変数a[i][j]は、外側ループのパラメータ毎に異なるラインに配置される。
【0151】
本実施の形態では、キャッシュメモリの1ラインには4個の変数が格納でき、必要な変数は6×6の配列であるので、ラインサイズ(4個)の余分な変数を設けて、6×10の配列変数を定義した。
【0152】
なお、ラインサイズ−1個の余分な変数を設ければよい。
【0153】
さらに、一般化すると、余分な配列変数の数の最低値は、下式が0以上となるSの最低値によって与えられる。
【0154】
余分な配列変数の数の最低値=S(4)の倍数−jmax
S:ラインサイズ
jmax:配列変数の外側ループより一つ内側のループの数(6)
【0155】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<3、0≦j<6)をキャッシュメモリ102上で処理し(1301)、プロセッシングエレメント(PE1)110が変数a[i][j](3≦i<6、0≦j<6)をキャッシュメモリ112上で処理し(1302)、PE0及びPE1が処理の結果をキャッシュメモリ102及び112から集中共有メモリ160に書き戻した。
【0156】
キャッシュメモリ102及び112から集中共有メモリ160へのデータの書き戻しは、ライン単位で行われる。しかし、図12を用いて前述した場合と異なり、図13Bに示すように、PE0とPE1とはキャッシュメモリの同じラインにアクセスしない。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0157】
なお、本実施の形態では、余分な変数が確保されるので、キャッシュメモリの利用効率が低下する。このため、本実施の形態は、配列変数の要素の数が少ないい場合、具体的には、下式を満たす場合に有効である。
【0158】
図14A及び図14Bは、第2の実施の形態を2次元配列変数に適用した例を説明する図である。
【0159】
第2の実施の形態では、キャッシュメモリのラインの区切りによって、各プロセッシングエレメントが処理するデータを分け、複数のプロセッシングエレメントによって処理されたデータがキャッシュメモリの1ライン上に格納されないようにする。
【0160】
まず、図14Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1400)。
【0161】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<4、0≦j<6)をキャッシュメモリ102上で処理し(1401)、プロセッシングエレメント(PE1)110が変数a[i][j](4≦i<6、0≦j<6)をキャッシュメモリ112上で処理する(1402)。その後、PE0が処理の結果をキャッシュメモリ102から集中共有メモリ160に書き戻し、PE1が処理の結果をキャッシュメモリ112から集中共有メモリ160に書き戻す。
【0162】
本実施の形態では、図14Aに示すように、1ラインは4個の変数が格納できる容量を有するが、a[3][6]と、a[4][0]とは異なるライン上に存在する。このため、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0163】
なお、本実施の形態ではPE0に24個、PE1に12個の配列変数の処理を割り当てたが、キャッシュラインサイズの倍数になるように分ければ、PE0に12個、PE1に24個の配列変数の処理を割り当てても、よい。また、各プロセッシングエレメントの処理能力の比に従って数の配列変数の処理を割り当ててもよい。
【0164】
なお、本実施の形態では、対象の次元以下の配列変数の要素のサイズがラインサイズの倍数となればループ分割が可能である。この場合、配列変数の要素の数及びプロセッシングエレメントの数によって割り当てられる配列変数の数が等しくならず、プロセッシングエレメントの処理負荷の不均衡が生じる場合がある。このため、本実施の形態は、配列サイズが十分に大きく、不均衡が配列サイズに比べて無視できるほど小さい場合に有効である。
【0165】
図15A及び図15Bは、第3の実施の形態を2次元配列変数に適用した例を説明する図である。
【0166】
第3の実施の形態では、ノンキャッシャブル領域を用いて、フォルスシェアリングの発生を避ける。
【0167】
まず、図15Bに示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される。また、1×6の1次元の配列変数nc_buf2が宣言され、変数nc_buf2が変数6個(内側ループの数)のサイズのノンキャッシャブル領域が設けられる(1500)。
【0168】
その後、プロセッシングエレメント(PE0)100が変数a[i][j](0≦i<3、0≦j<6)をキャッシュメモリ上で処理し(1501)、プロセッシングエレメント(PE1)110が変数a[3][j](0≦j<6)をnc_buf2[0][j](0≦j<6)を用いてノンキャッシャブル領域上で処理し(1502)、PE1が変数a[i][j](4≦i<6、0≦j<6)をキャッシュメモリ上で処理する(1503)。
【0169】
PE0は、その後又は処理1503と並行して、PE1で処理された変数nc_buf2[0][j](0≦j<6)をノンキャッシャブル領域から読み出し、PE0のキャッシュメモリの変数a[3][j](0≦j<6)に書き込む(1504)。これによって、PE1によってnc_buf2[0][j](0≦j<6)を用いて処理された変数a[3][j](0≦j<6)がPE0に転送される。
【0170】
その後、PE0が変数a[i][j](0≦i<4、0≦j<6)を集中共有メモリ160に書き戻し、PE1が変数a[i][j](4≦i<6、0≦j<6)を集中共有メモリ160に書き戻す。
【0171】
このように、第3の実施の形態では、図15Aに示すように、PE1がノンキャッシャブルバッファを用いて演算した結果をPE0のキャッシュメモリの変数に反映する。すなわち、複数のプロセシングエレメントが同じライン上のデータにアクセスする場合、一方のプロセシングエレメント(PE1)はノンキャッシャブル領域に当該ライン上のデータを格納し、他方のプロセシングエレメント(PE0)はノンキャッシャブル領域のデータを集中共有メモリのキャッシャブル領域に格納するので、複数のプロセシングエレメントが同じラインにデータを書き戻すことがなく、フォルスシェアリングは発生しない。
【0172】
なお、本実施の形態ではメモリ上にノンキャッシャブル領域を設ける必要があるが、ノンキャッシャブル領域は、集中共有メモリ、分散共有メモリ等の何れのメモリに設けてもよい。また、本実施の形態では、ノンキャッシャブル領域からキャッシュメモリにデータをコピーする処理のオーバーヘッドが生じる。しかし、ノンキャッシャブルのバッファとして分散共有メモリを利用することによって、低オーバーヘッドでデータの転送を実現することができる。
【0173】
図16は、第4の実施の形態を2次元配列変数に適用した例を説明する図である。
【0174】
まず、図16に示すように、6×6の2次元配列のグローバル変数aが宣言され、変数aが集中共有メモリのラインの先頭(キャッシュメモリのラインの先頭)に配置される(1600)。
【0175】
その後、プロセシングエレメント0(PE0)100が、6×6の2次元配列のローカル変数local_aを宣言し(1601)、変数a[i][j](0≦i<3、0≦j<6)をローカル変数local_a[i][j]を用いて処理し(1602)、ローカル変数local_a[i][j](0≦i<3、0≦j<6)をグルーバル変数a[i][j](0≦i<3、0≦j<6)へ書き込む(1603)。
【0176】
これと並行して又は前後して、プロセシングエレメント1(PE1)110が、6×6の2次元配列のローカル変数local_aを宣言し(1604)、変数a[i][j](3≦i<6、0≦j<6)をローカル変数local_a[i][j]を用いて処理し(1605)、ローカル変数local_a[i][j](3≦i<6、0≦j<6)をグルーバル変数a[i][j](3≦i<6、0≦j<6)へ書き込む(1606)。
【0177】
ステップ1606には、ステップ1103からのデータ依存が設定されているので、ステップ1606のlocal_a[i][j]をa[i][j]に書き込む前に、a[2][4]、a[2][5]を集中共有メモリ160からロードする。このため、ステップ1006では、PE0で更新されたa[2][4]及びa[2][5]を、a[3][0]及びa[3][1]と共に集中共有メモリに書き戻す。
【0178】
このように、第4の実施の形態では、図16に示すように、複数のプロセシングエレメントがローカル変数を用いてデータを更新し、各プロセシングエレメントがローカル変数をグローバル変数に書き戻す。このため、第4の実施の形態では、フォルスシェアリングは発生しない。
【0179】
なお、本実施の形態ではプロセシングエレメント間でデータをコピーする処理のオーバーヘッドが生じる。
【0180】
以上説明した実施の形態及び変形例は、プログラムのコンパイル時に一つ又は複数を組み合わせて用いることができる。
【0181】
次に、コンパイラが、フォルスシェアリングを回避するために最適な方法を選択する手順について説明する。
【0182】
図17Aは、本発明の実施の形態のループ分割前の処理を示すマクロタスクグラフである。
【0183】
ステップ1710のタスクは、変数iを制御変数とするループであり、ループ分割により生成する部分タスクをそれぞれ別々のプロセッシングエレメントにスケジューリングすることにより並列処理を行う。このタスクを最大分割数でループ分割を行う場合、つまりiループの1イタレーション分の処理を一つの部分タスクとなるようにループ分割した場合に生成される各部分タスクでは、2次元の配列変数Aについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があるということがデータアクセス範囲解析により解析される。同様にステップ1720のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を使用する可能性があり、ステップ1730のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を使用する可能性があり、ステップ1740のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があり、ステップ1750のタスクでは、2次元の配列変数Bについて1次元目の0から99までの要素、2次元目はiからiまでの要素を変更する可能性があることが解析される。ここで、各タスクを最大分割数で分割した場合のアクセス範囲を考慮しているのは、任意の分割パターンでタスク分割を行った場合に、フォルスシェアリングが発生する可能性があるかどうかを解析するためである。
【0184】
各タスクの各部分タスクにおけるデータのアクセス範囲から、フォルスシェアリングが発生する可能性のある箇所とその要因となる配列変数およびその配列次元を解析する。具体的には、前述の部分タスクにおけるデータアクセス範囲において、分割元のタスクにおけるループ制御変数が含まれている次元のうち最も下位の次元において、その下位次元の部分配列サイズをキャッシュメモリのラインサイズで除したときに余りが発生する場合、フォルスシェアリングが発生する可能性があると判断できる。その場合、当該配列の更新を行うタスクの分割後の各部分タスクの間、あるいは当該配列の更新を行うタスクの分割後の各部分タスクとその配列を使用するタスクの分割後の各部分タスクの間でフォルスシェアリングが発生する可能性がある。
【0185】
なお、変数をメモリへ格納する方法がプログラム言語によって異なるので、どの添字を1次元目とするかは、変数のメモリへの格納方法によって異なる。すなわち、メモリの連続した領域に格納される配列変数の要素で変化する添字と最内周ループを構成する添字とが異なる場合、コンパイラは、必要に応じて、計算順序を変えるインターチェンジを行ってもよい。
【0186】
また、配列変数が集中共有メモリ160のラインの先頭にアラインされていない場合、上記の条件にかかわらずフォルスシェアリングが発生する可能性があると解析される。
【0187】
図17Bは、本発明の実施の形態のループ分割後の処理を示すマクロタスクグラフである。本例では各タスクの分割数を3としているが、この分割数は任意に設定することが可能である。
【0188】
図17B中、実線(1本線)は、プログラム上のデータ依存を示し、2重線は、フォルスシェアリングが発生する可能性がある箇所を示す。
【0189】
なお、フォルスシェアリングを検出するコードの例を図17Cに示す。
【0190】
図18は、本発明の実施の形態の並列化コンパイラによるソフトウェアコヒーレンシ制御コードを生成する処理の概要を説明する図である。
【0191】
まず、コンパイルすべきプログラム2001が並列化コンパイラ2002に入力される。入力されるプログラム2001は、C、Fortran等の言語で記述された逐次プログラムである。
【0192】
並列化コンパイラ2002は、入力された逐次プログラムを並列化し、ノンコヒーレントキャッシュで実行するための制御コードが挿入された並列APIプログラム2003を生成する。生成される並列APIプログラム2003は、コヒーレンシ機能を持たないキャッシュメモリを用いてプログラムを実行するための指示(API)を含む並列プログラム形式である。
【0193】
生成された並列APIプログラム2003は、コード生成コンパイラ2004に入力される。コード生成コンパイラ2004は、コヒーレンシ機能を持たないキャッシュメモリを用いてプログラムを実行するための指示(API)を解釈しながら、プログラムを機械語命令(実行形式プログラム)2005に変換する。この実行形式プログラム2005にも、ノンコヒーレントキャッシュでプログラムを実行するための命令が含まれる。
【0194】
図19は、本発明の実施の形態のコンパイラによって実行される処理のフローチャートである。
【0195】
まず、コンパイラは、コンパイルすべきプログラムの字句を解析し、プログラムの構文を解析する(2101)。
【0196】
構文の解析結果に基づいて、階層的なタスク、すなわち、プログラムの階層的マクロタスクによる表現を生成する(2102)。
【0197】
その後、生成されたタスク間の依存関係(制御フロー)を解析し(2103)、タスク間のデータ依存を解析し(2104)、各タスクによってアクセスされるデータの範囲を解析する(2105)。
【0198】
その後、プログラムの解析結果を使用して、プログラムが最も早く実行できる条件を解析し(2106)、最早実行条件の解析結果を使用して、並列処理区間やタスクが割り当てられるプロセッサ数を決定し、マクロタスクグラフを生成する。
【0199】
その後、マクロタスクグラフにおけるデータ依存関係から、図17A、図17B、図17Cを用いて説明した方法によってフォルスシェアリングを検出し、フォルスシェアリングが検出された箇所及びフォルスシェアリングが検出された変数を含むフォルスシェアリング情報を生成する(2107)。
【0200】
その後、生成されたフォルスシェアリング情報に基づいて、フォルスシェアリングが検出された箇所毎に、フォルスシェアリングを回避する方法が決定され、決定された方法に従って命令が挿入され、フォルスシェアリングが回避された並列プログラムが生成される(2108)。このフォルスシェアリング回避処理については、図20A及び図20Bを用いて詳述する。
【0201】
その後、各タスクの実行順序を決定するタスクスケジューリングを実行し(2109)、ステイルデータに対処するためのキャッシュ操作指示を挿入する(2110)。これによって、コヒーレンシ制御機能つき並列プログラムが生成される。このキャッシュ操作指示の挿入処理については、図21を用いて詳述する。
【0202】
図20A及び図20Bは、本発明の実施の形態のフォルスシェアリング回避処理のフローチャートであり、コンパイル処理(図19)のステップ2108から呼び出される。
【0203】
図20A及び図20Bに示すフォルスシェアリング回避処理は、ステップ2107で検出されたフォルスシェアリング情報を入力とし、同じ配列に対して発生する各フォルスシェアリングについて以下の処理を行う。
【0204】
このフォルスシェアリング回避処理は、データレイアウト変換及びリストラクチャリングに大別され、図20Aにデータレイアウト変換処理を示し、図20Bにリストラクチャリング処理を示す。
【0205】
まず、処理の対象となる配列変数が変換可能であるか否かを判定する(2121)。例えば、この配列変数がコンパイルされるプログラム中で閉じている場合、具体的には、コンパイルされるプログラム中で宣言されており、かつ、このプログラム外で定義される関数の引数とならない場合、データレイアウトの変換によりプログラムが予期せぬ動作をする可能性がないので、配列変数が変換可能であると判定する。
【0206】
その結果、配列が変換不可能であると判定された場合、配列の拡張又はパディング等のデータレイアウトの変換が困難であるため、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0207】
一方、配列が変換可能であると判定された場合、配列の最速変化次元の要素間でフォルスシェアリングが発生するか否かを判定する(2122)。具体的には、N次元配列において、最速変化次元を1次元目、最遅変化次元をN次元目と定義する。最速変化次元とは、添字が連続的に変化する配列の次元である。例えば、N次元配列がループによって処理される場合、ループの最内周が最速変化次元となり、ループの最外周が最遅変化次元となる。すなわち、最速変化次元のデータはメモリ上の連続した領域に配置される。
【0208】
その結果、最速変化次元の要素間でフォルスシェアリングが発生すると判定された場合、配列の拡張が可能か否かを判定する(2123)。ステップ2123では、配列を拡張してもキャッシュ利用効率の低下に起因する性能の低下が小さいか否かを判定する。例えば、配列サイズが十分に小さい場合、図6Aに示すように配列を拡張しても、キャッシュ利用効率の低下に起因する性能低下が小さいことから、配列の拡張が可能であると判定する。具体的には、下式(1)を満たす場合、配列サイズが十分に小さいので、配列の拡張が可能であると判定することができる。
【0209】
Sa1≦S×N ・・・(1)
Sa1:対象の配列の1次元目の宣言サイズ
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0210】
その結果、配列の拡張が可能であると判定された場合、プログラム中に図6Bに示すコードを挿入することによって、図6Aに示すように、配列を拡張する。一方、配列の拡張が困難であると判定された場合、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0211】
一方、ステップ2122で、最速変化次元以外の次元の要素間でフォルスシェアリングが発生すると判定された場合、配列のパディングが可能か否かを判定する(2125)。ステップ2125では、配列をパディングしてもキャッシュ利用効率の低下に起因する性能の低下が小さいか否かを判定する。例えば、配列サイズが十分い大きい場合、図13Aに示すように配列をパディングしてもキャッシュ利用効率の低下に起因する性能低下が小さいことから、配列のパディングが可能であると判定する。具体的には、下式(2)を満たす場合、配列サイズが十分に小さいので、配列のパディングが可能であると判定することができる。
【0212】
Sa2≧S×N ・・・(2)
Sa2:対象の配列変数でフォルスシェアリングが発生する次元以下の部分配列サイズ
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0213】
その結果、配列の拡張が可能であると判定された場合、図13Bに示すコードをプログラム中に挿入することによって、図13Aに示すように、配列を拡張する。一方、配列の拡張が困難であると判定された場合、ステップ2131(図20B)に進み、リストラクチャリングを行う。
【0214】
図20Bに示すリストラクチャリング処理では、検出されたフォルスシェアリング情報のうち、データレイアウト変換で対処できなかったフォルスシェアリングに対して、以下の処理を行う。
【0215】
まず、各プロセッサによる処理の境界領域のみでフォルスシェアリングが発生するか否かを判定する(2131)。具体的には、処理の対象となる配列へのアクセスが連続アクセスになっているか否かを判定する。例えば、並列化後に各プロセッサがアクセスする領域が重複している場合(PE0がi、i+2、i+4…とアクセスし、PE1がi+1、i+3、i+5…とアクセスする場合)、処理の対象となる配列へのアクセスは連続アクセスとならないことから、境界領域以外でもフォルスシェアリングが発生する。
【0216】
その結果、境界領域以外でもフォルスシェアリングが発生すると判定された場合、ステップ2139へ進む。
【0217】
一方、境界領域のみでフォルスシェアリングが発生すると判定された場合、フォルスシェアリングが発生すると判定された場所がループによる並列処理であるか否かを判定する(2132)。
【0218】
その結果、ループによる並列処理以外でフォルスシェアリングが発生すると判定された場合、ステップ2139へ進む。
【0219】
一方、ループによる並列処理においてフォルスシェアリングが発生すると判定された場合、キャッシュラインの境界でループを分割できるか否かを判定する(2133)。
【0220】
その結果、キャッシュラインの境界でループを分割できないと判定された場合、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2138)。
【0221】
一方、キャッシュラインの境界でループを分割できると判定された場合、ループの分割に起因する負荷の不均衡による性能低下が小さいか否かを判定する(2134)。例えば、ループ回転数が十分に大きい場合、ループの分割に起因する負荷の不均衡による影響は小さいと判定できる。具体的には、下式(3)を満たす場合、ループ回転数が十分に大きいので、負荷の不均衡による影響は小さいと判定することができる。
【0222】
R≧S×N ・・・(3)
R:ループ回転数
S:キャッシュラインサイズ
N:使用するプロセッサ数
【0223】
また、各プロセッサにタスクを均等に分割した場合、分割されたタスクによって使用されるデータ量(アクセス範囲)の最大値と最小値との差をラインサイズと比較し、この差がラインサイズより小さい場合に負荷不均衡による影響が小さいと判定してもよい。
【0224】
その結果、ループの分割による負荷の不均衡による影響が大きいと判定された場合、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2138)。なお、図10A、図10Bに示す方法を用いてもよく、多次元配列の場合は図15A、図15Bに示す方法を用いる。
【0225】
一方、ループの分割による負荷の不均衡による影響は小さいと判定された場合、キャッシュラインの境界のみでループを分割できるか否かを判定する(2135)。例えば、配列変数の要素a[i]及びa[i+1]に同じループ内でアクセスされる場合、キャッシュラインの境界のみでループを分割することはできない。
【0226】
その結果、キャッシュラインの境界のみでループを分割できると判定された場合、図7Bに示すコードをプログラム中に挿入することによって、図7Aに示すように、キャッシュラインの境界でループを分割する(2136)。なお、多次元配列の場合は図15A、図15Bに示す方法を用いる。
【0227】
一方、配列変数a[i]及びa[i+1]に同じループ内でアクセスされる場合、キャッシュラインの境界のみではループを分割できない場合、キャッシュラインの境界でループを分割できる箇所(例えば、a[i]が分割される箇所)には、図7Bに示すコードをプログラム中に挿入する。さらに、キャッシュラインの境界でループを分割できない箇所(例えば、a[i+1]が分割される箇所)には、図8Bに示すコードをプログラム中に挿入することによって、図8Aに示すように、バッファを用いてプロセッシングエレメント間で通信する(2137)。
【0228】
例えば、a[i]は、キャッシュラインの境界でループを分割し、a[i+1]については、バッファを用いてプロセッシングエレメント間で通信するとよい。この場合、a[i]のアクセス回数とa[i+1]のアクセス回数とを比較し、アクセス回数が多い配列変数の要素の添字について、キャッシュラインの境界でループを分割して、バッファに格納されたデータの通信のオーバーヘッドを少なくするとよい。
【0229】
一方、ステップ2139では、各プロセッシングエレメントにおける演算に用いられるプライベート変数からグローバル変数へのコピー処理のオーバーヘッドが小さいか否かを判定する。具体的には、ループ中で実行される計算の処理量が十分に大きい場合、コピー処理のオーバーヘッドは無視できる程度の小さい。例えば、単に他の変数のデータをaへ代入(コピー)する場合、ループ中で実行される計算の処理量は小さいが、ループ中で四則演算や関数による計算結果をaへ代入している場合、ループ中で実行される計算の処理量は大きくなる。
【0230】
その結果、変数のコピー処理のオーバーヘッドが小さいと判定された場合、図11に示すコード(多次元配列の場合は図16に示すコード)をプログラム中に挿入することによって、各プロセッシングエレメントにおいて定義されたプライベート変数を用いて演算をし、演算の結果をプライベート変数からグローバル変数へコピーする(2140)。
【0231】
一方、変数のコピー処理のオーバーヘッドが大きいと判定された場合、各プロセッシングエレメントによる演算の結果を、逐次、集中共有メモリ160に書き込む(2141)。
【0232】
図21は、本発明の実施の形態のキャッシュ操作指示の挿入処理のフローチャートである。
【0233】
まず、並列化フェイズにおけるタスクグラフのスケジューリング結果において、異なるプロセッサに割り当てられたタスク間のデータ依存を解析する(2151)。
【0234】
解析されたデータの依存関係が、フロー依存又は出力依存であるか否かを判定する(2152)。その結果、解析されたデータの依存関係がフロー依存又は出力依存である場合、キャッシュ操作指示を挿入する。
【0235】
具体的には、図3Bを用いて前述したように、データを生産する側のプロセシングエレメントが、データを更新後にライトバック命令によって主記憶(集中共有メモリ160)に更新されたデータを書き戻すキャッシュ操作指示と、データを消費する側のプロセシングエレメントが、データを消費する前にセルフインバリデート命令によって主記憶からデータを読み込むキャッシュ操作指示と生成し、生成されたキャッシュ操作指示をプログラム中に挿入する。このとき、生産側のプロセシングエレメントによるデータの更新の終了はフラグによって消費側のプロセシングエレメントに通知され、消費側のプロセシングエレメントはフラグの更新によってデータの更新を知り、更新されたデータを主記憶から読み込むように制御される。コンパイラは、このフラグによる制御命令を生成し、生成された制御命令をプログラム中に挿入する。
【0236】
一方、解析されたデータの依存関係がフロー依存でも出力依存でもない場合、キャッシュ操作指示の挿入処理を終了する。
【0237】
以上説明したように、本発明の実施の形態によると、ソフトウェアによる制御によって、コヒーレンシ制御のためのハードウェアが不要となり、ハードウェアを簡素化できる。このため、低コストかつ低消費電力のマルチプロセッサを実現できる。また、コンパイラの最適化によって、スケーラブルな性能向上が可能となる。
【0238】
特許請求の範囲に記載した以外の本発明の観点の代表的なものとして、次のものがあげられる。
【0239】
(1)複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備えるマルチプロセッサシステムであって、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントは、
前記主記憶装置から読み込んだデータを前記キャッシュメモリに一時的に格納し、
使用が終了したデータを前記キャッシュメモリから、前記キャッシュメモリの管理単位に従って、前記主記憶装置に書き戻し、
前記プログラムを分割して生成される各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納することを特徴とするマルチプロセッサシステム。
【0240】
(2)前記プロセッシングエレメントは、少なくとも第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記第1のプロセッシングエレメントは、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算し、
前記第2のプロセッシングエレメントは、
前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記ノンキャッシャブル領域で演算し、
前記ノンキャッシャブル領域で演算した結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送することを特徴とする(1)に記載のマルチプロセッサシステム。
【0241】
(3)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記各プロセッシングエレメントは、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算し、
前記第1のプロセッシングエレメントは、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込むことを特徴とする(1)に記載のマルチプロセッサシステム。
【0242】
(4)異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻し、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化することを特徴とする(1)から(3)のいずれか一つに記載のマルチプロセッサシステム。
【0243】
(5)マルチプロセッサシステムに備わるプロセッサにおいて演算処理を実行させるプログラムであって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリの管理単位に従ってデータが転送され、
前記プログラムは、各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順を含むことを特徴とするプログラム。
【0244】
(6)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算する手順と、
前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順と、
前記第2のプロセッシングエレメントが、前記ノンキャッシャブル領域に格納された演算結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送する手順とを含むことを特徴とする(5)に記載のプログラム。
【0245】
(7)前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算する手順と、
前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込む手順とを含むことを特徴とする(5)に記載のプログラム。
【0246】
(8)異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻す手順と、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化する手順とを含むことを特徴とする(5)から(7)のいずれか一つに記載のプログラム。
【符号の説明】
【0247】
100、110、120 プロセシングエレメント
101、111、121 プロセッサ
102、112、122 キャッシュメモリ
150 内部結合網
160 集中共有メモリ(主記憶)
【特許請求の範囲】
【請求項1】
マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを、コンパイラによって生成する方法であって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリの管理単位に従ってデータが転送され、
前記方法は、
前記プロセッサによって実行されるプログラムを解析し、
前記プログラムに含まれる各タスクの実行に必要なデータを解析し、
前記解析の結果に基づいて、前記各タスクを分割した場合、前記分割されたタスクによって使用されるデータの境界がメモリの管理単位と整合するか否かを判定し、
前記タスクによって使用されるデータの境界がメモリの管理単位と整合しないと判定された場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設けるコードと、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納するコードとを生成することを特徴とするコードの生成方法。
【請求項2】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記プログラムの解析結果に基づいて、前記第1のプロセッシングエレメントによって実行されるタスクと前記第2のプロセッシングエレメントによって実行されるタスクとの境界がメモリの管理単位と整合しないと判定された場合、前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算するコードと、前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納するコードと、前記ノンキャッシャブル領域に格納された演算結果を前記第1のプロセッシングエレメントのキャッシュメモリに転送するコードとを生成することを特徴とする請求項1に記載のコードの生成方法。
【請求項3】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメントに設けられ、
前記プログラムの解析結果に基づいて、前記第1のプロセッシングエレメントによって実行されるタスクと前記第2のプロセッシングエレメントによって実行されるタスクとの境界がメモリの管理単位と整合しないと判定された場合、前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算するコードと、前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込むコードとを生成することを特徴とする請求項1に記載のコードの生成方法。
【請求項4】
前記ノンキャッシャブル領域を前記主記憶装置に設ける命令又は設定文を生成することを特徴とする請求項1又は2に記載のコードの生成方法。
【請求項5】
前記各プロセッシングエレメントは、前記各プロセッシングエレメントからアクセス可能な分散共有メモリ備え、
前記ノンキャッシャブル領域を前記分散共有メモリに設ける命令又は設定文を生成することを特徴とする請求項1から3のいずれか一つに記載のコードの生成方法。
【請求項6】
前記プログラムの解析結果に基づいて、前記分割されたタスクが前記主記憶の複数の領域にアクセスすると判定された場合、タスクによって使用されるデータの境界と整合する前記メモリの管理単位については、当該管理単位に整合するように前記タスクを分割し、前記タスクによって使用されるデータの境界と整合しない管理単位については、データが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を用いて、当該境界を含む前記管理単位に格納されたデータを演算するコードを生成することを特徴とする請求項1から5のいずれか一つに記載のコードの生成方法。
【請求項7】
前記プログラムの解析結果に基づいて、前記タスクによって使用されるデータが、当該プログラムにおいて宣言され、当該プログラムのみで使用されると判定された場合、当該データの複数の要素が前記各管理単位に配置されないように配列を拡張するコードを生成することを特徴とする請求項1から6のいずれか一つに記載のコードの生成方法。
【請求項8】
前記タスクによって使用されるデータは配列変数であって、
前記プログラムの解析結果に基づいて、前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が発生している箇所を判定し、
前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が、前記配列変数の要素が前記主記憶装置の連続する領域に格納される次元の要素間で発生している場合、前記配列変数の複数の要素が前記各管理単位に配置されないように前記配列変数を拡張するコードを生成し、
前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が、前記配列変数の要素が前記主記憶装置の連続する領域に格納される次元の要素間で発生していない場合、前記不整合が発生している次元より下位の複数の次元の前記配列変数の要素が前記各管理単位に配置されないように前記配列変数を拡張するコードを生成することを特徴とする請求項7に記載のコードの生成方法。
【請求項9】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記各プロセシングエレメント毎に、当該プロセシングエレメント内で使用されるローカル変数を定義するコードと、
前記各プロセッシングエレメントが前記定義されたローカル変数を用いて演算をするコードと、
前記第1のプロセシングエレメントが前記ローカル変数で演算した結果を主記憶装置に書き戻すコードと、
前記第2のプロセシングエレメントが前記第1のプロセシングエレメントによる演算結果を前記主記憶装置から読み込むコードと、
前記第2のプロセシングエレメントが前記主記憶装置から読み込んだデータを前記キャッシュメモリに書き込むコードとを含むことを特徴とする請求項1から8のいずれか一つに記載のコードの生成方法。
【請求項10】
異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、前記データを生産するプロセシングエレメントが前記依存関係があるデータを前記主記憶装置に書き戻すコードと、前記データを消費するプロセシングエレメントが前記依存関係があるデータを無効化するコードとを生成することを特徴とする請求項1から9のいずれか一つに記載のコードの生成方法。
【請求項11】
マルチプロセッサシステムに備わるプロセッサがプログラムを実行する際にメモリの記憶領域を管理する方法であって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記方法は、
前記プロセッシングエレメントが、前記主記憶装置から読み込んだデータを、前記キャッシュメモリの管理単位に従って、前記キャッシュメモリに一時的に格納する手順と、
前記プロセッシングエレメントによる使用が終了したデータを、前記キャッシュメモリの管理単位に従って、前記キャッシュメモリから前記主記憶装置に書き戻す手順と、
前記プログラムを分割して生成される各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順とを含むことを特徴とする記憶領域の管理方法。
【請求項12】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算する手順と、
前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順と、
前記第2のプロセッシングエレメントが、前記ノンキャッシャブル領域に格納された演算結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送する手順とを含むことを特徴とする請求項11に記載の記憶領域の管理方法。
【請求項13】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算する手順と、
前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込む手順とを含むことを特徴とする請求項11に記載の記憶領域の管理方法。
【請求項14】
異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻し、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化することを特徴とする請求項11から13のいずれか一つに記載の記憶領域の管理方法。
【請求項15】
マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを生成するプログラムであって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリのアクセス管理単位に従ってデータが転送され、
前記コード生成プログラムは、当該プログラムを実行する計算機に
前記プロセッサによって実行されるプログラムを解析する手順と、
前記プログラムに含まれる各タスクの実行に必要なデータを解析する手順と、
前記解析の結果に基づいて、前記プログラムを前記各タスクをに分割した場合に、前記分割されたタスクによって使用されるデータの境界がメモリのアクセス管理単位と整合するか否かを判定する手順と、
前記タスクによって使用されるデータの境界がメモリのアクセス管理単位と整合しないと判定された場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設けるコードと用いて、当該タスクによって使用されるデータの境界を含むアクセス管理単位に格納されたデータを演算結果を前記ノンキャッシャブル領域に格納するコードとを生成する手順とを実行させることを特徴とするコード生成プログラム。
【請求項1】
マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを、コンパイラによって生成する方法であって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリの管理単位に従ってデータが転送され、
前記方法は、
前記プロセッサによって実行されるプログラムを解析し、
前記プログラムに含まれる各タスクの実行に必要なデータを解析し、
前記解析の結果に基づいて、前記各タスクを分割した場合、前記分割されたタスクによって使用されるデータの境界がメモリの管理単位と整合するか否かを判定し、
前記タスクによって使用されるデータの境界がメモリの管理単位と整合しないと判定された場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設けるコードと、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納するコードとを生成することを特徴とするコードの生成方法。
【請求項2】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記プログラムの解析結果に基づいて、前記第1のプロセッシングエレメントによって実行されるタスクと前記第2のプロセッシングエレメントによって実行されるタスクとの境界がメモリの管理単位と整合しないと判定された場合、前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算するコードと、前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納するコードと、前記ノンキャッシャブル領域に格納された演算結果を前記第1のプロセッシングエレメントのキャッシュメモリに転送するコードとを生成することを特徴とする請求項1に記載のコードの生成方法。
【請求項3】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメントに設けられ、
前記プログラムの解析結果に基づいて、前記第1のプロセッシングエレメントによって実行されるタスクと前記第2のプロセッシングエレメントによって実行されるタスクとの境界がメモリの管理単位と整合しないと判定された場合、前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算するコードと、前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込むコードとを生成することを特徴とする請求項1に記載のコードの生成方法。
【請求項4】
前記ノンキャッシャブル領域を前記主記憶装置に設ける命令又は設定文を生成することを特徴とする請求項1又は2に記載のコードの生成方法。
【請求項5】
前記各プロセッシングエレメントは、前記各プロセッシングエレメントからアクセス可能な分散共有メモリ備え、
前記ノンキャッシャブル領域を前記分散共有メモリに設ける命令又は設定文を生成することを特徴とする請求項1から3のいずれか一つに記載のコードの生成方法。
【請求項6】
前記プログラムの解析結果に基づいて、前記分割されたタスクが前記主記憶の複数の領域にアクセスすると判定された場合、タスクによって使用されるデータの境界と整合する前記メモリの管理単位については、当該管理単位に整合するように前記タスクを分割し、前記タスクによって使用されるデータの境界と整合しない管理単位については、データが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を用いて、当該境界を含む前記管理単位に格納されたデータを演算するコードを生成することを特徴とする請求項1から5のいずれか一つに記載のコードの生成方法。
【請求項7】
前記プログラムの解析結果に基づいて、前記タスクによって使用されるデータが、当該プログラムにおいて宣言され、当該プログラムのみで使用されると判定された場合、当該データの複数の要素が前記各管理単位に配置されないように配列を拡張するコードを生成することを特徴とする請求項1から6のいずれか一つに記載のコードの生成方法。
【請求項8】
前記タスクによって使用されるデータは配列変数であって、
前記プログラムの解析結果に基づいて、前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が発生している箇所を判定し、
前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が、前記配列変数の要素が前記主記憶装置の連続する領域に格納される次元の要素間で発生している場合、前記配列変数の複数の要素が前記各管理単位に配置されないように前記配列変数を拡張するコードを生成し、
前記分割されたタスクによって使用されるデータの境界と前記管理単位との不整合が、前記配列変数の要素が前記主記憶装置の連続する領域に格納される次元の要素間で発生していない場合、前記不整合が発生している次元より下位の複数の次元の前記配列変数の要素が前記各管理単位に配置されないように前記配列変数を拡張するコードを生成することを特徴とする請求項7に記載のコードの生成方法。
【請求項9】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記各プロセシングエレメント毎に、当該プロセシングエレメント内で使用されるローカル変数を定義するコードと、
前記各プロセッシングエレメントが前記定義されたローカル変数を用いて演算をするコードと、
前記第1のプロセシングエレメントが前記ローカル変数で演算した結果を主記憶装置に書き戻すコードと、
前記第2のプロセシングエレメントが前記第1のプロセシングエレメントによる演算結果を前記主記憶装置から読み込むコードと、
前記第2のプロセシングエレメントが前記主記憶装置から読み込んだデータを前記キャッシュメモリに書き込むコードとを含むことを特徴とする請求項1から8のいずれか一つに記載のコードの生成方法。
【請求項10】
異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、前記データを生産するプロセシングエレメントが前記依存関係があるデータを前記主記憶装置に書き戻すコードと、前記データを消費するプロセシングエレメントが前記依存関係があるデータを無効化するコードとを生成することを特徴とする請求項1から9のいずれか一つに記載のコードの生成方法。
【請求項11】
マルチプロセッサシステムに備わるプロセッサがプログラムを実行する際にメモリの記憶領域を管理する方法であって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記方法は、
前記プロセッシングエレメントが、前記主記憶装置から読み込んだデータを、前記キャッシュメモリの管理単位に従って、前記キャッシュメモリに一時的に格納する手順と、
前記プロセッシングエレメントによる使用が終了したデータを、前記キャッシュメモリの管理単位に従って、前記キャッシュメモリから前記主記憶装置に書き戻す手順と、
前記プログラムを分割して生成される各タスクによって使用されるデータの境界がメモリの管理単位と整合しない場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設け、当該境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順とを含むことを特徴とする記憶領域の管理方法。
【請求項12】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記第1のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを前記キャッシュメモリにおいて演算する手順と、
前記第2のプロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納された演算結果を前記ノンキャッシャブル領域に格納する手順と、
前記第2のプロセッシングエレメントが、前記ノンキャッシャブル領域に格納された演算結果を、前記第1のプロセッシングエレメントのキャッシュメモリに転送する手順とを含むことを特徴とする請求項11に記載の記憶領域の管理方法。
【請求項13】
前記プロセッシングエレメントは、第1のプロセッシングエレメント及び第2のプロセッシングエレメントを含み、
前記ノンキャッシャブル領域は、前記各プロセッシングエレメント毎に設けられ、
前記ノンキャッシャブル領域を用いて演算する手順は、
前記各プロセッシングエレメントが、前記タスクによって使用されるデータの境界を含む管理単位に格納されたデータを自プロセッシングエレメントのノンキャッシャブル領域において演算する手順と、
前記第1のプロセッシングエレメントが、前記ノンキャッシャブル領域で演算した結果を、前記第2のプロセッシングエレメントの共有メモリに書き込む手順とを含むことを特徴とする請求項11に記載の記憶領域の管理方法。
【請求項14】
異なる前記プロセッシングエレメントによって実行されるタスク間でデータ依存がある場合、
前記データを生産するプロセシングエレメントが、前記依存関係があるデータを前記主記憶装置に書き戻し、
前記データを消費するプロセシングエレメントが、前記依存関係があるデータを無効化することを特徴とする請求項11から13のいずれか一つに記載の記憶領域の管理方法。
【請求項15】
マルチプロセッサシステムに備わるプロセッサによって実行可能なコードを生成するプログラムであって、
前記マルチプロセッサシステムは、複数のプロセッシングエレメントと、前記各プロセッシングエレメントからアクセス可能な主記憶装置とを備え、
前記各プロセッシングエレメントは、演算処理をするプロセッサと、前記プロセッサによって使用されるデータが一時的に格納されるキャッシュメモリとを備え、
前記プロセッシングエレメントが前記主記憶装置から読み込んだデータは、前記キャッシュメモリに一時的に格納され、
前記プロセッシングエレメントによる使用が終了したデータは、前記キャッシュメモリから前記主記憶装置に書き戻され、
前記主記憶装置と前記キャッシュメモリとの間では、前記キャッシュメモリのアクセス管理単位に従ってデータが転送され、
前記コード生成プログラムは、当該プログラムを実行する計算機に
前記プロセッサによって実行されるプログラムを解析する手順と、
前記プログラムに含まれる各タスクの実行に必要なデータを解析する手順と、
前記解析の結果に基づいて、前記プログラムを前記各タスクをに分割した場合に、前記分割されたタスクによって使用されるデータの境界がメモリのアクセス管理単位と整合するか否かを判定する手順と、
前記タスクによって使用されるデータの境界がメモリのアクセス管理単位と整合しないと判定された場合、当該境界を含む管理単位に格納されるべきデータが前記キャッシュメモリに一時的に格納されないノンキャッシャブル領域を設けるコードと用いて、当該タスクによって使用されるデータの境界を含むアクセス管理単位に格納されたデータを演算結果を前記ノンキャッシャブル領域に格納するコードとを生成する手順とを実行させることを特徴とするコード生成プログラム。
【図1】
【図2】
【図3A】
【図3B】
【図4】
【図6B】
【図9A】
【図10B】
【図11】
【図13B】
【図15B】
【図16】
【図17A】
【図17B】
【図17C】
【図18】
【図19】
【図20A】
【図20B】
【図21】
【図22】
【図23】
【図5A】
【図5B】
【図6A】
【図7A】
【図7B】
【図8A】
【図8B】
【図8C】
【図8D】
【図9B】
【図9C】
【図10A】
【図12A】
【図12B】
【図13A】
【図14A】
【図14B】
【図15A】
【図2】
【図3A】
【図3B】
【図4】
【図6B】
【図9A】
【図10B】
【図11】
【図13B】
【図15B】
【図16】
【図17A】
【図17B】
【図17C】
【図18】
【図19】
【図20A】
【図20B】
【図21】
【図22】
【図23】
【図5A】
【図5B】
【図6A】
【図7A】
【図7B】
【図8A】
【図8B】
【図8C】
【図8D】
【図9B】
【図9C】
【図10A】
【図12A】
【図12B】
【図13A】
【図14A】
【図14B】
【図15A】
【公開番号】特開2011−128803(P2011−128803A)
【公開日】平成23年6月30日(2011.6.30)
【国際特許分類】
【出願番号】特願2009−285586(P2009−285586)
【出願日】平成21年12月16日(2009.12.16)
【出願人】(899000068)学校法人早稲田大学 (602)
【Fターム(参考)】
【公開日】平成23年6月30日(2011.6.30)
【国際特許分類】
【出願日】平成21年12月16日(2009.12.16)
【出願人】(899000068)学校法人早稲田大学 (602)
【Fターム(参考)】
[ Back to top ]