(57)【要約】本発明は、順次処理を行うプロセッサとリコンフィギュラブルアレイとを同時に動作させる方法に関し、ここではデータは前記リコンフィギュラブルアレイに、該アレイに対するデータキャッシュから転送され、上記アレイにて前記データから形成された結果が宛先に書き込まれる。【特許請求の範囲】
【請求項１】
順次実行形プロセッサとリコンフィギュラブルアレイとを同時に動作させる方法において、
データを前記リコンフィギュラブルアレイに、該アレイに対するデータキャッシュから転送し、
当該データから当該アレイにて形成された結果を宛先に書き込むことを特徴とする、
順次実行形プロセッサとリコンフィギュラブルアレイとを同時に動作させる方法。
【請求項２】
前記宛先は、前記順次実行形プロセッサの算術ユニットの上流に配置されている、
請求項１に記載の方法。
【請求項３】
前記リコンフィギュラブルアレイからのデータ出力を、少なくとも部分的に、処理ユニットのデコーディング回路の下流にある前記プロセッサユニットのデータパスに供給する、
請求項１または２の記載の方法。
【請求項４】
前記のプロセッサの算術論理ユニットは、リコンフィギュラブルアレイから出力されるデータに対して少なくとも１つの演算を行うように適合化されている、
請求項１から３までのいずれか１項に記載の方法。
【請求項５】
前記算術論理回路は、乗算および／または除算および／または殊に前記リコンフィギュラブルアレイから出力されるデータに実行される演算のための回路を含んでおり、
当該の演算には、乗算および／または除算および／または正規化（norming）が含まれる、
請求項１から４までのいずれか１項に記載の方法。
【請求項６】
前記のリコンフィギュラブルアレイから出力されるデータは有利には、前記の順次実行形処理ユニットのレジスタおよび／またはキャッシュの以外のメモリ位置に選択に書き込み可能である、
請求項１から５までのいずれか１項に記載の方法。
【請求項７】
前記の宛先は、算術論理ユニットの下流および／または前記処理ユニットに結合されたキャッシュの上流にある、
請求項１から６までのいずれか１項に記載の方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、複数のデータ処理素子から成るリコンフィギュアラブルアレイの作動方法に関する。
【０００２】
この種のアレイを使用する場合に望ましいのは、アレイを他のユニットに結合するやり方たとえばコプロセッサとして使用されるならばプロセッサに結合するやり方を最適化することであり、および／またはアレイをコンフィギュレーションするやり方を最適化することである。
【０００３】
本発明の目的は従来技術を改善することにある。
【０００４】
なお、本発明の開示内容はその説明に関して複数の主要な部分から成り、それらすべてはアレイの最適な使用を可能にする手法に関するものであり、したがってそれらの部分は密に関係し合っている。
【０００５】
また、それらの部分にはテキストに関係する複数の図面が含まれているが、それらについて必ずしも精確かつ精密かつ適正に言及がなされているわけではない。とはいえ当業者であれば、適正な参照からの何らかの逸脱は自明である。
【０００６】
第１主要部
１  実施概要  ４
２  ハードウェア  ６
２．１  デザインパラメータの変更  ６
２．１．１  パイプライン／コンカレンシー／シンクロニシティ  ６
２．１．３  ソフトウェア／マルチタスクオペレーシングシステム  ７
２．２  ＲＩＳＣコアとＸＰＰコアとの通信  ８
２．２．１  ストリーミング  ８
２．２．２  共有メモリ（メインメモリ）  ８
２．２．３  共有メモリ（ＩＲＡＭ）  ８
２．３  ＸＰＰコアの状態  ９
２．３．１  メモリトラフィックの制限  １０
２．４  コンテキスト切り替え  １０
２．４．１  ＳＭＴ仮想プロセッサスイッチ  １１
２．４．２  入力サービスルーチン  １１
２．４．３  タスクスイッチ  １１
２．５  ロードストアアーキテクチャ  １２
２．５．１  基本的な実装  １４
２．５．２  実装の改善  １７
２．５．３  データディストリビューションおよびデータ認識のサポート  １８
２．６  ソフトウェア／ハードウェアインタフェース  ２０
２．６．１  明示的なキャッシュ  ２０
２．７  その他の実装  ２２
２．７．１  プログラミングモデルの変更  ２４
２．７．２  実装の詳細の隠蔽  ２４
３  プログラム最適化  ２５
３．１  コード解析  ２５
３．１．１  データフロー解析  ２５
３．１．２  データ依存関係解析  ２６
３．１．３  プロシージャ間のエイリアス解析  ２８
３．１．４  プロシージャ間の値のレンジの解析  ２９
３．１．５  アライメント解析  ３０
３．２  コード最適化  ３１
３．２．１  一般的な変換  ３１
３．２．２  ループ変換  ３２
３．２．３  データレイアウト最適化  ４０
３．２．４  最適化の適用例  ４１
４  ＰＡＣＴ ＸＰＰ用コンパイラの仕様  ４５
４．１  イントロダクション  ４５
４．２  コンパイラの構造  ４５
４．２．１  コード準備処理  ４６
４．２．２  パーティショニング  ４６
４．２．３  ＲＩＳＣコード生成およびスケジューリング  ４７
４．３  ループのためのＸＰＰコンパイラ  ４７
４．３．１  一時的なパーティショニング  ４８
４．３．２  ＮＭＬコードの生成  ４８
４．３．３  マッピングステップ  ４８
４．４  ＸＰＰループ最適化ドライバ  ４８
４．４．１  システムの組織化  ４８
４．４．２  ループ準備処理  ５０
４．４．３  データ依存関係グラフの変換  ５０
４．４．４  アーキテクチャに関するパラメータの影響  ５０
４．４．５  ハードウェア改善に向けた最適化  ５６
４．４．６  コンフィギュレーション実行時間の制限  ５９
５  ケーススタディ  ６０
５．１  ３ｘ３エッジ検出器  ６０
５．１．１  オリジナルコード  ６０
５．１．２  前変換  ６１
５．１．３  プリコード生成変換  ６３
５．１．４  ＸＰＰコード生成  ６４
５．１．５  並列性の増強  ６８
５．１．６  パラメータ化ファンクション  ７０
５．２  ＦＩＲフィルタ  ７２
５．２．１  オリジナルコード  ７２
５．２．２  第１の解決策  ７３
５．２．３  いっそう並列的な解決策  ７７
５．２．４  他の変形例  ８３
５．３  行列乗算  ８４
５．３．１  オリジナルコード  ８４
５．３．２  前変換  ８４
５．３．３  ＸＰＰコード生成  ９０
５．４  ビタビエンコーダ  ９３
５．４．１  オリジナルコード  ９３
５．４．２  プロシージャ間の最適化およびスカラ変換  ９４
５．４．３  初期化  ９５
５．４．４  バタフライループ  ９９
５．４．５  再最適化  １０３
５．４．６  最終コード  １０３
５．５  ＭＰＥＧ２  エンコーダ／デコーダ  １０７
５．５．１  量子化／逆量子化（quant.c）  １０７
５．５．２  逆離散コサイン変換（idct.c）  １１１
５．６  ウェーブレット  １２３
５．６．１  オリジナルコード  １２３
５．６．２  全体ループネストの最適化  １２３
５．６．３  内側ループの最適化  １３４
６  参考文献
１  実施概要
この研究は以下の３つの目的に係わるものである。
１．ＰＡＣＴ ＸＰＰコアを標準ＲＩＳＣプロセッサアーキテクチャに効率的に組み込むことのできるハードウェアフレームワークの提案
２．結合されたＲＩＳＣ＋ＸＰＰハードウェアのためのコンパイラの提案。このコンパイラは、ソースコードのいずれの部分がＲＩＳＣプロセッサにおいて実行されるのか、いずれの部分がＰＡＣＴ ＸＰＰにおいて実行されるのかを自動的に判定する。
３．複数のケーススタディのデモンストレーションに関するプレゼンテーション。その結果は、提案するＣコンパイラを提案するハードウェアフレームワークと共働させて利用することによって達成できる。
【０００７】
提案するハードウェアフレームによってＸＰＰコアは２つの点で加速される。第１に、ＸＰＰの内部動作周波数をＲＩＳＣ周波数まで引き上げることにより、データスループットが上昇する。しかしこのことは、ＸＰＰがすべての高い周波数のプロセッサと同じ落とし穴に陥ることを意味し、メモリアクセスはプロセッサ内部の計算に比べて著しく遅くなる。これがキャッシュの使用を提案する理由である。これによって、ＸＰＰ上で実行するのに適したアルゴリズムの広い範囲にわたってメモリアクセスの問題が簡単になる。第２のスループットを上昇させるフィーチャとしてのキャッシュのためにはコントローラが必要とされる。したがってプログラマブルキャッシュコントローラが導入され、これによってキャッシュ内容が管理され、ＸＰＰコアに供給される。これによればＸＰＰコアの計算がデータ伝送から分離され、その際にたとえば特定のキャッシュセクタにプリロードされたデータが生じる一方、ＸＰＰは異なるキャッシュセクタに配置されたデータにおいて動作する。
【０００８】
結合されたＲＩＳＣ＋ＸＰＰハードウェアにより発生する別の問題点は、ＲＩＳＣのマルチタスクコンセプトに係わるものである。これによれば、タスクスイッチ実行のためＸＰＰ上で計算を中断しなければならない。提案するコンパイラによっても提案するハードウェアによっても、マルチタスクがサポートされている。第１に、各ＸＰＰコンフィギュレーションは割り込み不可能なエンティティとみなされる。つまりこのことは、コンフィギュレーションを生成するコンパイラは、コンフィギュレーションの実行時間が所定のタイムスライスを超えないよう留意することを意味する。第２にキャッシュコントローラは、割り込み後のＸＰＰにおける状態のセーブとリストアに係わる。提案するキャッシュコンセプトによって、割り込み処理のためのメモリトラフィックが最小限に抑えられ、メモリアクセスをまったく避けることすら頻繁に可能になる。
【０００９】
さらに、提案するキャッシュコンセプトはシンプルなＩＲＡＭセルストラクチャに基づくものであり、これによればたとえばＸＰＰのキャッシュサイズを拡張するハードウェアの簡単なスケーラビリティが可能となり、そのためにＩＲＡＭセルのデュプリケート以外のことはたいして必要とされない。
【００１０】
この研究によれば、ＲＩＳＣ＋ＸＰＰのためのコンパイラが提案される。コンパイラの目標はＣ言語で書かれた実際のアプリケーションであり、これをＲＩＳＣ＋ＸＰＰシステムのためにコンパイルすることができる。このコンパイラによれば、ＸＰＰのためのＮＭＬコードを手で開発する必要性が取り除かれる。その代わりに、Ｃ言語でアルゴリズムを実装することができ、あるいはＸＰＰシステムに対し整合をたいして行うことなく、既存のＣアプリケーションをそのまま使用することができる。提案するコンパイラには、ＸＰＰのためのコンパイルプロセスを実行するために３つの主要なコンポーネントが含まれている：
１．ＣソースコードをＲＩＳＣパートとＸＰＰパートに分割
２．ＸＰＰのためのコードを最適化するために変換
３．ＮＭＬコードを生成
生成されたＮＭＬコードは、最終的にＸＰＰのために配置されルーティングされる。
【００１１】
コンパイラにおける分割コンポーネントは、アプリケーションのどのパートをＸＰＰで実行することができ、どのパートをＲＩＳＣで実行することができるかを判定する。ＸＰＰコードになるための候補は多数の反復を伴うループであって、このループボディの大部分は算術演算である。残りのソースコードはデータ変換コードも含めて、ＲＩＳＣのためにコンパイルされる。
【００１２】
提案するコンパイラはＸＰＰコードを、ＮＭＬコード生成に最適化されるよう変換する。コンパイラに含まれている変換は、多数のループ変換も含まれているし汎用コード変換も含まれている。データコード解析とともにコンパイラは、ＸＰＰアレイにフィットするよう、さらには最終的なパフォーマンスが純粋なＲＩＳＣパフォーマンスを超えるよう、コードを再構成する。最後にコンパイラは、変換されたプログラムからＮＭＬコードを生成する。コンパイルプロセス全体は最適化ドライバによりコントロールされ、これはソースコードに基づき最適な変換順序を選択する。
【００１３】
ケーススタディはこの研究の主要なアスペクトを成している。選ばれた事例は、各事例が一連の典型的な実際のアプリケーションを代表しているという原則を与えることで進められる。事例ごとに研究によって、提案されたコンパイラの働きがデモンストレーションされる。最初にコードが分割される。その際、コンパイラによってなされるコード変換を示して説明する。いくつかの事例のためには、手動で実行する必要のある小さいソースコード変換が必要とされる。研究によって判明したのは、これらの変換はコストがかかりすぎるし、あるいは提案するコンパイラに含まれるということを理解するには細かすぎる。ＮＭＬコードを生成するためコンパイラにより使用される事例ごとに、変換されたコードのデータフローグラフが構成される。さらにこれに加えて、ＸＰＰリソースの使用法も示す。
【００１４】
ケーススタディによれば、提案する変換を含むコンパイラはＸＰＰのための多数のアプリケーションから効率的なコードを生成することができることがデモンストレーションされる。このことが可能である理由は、コンパイラはキャッシュコントローラなど提案するハードウェアの特徴に基づいているからである。
【００１５】
２  ハードウェア
２．１  デザインパラメータの変更
ＸＰＰコアは機能ユニットとして標準ＲＩＳＣコアに統合されることになるので、いくつかのシステムパラメータを再考する必要がある。
【００１６】
２．１．１  パイプライニング／コンカレンシー／シンクロニシティ
完全に異なるタイプＲＩＳＣ命令（Ld/St, ALU, Mul/Div/MAC, FPALU, FPMul...）は、平均的にビジーであるシリコン部分を増加させるため別個に専用化された機能ユニットにおいて実行される。このように機能ユニットを分離した結果、スーパースカラＲＩＳＣデザインに至り、これによればいっそう高度な並列性が活用される。
【００１７】
ＲＩＳＣの各機能ユニットは、スループット改善のため高度にパイプライン化されている。パイプライニングは、複数の命令を関連のないフェーズに分割することでそれらの実行をオーバラップさせ、それらはパイプラインの種々のステージで実行される。したがって連続する命令の種々のステージを並列に実行することができ、その際に各ステージは実行するために僅かな時間しかとらない。これによっていっそう高度なコア周波数が可能となる。
【００１８】
すべての機能ユニットのパイプラインは近似的に同じサイズ（実行時間）のサブオペレーションに分割されるので、これらの機能ユニット／パイプライン命令は、複雑な浮動小数点パイプラインは例外として、高度に同期がとられながら実行される。
【００１９】
ＸＰＰコアはデータフロー計算を使用するので、デザインによってパイプライン化されている。しかしながら１つのコンフィギュレーションによって通常はアプリケーションの１つのループが実装されるので、多くのサイクルにわたりコンフィギュレーションはアクティブなままであり、これは典型的にはせいぜい１サイクルまたは２サイクルの間に実行される他のすべての機能ユニットにおける命令とは異なる。したがってこの比較的粗いスケールのパイプラインを介したコンカレンシーを改善するため、１つのＸＰＰコンフィギュレーション（＝ＸＰＰ命令）における複数のフェーズ（たとえばLd/Ex/Store）を複数の機能ユニットに分割することをさらに考慮する価値がある。これによって、マルチタスクオペレーションならびに同時に発生するマルチスレッド（ＳＭＴ）の実装に関連してスループットと応答時間も改善される。
【００２０】
マルチサイクル実行時間によっても強固に同時性のある実行パターンが禁止され、むしろたとえば浮動小数点平方根ユニットのためなど非同期のパターンが生じる。他方、これによって明示的な同期命令の存在が必要とされる。
【００２１】
コア周波数／メモリ階層
機能ユニットとして、ＸＰＰ動作周波数はコア周波数の半分とされるかまたはＲＩＳＣのコア周波数と等しくされる。現在市販されているほとんどすべてのＲＩＳＣコアのコア周波数はそのメモリバス周波数を大きな率で超えている。したがってキャッシュが採用され、これによりいわゆるメモリ階層が形成される：キャッシュの各レイヤは前者よりも大きいけれども遅い。
【００２２】
このメモリ階層によっても、データを僅かに再利用するだけでまたはデータを再利用せずに大量のデータをシャッフルする計算をスピードアップする役には立たない。このような計算は「メモリ帯域幅バウンド」と呼ばれる。しかしながらもっと多くのデータ局所性（データ再利用の別名）を伴う他のタイプの計算によって、それらがメモリ階層における低い方のレイヤのうちの１つに整合しているかぎり、パフォーマンスが得られる。これは、メモリ階層が導入されるときに最高のスピードアップを得るアプリケーションのクラスである。
【００２３】
メモリ階層の低い方のレイヤに整合させるには大きすぎるデータセットを伴うメモリバウンドなアルゴリズムを変換するために、古典的なベクトル化を使用することができる。いっそう小さいデータセットを再利用するためにコードを書き換えるとただちに、いっそう小さいスケールでのメモリ再利用が現れる。新しいデータセットのサイズはメモリ階層のキャッシュに整合するよう選定されるので、アルゴリズムはもはやメモリバウンドではなく、著しいスピードアップが得られるようになる。
【００２４】
２．１．３  ソフトウェア／マルチタスクオペレーティングシステム
ＸＰＰがＲＩＳＣコアに導入されるので、変更された環境（いっそう高い周波数およびメモリ階層）のためにハードウェアデザインパラメータの再考だけでなくソフトウェア環境の再評価も必要とされる。
【００２５】
メモリ階層
メモリ階層の導入によって、効率的に実装可能なアプリケーションのセットが強められる。これまでＸＰＰは主としてデータセットを直線的に読み出すアルゴリズムのために使用されてきており、この場合、いくつかの計算はパイプライン化されたかたちで適用され、データはメモリに書き戻される。計算すべてがＸＰＰアレイに整合しているかぎり、これらのアルゴリズムはメモリバウンドである。典型的なアプリケーションは一般にフィルタリングおよび音声信号処理である。
【００２６】
しかし、計算がいっそう複雑でメモリ帯域幅の要求がいっそう高い別の一連のアルゴリズムも存在する。その例は画像処理およびビデオ処理であり、この場合、２次元および２次元のデータコヒーレンスが生じる。このコヒーレンスはたとえば画像およびビデオの圧縮アルゴリズムによって活用され、これによれば類似性について１つのビデオストリームの連続画像がサーチされるにしても相似性を見つけるため２つの次元で画像がスキャンされる。もちろんこれらのアルゴリズムのアルゴリズム的複雑性はいっそう高く、メモリ要求もいっそう高い。それらは意図的にまだデータローカルであり、あるいはそれらを、メモリ階層ならびにメモリ階層をもつプロセッサのいっそう高いクロック周波数を効率的に活用するよう変換することができる。
【００２７】
マルチタスク
標準ＲＩＳＣコアに導入するためには、マルチタスクオペレーティングシステムの必要性を理解しサポートしなければならない。それというのもＲＩＳＣプロセッサは一般にマルチタスク環境で動かされるからである。マルチタスクによれば、オペレーティングシステムは規則的なベースに基づき実行アプリケーションを切り替え、複数のアプリケーション（タスク）のコンカレントな実行をシミュレートする。タスクを切り替えるため、オペレーティングシステムは実行中のタスクの状態（たとえばすべてのレジスタの内容）をセーブし、ついて他のタスクの状態をリロードする必要がある。したがってプロセッサがどんな状態であるかを判定し、効率的なコンテキスト切り替えを行えるようできるかぎり小さくそれを保持する必要がある。
【００２８】
最新のマイクロプロセッサは、高いコア周波数を可能にする特殊化され深くパイプライン化された複数の機能ユニットならびに高度なメモリ階層からそのパフォーマンスを得ている。しかし高度なメモリ階層ということは、コアとメモリの周波数の差に起因してキャッシュミスのペナルティが高いことを意味する。値がメモリから最終的に得られるまでに多くのコアサイクルが経過する。深いパイプラインゆえに、データ依存関係に起因するパイプラインストールが引き起こされるし、誤って予測された条件分岐に対する分岐ペナルティも引き起こされる。浮動小数点ユニットのような特殊化された機能ユニットは整数のみのプログラムの間、遊んでいる。これらの理由から、平均的な機能ユニット利用率がかなり下がりすぎてしまう。
【００２９】
ＲＩＳＣプロセッサによる最新の環境である同時マルチスレッド（Simultaneous MultiThreading SMT）によれば、いっそう細かい粒度（命令／機能ユニットレベル）のタスクの切り替えを行うためのハードウェアサポートが付加され、これによれば２つ以上の独立した命令ストリームが実行させられる。したがってある１つの命令ストリームがストールするかまたは機能ユニットをすべては利用しないときはいつでも、他のストリームをそこにジャンプさせることができる。
【００３０】
ＳＭＴによれば、タスク（プロセス）の切り替えはハードウェアにおいて行われるので、プロセッサの状態のデュプリケートをハードウェアにおいて形成しなければならない。したがってここでも、その状態をできるかぎり小さく保持するのが効率的である。ＰＡＣＴ ＸＰＰと標準ＲＩＳＣプロセッサとを組み合わせるために、ＳＭＴは非常に有利である。なぜならば、ＸＰＰコンフィギュレーションは平均的なＲＩＳＣ命令よりも長く実行されるからである。したがってコンフィギュレーション実行中、他のタスクが他の機能ユニットを利用することができる。他方、すべてのタスクがＸＰＰを利用するというわけではないので、ＸＰＰタスクではない１つのタスクが実行されている間、別のタスクがＸＰＰコアを利用することができる。
【００３１】
２．２  ＲＩＳＣコアとＸＰＰコアとの通信
以下のセクションでは、メモリをアクセスするための複数の可能なハードウェアインプリメンテーションについて説明する。
【００３２】
２．２．１  ストリーミング
ストリーミングはサイクルあたり［ＩＯポートの個数*ＩＯポートの幅］というビットしかサポートできないので、僅かな入出力を特徴とする重くパイプライン化されたコンフィギュレーションを伴う小さいＸＰＰアレイのためにのみ良好に適している。パイプラインは充填したり空にしたりするのに長い時間をとる一方、１つのコンフィギュレーションの実行時間は（「コンテキスト切り替え」のところで説明したように）制限されているので、この種の通信をいっそう大きいＸＰＰアレイおよびＲＩＳＣコア周波数に近いＸＰＰ周波数に良好にはスケーリングされない。
・ＲＩＳＣコアからのストリーミング
このセットアップにおいて、ＲＩＳＣはＸＰＰアレイにストリーミングデータを供給する。ＲＩＳＣコアはアドレスを計算しメモリからのアイテムをロードするために複数の命令を実行しなければならないので、このセットアップはＸＰＰコアがＲＩＳＣコア周波数よりもずっと低い周波数でデータを読み出す場合にしか適していない。
・ＤＭＡを介したストリーミング
このモードではＲＩＳＣはＤＭＡチャネルの初期化だけを行い、ついでＤＭＡチャネルはデータアイテムをＸＰＰコアのストリーミングポートへ供給する。
【００３３】
２．２．２  共有メモリ（メインメモリ）
このコンフィギュレーションにおいてＸＰＰアレイコンフィギュレーションは、ＩＯポートを介してメインメモリをアクセスするために用いられるアドレスを生成する目的で、複数のＰＡＥを使用する。ＩＯポートの個数は非常に制限されているので、いっそう大きいＸＰＰアレイに対しアドレス生成のためにＰＡＥを使用する影響は少ないにもかかわらず、このアプローチは前者と同じ制限を受けることになる。しかしながらこのアプローチは、著しく僅かなベクトルから値をロードするためには依然として有用である。
【００３４】
２．２．３  共有メモリ（ＩＲＡＭ）
このデータアクセスメカニズムは、ローカルな計算のためのデータを格納するためにＩＲＡＭ素子を使用する。ＩＲＡＭはベクトルレジスタとみなすことができ、あるいはメインメモリのローカルなコピーとみなすことができる。この場合、ＩＲＡＭにデータを満たすために複数のやり方が存在する。
１．ストリーミングを使用する別個のコンフィギュレーションによって、ＩＲＡＭをまえもってロードしておく。
【００３５】
この手法は現在のＸＰＰアーキテクチャによって実装することができる。ＩＲＡＭはベクトルレジスタとして振る舞う。上述のようにこれによりＸＰＰアレイのパフォーマンスが制約されることになり、その理由は殊に、ＩＲＡＭが常に外部からみえる状態の一部分であり、したがってコンテキスト切り替えにあたりセーブとリストアが必要とされるからである。
２．ＩＲＡＭを別個のロード命令によりまえもってロードしておくことができる。
【００３６】
これは１番目の方法と似ている。ロード命令は、データをＩＲＡＭにロードするハードウェアにインプリメントされる。このロード命令は、ハードコーディングされたロード命令とみなすことができる。したがってコンフィギュレーションのリドードが低減される。これに加えて特別なロード命令は、メモリ階層に対するいっそう広いインタフェースを使用することができる。このためストリーミングよりもいっそう効率的な手法を使用することができる。
３．ＩＲＡＭを、キャッシュコントローラの「メモリからのバーストプリロード burst preload from memory」命令によってロードすることができる。ＸＰＰにおいてコンフィギュレーションまたはロード命令は必要とされない。ＩＲＡＭロードはキャッシュコントローラに実装され、ＲＩＳＣプロセッサによってトリガされる。ただしＩＲＡＭは依然としてベクトルレジスタとして振る舞い、それゆえ外部から見える状態に含まれている。
４．とはいえ最良のモードは、上述の解決策とキャッシュの拡張との組み合わせである：
プリロード命令により、開始アドレスとサイズによって定義された所定のメモリエリアがＩＲＡＭにマッピングされる。これによってメモリ階層（キャッシュ）からの（遅延された低い優先度の）バーストロードがトリガされる。すべてのＩＲＡＭがマッピングされた後、次のコンフィグレーションをアクティブにすることができる。アクティブ状態にすることで、すべてのバーストロードが完了するまでウェイトが生じる。しかしながらプリロード命令が十分前に発行されて、割り込みやタスク切り替えによってもキャッシュの局所性が破壊されなければ、ウェイトによっていかなる時間も消費しないことになる。
【００３７】
ある１つのメモリブロックをアウトプットオンリーＩＲＡＭとして指定するために「プリロードクリーン」命令が用いられ、この命令によってメモリからのデータのロードが回避される。［プリロードクリーン」命令によって、書き戻しのためにＩＲＡＭが指示される。
【００３８】
ＩＲＡＭにキャッシュされている特定のメモリエリアの内容メモリ階層に確実に書き戻せるようにするために、同期命令が必要とされる。このことは包括的に行うことができるし（全体の書き戻し）、あるいはアクセスされることになるメモリエリアを選択的に指定することによって行うこともできる。
【００３９】
２．３  ＸＰＰコアの状態
先のセクションで述べたように、状態のサイズはコンテキスト切り替えのために重要である。しかしながら、状態のサイズがＸＰＰコアに関して一定であるにもかかわらず、これはそれらをセーブすべきか否かという種々の状態の要素の宣言に依存している。
【００４０】
ＸＰＰコアの状態を以下のように分類することができる：
１．リードオンリ（命令データ）
・ＰＡＥコンフィギュレーションデータとルーティングコンフィギュレーションデータから成るコンフィギュレーションデータ
２．リード−ライト
・バスに送られるデータレジスタおよびＰＡＥのラッチの内容
・ＩＲＡＭ素子の内容
２．３．１  メモリトラフィックの制限
コンテキスト切り替え中にメモリトラフィック量を制限するために複数の可能性がある。
【００４１】
リードオンリーデータはセーブしない
コンフィギュレーションデータはリードオンリであるため、これによってコンフィギュレーションデータの格納が回避される。現在のコンフィギュレーションは新たなものによって単純に上書きされる。
【００４２】
僅かなデータだけをセーブ
コンフィギュレーションが割り込み不可能であると定義されているならば（ノンプリエンプティブ）、バスおよびＰＡＥにおけるローカルな状態すべてがスクラッチとして宣言される。つまりこのことは、すべてのコンフィギュレーションはその入力データをＩＲＡＭから受け取り、その出力データをＩＲＡＭに書き込むことを意味する。このためコンフィギュレーションが完了してしまえば、ＰＡＥおよびバスにおけるすべての情報が冗長なものとなりあるいは無効となり、セーブする必要がなくなる。
【００４３】
変更されたデータのみセーブ
セーブしなければならない読み出しデータおよび書き込みデータの量を減らす目的で、種々のエンティティにおける変更状態を覚えておく必要がある。これによれば付加的な「ダーティな」ビットのためにシリコンエリアにペナルティが生じる。
【００４４】
メモリトラフィックを低減するためにキャッシングを利用
コンフィグレーションマネージャは、コンフィギュレーションの手動によるプリロードを扱う。プリロードは、タスク切り替え中にメモリ転送を他の計算と並列処理するときに役立つことになる。プリロードメカニズムに加えて最低使用頻度（Least Recently Used LRU）置換ストラテジが実装されているならば、頻繁なコンテキスト切り替えに対しこのキャッシュによってメモリトラフィックを低減することもできる。
【００４５】
セクション２．２．３における４番目の方法として提案したように、ＩＲＡＭをメインメモリのローカルなキャッシュコピーとして定義することができる。この場合、各ＩＲＡＭは開始アドレスおよび変更状態情報と対応づけられている。ＩＲＡＭメモリセルはレプリケートされる。ＩＲＡＭ ＰＥＡには、複数のＩＲＡＭインスタンスをもつＩＲＡＭブロックが含まれている。ＩＲＡＭの開始アドレスだけを、コンテキストとしてセーブしリストアすることができる。現在のコンフィギュレーションのＩＲＡＭのための開始アドレスによって、使用される同一のアドレスをもつＩＲＡＭインスタンスが選択される。
【００４６】
ＩＲＡＭインスタンスのアドレスタグが新たにロードされたコンテキストのアドレスにマッチしているならば、対応するメモリエリアが空のＩＲＡＭインスタンスにロードされる。
【００４７】
空のＩＲＡＭインスタンスが利用できるのであれば、クリーンな（変更されていない）インスタンスが空であると宣言される（したがってあとでリロードする必要がある）。
【００４８】
クリーンなＩＲＡＭインスタンスが利用できなければ、変更された（ダーティな）インスタンスがそのデータをメインメモリに書き戻すことによってクリーンにされる。これにより書き戻しに対して所定の遅延が加わる。
【００４９】
別個の状態マシン（キャッシュコントローラ）が非アクティブ状態にあるクリーンなＩＲＡＭインスタンスを、使われていないメモリサイクルを用いてＩＲＡＭインスタンスの内容を書き戻すことによってクリーンにしようとするならば、上述の遅延を回避することができる。
【００５０】
２．４  コンテキスト切り替え
１つのプロセッサは通常、単一の命令ストリームを実行するものとみなされる。しかし今日のマルチタスクオペレーティングシステムによれば、シングルプロセッサ上で実行される数１００のタスクがサポートされる。このことはコンテキスト切り替えによって達成され、その場合、現在のタスク（タスクのコンテキスト）に属するプロセッサ状態のすべてまたは少なくともほとんどの主要部分が、次に実行されることになる別のタスクの状態と交換される。
【００５１】
この場合、３つの種類のコンテキスト切り替えが存在する。すなわちそれらは同時マルチスレッディング（ＳＭＴ、ハイパースレッディングとしても知られている）を伴う仮想プロセッサの切り替え、割り込みサービスルーチン（ＩＳＲ）の実行、ならびにタスクスイッチである。
【００５２】
２．４．１  ＳＭＴ仮想プロセッサスイッチ
このタイプのコンテキストスイッチは、ソフトウェアインタラクションを伴わず完全にハードウェアで実行される。命令レベルの並列性を高めかつ機能ユニットの利用率を改善するため、複数の命令ストリームの命令が単一の命令ストリームにマージされる。したがってプロセッサ状態を格納することはできず、種々異なる命令ストリームから命令間でメモリからリロードすることはできない。２つのストリームから交互に命令が生じる最悪のケースを考えると、プロセッサ状態をメモリに書き込み他の状態で読み出すために数１００〜数１０００のサイクルが必要とされる。
【００５３】
このためハードウェアデザイナは、すべての仮想プロセッサのために内部状態をレプリケートする必要がある。すべての命令は仮想プロセッサの（状態における）コンテキスト内で実行され、そのプログラムカウンタは命令をフェッチするために使用されたものである。状態をレプリケートする場合、種々の状態のうちの１つを選択するために挿入すべきマルチプレクサだけを切り替えればよい。
【００５４】
したがって状態のサイズによりＳＭＴの実装に必要とされるシリコンエリアが増大し、このため状態のサイズは数多くのデザイン決定にとって重要である。
【００５５】
２．４．２  割り込みサービスルーチン
この種のコンテキストスイッチは、部分的にハードウェアにより処理され部分的にソフトウェアにより処理される。ＩＳＲにより変更されたすべての状態は入口でセーブされなければならず、出口でリストアされなければならない。
【００５６】
ＩＳＲへのジャンプにより破壊される状態の一部分はハードウェアによりセーブされる（たとえばプログラムカウンタ）。ＩＳＲ内で現在使用されている他のすべてのリソースの状態をセーブしリストアするのはＩＳＲの役割である。セーブすべき情報が増えれば増えるほど、割り込み応答時間が遅くなり、外部イベントが割り込みを拘束にトリガするならばパフォーマンスの影響が大きくなる。
【００５７】
さらに命令の実行モデルも、短い割り込みレイテンシと最大スループットとの間のトレードオフに影響を及ぼすことになる：パイプラインにおける命令が完了すればスループットが最大になり、ＩＳＲの命令がチェーンされる。このことは割り込みレイテンシに不利に作用する。しかし割り込みレイテンシが短くなるよう命令を廃棄すれば（プリエンプティブ）、それらをあとでもう一度フェッチしなければならず、これはスループットに影響を及ぼす。３番目の可能性は、パイプライン内の命令の内部状態をセーブすることであるが、このためにはハードウェアが複雑になりすぎる。通常、このことは行われない。
【００５８】
２．４．３  タスク切り替え
この種のコンテキスト切り替えは完全にソフトウェアによって実行される。タスクのコンテキスト（状態）のすべてはメモリにセーブしなければならず、新たなタスクのコンテキストはリロードしなければならない。タスクは通常、パフォーマンス達成のためプロセッサリソースのすべてを使用することができるので、プロセッサ状態のすべてをセーブしリストアしなければならない。状態の量が過剰になれば、リスケジューリングの頻度を少なくすることでコンテキスト切り替え速度を低減しなければならず、あるいは大部分の時間をタスクコンテキストのセーブとリストアとに費やすことになるため、スループットの著しい低減が生じることになる。他方、このことによってタスクのための応答時間が増大する。
【００５９】
２．５  ロード／ストア・アーキテクチャ
本発明によれば、ＲＩＳＣ用の非同期パイプライン化機能ユニットとしてのＸＰＰインテグレーションが提案される。さらに本発明によれば（セクション２．２．３における第４の方法として提案したように）ＲＩＳＣ内に存在するメモリ階層のトップに、ＩＲＡＭのための明示的にプリロードされたキャッシュを用いることが提案される。これに加えて、コンフィギュレーションのプリロードおよび各コンフィギュレーションの高速切り替えをサポートする目的で、明示的にプリロードされた分散型のコンフィギュレーションが採用される。
【００６０】
ＩＲＡＭの内容は明示的にプリロードされたメモリエリアであるので、仮想的に制約のない個数のこの種のＩＲＡＭを使用することができる。それらは自身のメモリアドレスとサイズとによって同定される。ＩＲＡＭの内容はアプリケーションによって明示的にプリロードされる。メモリ階層からデータを再利用することから、キャッシングによってパフォーマンスが増大することになる。キャッシュされたオペレーションによって、明示的なストア命令も必要なくなる。それらはキャッシュの書き戻しオペレーションによって暗黙的に処理されるけれども、ＲＩＳＣと同期合わせするために強制することもできる。
【００６１】
ＸＰＰ機能ユニットのパイプラインステージはロード、実行および書き戻し（ストア）である。ストアはキャッシュ書き戻しとして遅延されて実行される。パイプラインステージは非同期で実行されるので、キャッシュプリロードおよびＰＡＥアレイからの可変の遅延は隠される。
【００６２】
ＸＰＰ機能ユニットはＦＩＦＯによりＲＩＳＣから分離され、これにはＸＰＰ命令が供給される。このＦＩＦＯの先頭において、ＸＰＰ ＰＡＥはコンフィギュレーションおよびプリロードされたＩＲＡＭを消費して実行する。ＸＰＰとＲＩＳＣの同期合わせは同期命令によって明示的に行われる。
【００６３】
命令
以下、提案するアーキテクチャのために必要とされる命令フォーマットについて定義する。データ型を指定するため、Ｃ言語スタイルのプロトライプ定義を使用する。XppSync命令を除いてすべての命令は非同期で実行される。XppSync命令は同期を強制するために用いることができる。
【００６４】
XPPPreloadConfig(void *ConfigurationStartAddress)
ＰＡＥアレイ内のコンフィギュレーションキャッシュにロードすべきプリロードＦＩＦＯにコンフィギュレーションが加えられる。
【００６５】
なお、連続的なプリロードコマンドによって先行のものが上書きされるため、投機的プリロードが可能である。パラメータは、ＲＩＳＣポインタレジスタファイルのポインタレジスタである。サイズはコンフィギュレーション内に暗黙的に含まれている。
【００６６】
XPPPreload(int IRAM, void *StartAdress, int Size)
XPPPreloadClean(int IRAM, void *StartAddress, int Size)
この命令によって、次のコンフィギュレーション実行のためのＩＲＡＭの内容が指定される。実際、指定されたＩＲＡＭにロードすべきプリロードＦＩＦＯにメモリエリアが加えられる。
【００６７】
第１のパラメータはＩＲＡＭ番号である。これは即値（定数）である。第２のパラメータは開始アドレスへのポインタである。このパラメータはＲＩＳＣポインタレジスタファイルのポインタレジスタ内に設けられている。第３のパラメータは３２ｂｉｔワードの単位のサイズである。これは整数値であり、ＲＩＳＣ整数レジスタファイルにおける汎用レジスタ内に存在する。
【００６８】
第１の変数は現在、メモリからのデータをプリロードする。第２の変数はライトオンリーアクセスのためである。これによりローディングオペレーションがスキップされる。したがってこのＩＲＡＭについてキャッシュミスが発生する可能性はない。アドレスとサイズだけが定義される。これらは明らかにＩＲＡＭキャッシュの書き戻しオペレーションのために必要とされる。なお、同じＩＲＡＭに対する連続的なプリロードコマンドは（その間にコンフィギュレーションが実行されなければ）互いに上書きし合うので、投機的なプリロードが可能である。
【００６９】
XPPExecute()
この命令により、最後にプリロードされたＩＲＡＭ内容で最後にプリロードされたコンフィギュレーションが実行される。実際、コンフィギュレーションスタートコマンドがＦＩＦＯに発行される。ついでＦＩＦＯが進められる。つまりプリロードコマンドによって、次のコンフィギュレーションまたは次のコンフィギュレーションのパラメータが指定されることになる。スタート命令がすでに発行されているならば、コンフィギュレーションが終わると常に、次のコンフィギュレーションがＦＩＦＯの先頭から消費される。
【００７０】
XPPSync(void *StartAdress, int Size)
この命令により、所定のメモリエリアをオーバラップしているすべてのＩＲＡＭに対する書き戻しオペレーションが強制される。オーバラップしているＩＲＡＭが使用すべきコンフィギュレーションまたはプリロードによってまだ使用中であるならば、このオペレーションはブロックされることになる。ＮＵＬＬ（ゼロ）のアドレスと（実際のメモリよりも大きいMAX_INTのサイズを与えれば、発行されたすべてのコンフィギュレーションが完了するまで待機させるためにこの命令を用いることもできる。
【００７１】
２．５．１  基本的な実装
【００７２】
【数１】
2005535055.tif 000002
【００７３】
上述の図面におけるプリロードＦＩＦＯには、すでに発行されたＩＲＡＭプリロードのためのアドレスとサイズが含まれており、それらはＸＰＰキャッシュコントローラに与えられる。ＦＩＦＯは、ＳＭＴ環境におけるすべての仮想プロセッサのためにデュプリケートする必要がある。この場合、タグは開始アドレス、サイズおよび状態（エンプティ｜クリーン｜ダーティ｜使用中）。付加的な使用中状態によって、現在のコンフィギュレーションによる使用がシグナリングされる。キャッシュコントローラはそれらのＩＲＡＭインスタンスを操作できない。
【００７４】
実行コンフィギュレーションコマンドによってすべてのプリロードＦＩＦＯが進められ、古い状態が新たに生成されたエントリにコピーされる。このようにして後続のプリロードは、先行して使用されていたＩＲＡＭおよびコンフィギュレーションを置き換える。コンフィギュレーション実行前にＩＲＡＭに対してプリロードが発行されなければ、先行のコンフィギュレーションのプリロードが保持される。それゆえ、連続するコンフィギュレーションにおけるＩＲＡＭのために同一のプリロードを繰り返す必要がない。
【００７５】
【数２】
2005535055.tif 000003
【００７６】
各コンフィギュレーションの実行コマンドはすべての必要なプリロードが完了するまで、同期コマンドの使用によって明示的にあるいはキャッシュコントローラによって暗黙的に遅延（ストール）させなければならない。したがってキャッシュコントローラ（XPP Ld/Stユニット）は同期を処理しコマンドも処理しなければならず、これによりすべてのデータが準備完了状態になるとすぐにコンフィギュレーションが開始される。コンフィギュレーション完了後、ダーティなＩＲＡＭはその内容が同じＩＲＡＭにおいて再利用されないのであれば、できるだけ早くメモリに書き戻される。したがってＸＰＰ ＰＡＥアレイとＸＰＰキャッシュコントローラを単一のユニットとみなすことができる。その理由は、それらは異なる命令ストリームをもっていないからである。むしろキャッシュコントローラを、コンフィギュレーションフェッチ（ＣＦ）、オペランドフェッチ（ＯＦ）（ＩＲＡＭプリロード）およびＸＰＰパイプラインの書き戻し（ＷＢ）ステージとみなすことができ、これによって実行ステージ（ＥＸ）（ＰＡＥアレイ）もトリガされる。
【００７７】
長いレイテンシならびにそれらの非予測性（キャッシュミス、可変の長さのコンフィギュレーション）ゆえに、コンフィギュレーションおよび緩い結合のためのＦＩＦＯ（＝パイプライン）を使用して、複数のコンフィギュレーションにわたりステージをオーバラップすることができる。コンフィギュレーションが実行され、次のコンフィギュレーションのためのデータがすでにプリロードされているならば、１つおいて次のコンフィギュレーションのためのデータがプリロードされる。これらのプリロードは投機的に行うことができる：投機の量はコンパイラのトレードオフである。プリロードＦＩＦＯのリーズナブルな長さを複数のコンフィギュレーションとすることができる。これは収量漸減、アルゴリズムプロパティ、早期にプリロードをスケジューリングするコンパイラの能力、さらにはＦＩＦＯの長さと少なくとも同じでなければならないＩＲＡＭデュプリケートファクタに基づくシリコンの使用によって制約される。このように緩く結合されたオペレーションゆえに、ＩＲＡＭ間のデータハザードを回避するためのインターロックはソフトウェア（スケジューリング）によっても最適には行うことができないけれども、これはハードウェアによって強制しなければならない（ハードウェアインターロック）。したがってＸＰＰキャッシュコントローラとＸＰＰ ＰＡＥアレイを、別個には設けられているけれども完全には独立していない機能ユニットとみなすことができる。
【００７８】
【数３】
2005535055.tif 000004
【００７９】
ＸＰＰキャッシュコントローラは複数のタスクを有している。これらのタスクは上記の図面において状態として描かれている。状態遷移は、エッジに対する条件が真であるときには常に、各状態間のエッジに沿って行われる。条件がもはや真ではなくなるとただちに、反転状態遷移が生じる。これらの状態に対するアクティビティは以下の通りである。
【００８０】
最も低い優先順位においてＸＰＰキャッシュコントローラは、ダーティなＩＲＡＭをできるかぎり早く書き戻している間に、すでに発行されているプリロードコマンドを履行しなければならない。
【００８１】
コンフィギュレーションが完了すれば、次のコンフィギュレーションをただちにスタートさせることができる。これは書き戻しまたは以降のプリロードよりも緊急のタスクである。このことを行えるようにする目的で、まだ履行されていないプリロードを最初に完了させなければならない。したがってそれらは実行状態から継承された高い優先度でプリロードされる。
【００８２】
プリロード自体は、異なるブロックにおける使用中のＩＲＡＭまたはダーティなＩＲＡＭのオーバラップによって、あるいはターゲットのＩＲＡＭブロックに空のＩＲＡＭがないことによって阻止される可能性がある。前者は、コンフィギュレーションが完了するのを待つことによって、および／または書き戻しによって解決することができる。後者を解決するために、最低使用頻度のクリーンなＩＲＡＭを廃棄して空にすることができる。空のまたはクリーンなＩＲＡＭインスタンスが存在しないのであれば、ダーティなＩＲＡＭをメモリ階層に書き戻す必要がある。空のまたはクリーンなまたはダーティなＩＲＡＭインスタンスが存在しないということはあり得ない。なぜならば１つのインスタンスだけを使用中とすることができ、ＩＲＡＭブロック内に２つ以上のインスタンスが存在するはずであり、さもなければ達成できない。
【００８３】
【数４】
2005535055.tif 000005
【００８４】
ＳＭＴ環境の場合、すべての仮想プロセッサについてロードＦＩＦＯをレプリケートしなければならない。機能ユニットのパイプラインは共有フェッチ／リオーダ／発行ステージから供給される。すべての機能ユニットは並列に実行される。それぞれ異なるユニットがそれぞれ異なる仮想プロセッサの命令を実行することができる。
【００８５】
したがって、それぞれ最小の初期値をもつ以下の出剤パラメータが得られる：
ＩＲＡＭの長さ：１２８ワード
ＩＲＡＭの長さが長くなればなるほど、コンフィギュレーションの実行時間が長くなり、パイプラインのスタートアップの影響は小さくなる。
ＦＩＦＯの長さ：１
このパラメータはプリロード中のキャッシュミスを隠すのに役立つ。ＦＩＦＯの長さが長くなればなるほど、単一のコンフィギュレーションに対する一連のキャッシュミスの破壊性が小さくなる。
ＩＲＡＭデュプリケーションファクタ：（パイプラインステージ＋キャッシングファクタ）*仮想プロセッサ：３
パイプラインステージは、１以上のすべてのＦＩＦＯステージについてパイプラインステージＬＤ／ＥＸ／ＥＢ＋１の個数である：３
キャッシングファクタは、キャッシングのために利用可能なＩＲＡＭデュプリケートの個数である：０
仮想プロセッサは、ＳＭＴによる仮想プロセッサの個数である：１
仮想プロセッサにおける状態のトータルサイズは主としてＦＩＦＯの長さに依存する：
ＦＩＦＯの長さ*#ＩＲＡＭポート*（３２ｂｉｔ（アドレス）＋３２ｂｉｔ（サイズ））
これはすべての仮想プロセッサについてレプリケートされなければならない。
ＩＲＡＭのために使用されるメモリのトータルサイズ：
＃ＩＲＡＭポート*ＩＲＡＭデュプリケーションファクタ*ＩＲＡＭの長さ*３２ｂｉｔ
第１の実装は上述の最小パラメータに近い値におそらく保持されることになり、この場合、ＦＩＦＯの長さを１、ＩＲＡＭデュプリケーションファクタを４、ＩＲＡＭの長さを１２８とし、同時マルチスレッディングは用いられない。
【００８６】
２．５．２  実装の改善
書き込みポインタ
ロードされていないＩＲＡＭの欠点をさらに低減するため、ＩＲＡＭごとに単純な書き込みポインタを使用することができ、このポインタはすでにＩＲＡＭにおいて最終アドレスを保持している。したがってこの書き込みポインタの及ばないアクセスが出現しないかぎり、ストールは必要としない。このことは、タスク切り替え後にすべてのＩＲＡＭをリロードしなければならないときに殊に有用である：コンフィギュレーションスタートに対する遅延は、複数のＩＲＡＭがさらにロードを必要とするときには常にキャッシュコントローラのプリロードエンジンがブロックしているＩＲＡＭを選択するならば、いっそう短くすることができる。
【００８７】
いっそう長いＦＩＦＯ
メモリ階層底部（メインメモリ）における周波数は、ＣＰＵコアの周波数と同じ程度まで引き上げることができない。ＲＩＳＣコアとＰＡＣＴ ＸＰＰコアとのコンカレンシーを高めるため、上記の図面におけるプリフェッチを拡張することができる。したがって複数のコンフィギュレーションのためのＩＲＡＭ内容を、コンフィギュレーション自体のようにプリロードすることができる。簡単な取り決めによって、どのコンフィギュレーションに属するどのＩＲＡＭをプリロードするのかが明確になる。コンフィギュレーションは次のコンフィギュレーションコンテキストへの切り替えを実行する。これはコンフィギュレーション実行のたびにＦＩＦＯ書き込みポインタを進めることによって達成することができ、その間、各プリロードの終了後それはそのままにしておかれる。割り当てられていないＩＲＡＭ ＦＩＦＯのエントリは先行のコンフィギュレーションからその内容を保持するので、成功したすべてのコンフィギュレーションは、異なるＩＲＡＭがプリロードされなかったのであれば、先行するコンフィギュレーションのＩＲＡＭを使用することになる。ＩＲＡＭにコピーすべきいかなるメモリエリアもキャッシュになければ、メモリはボトルネックとなるのでＦＩＦＯの伸長は役に立たない。したがってキャッシュサイズはＦＩＦＯの長さと合わせて調節すべきである。
【００８８】
ＦＩＦＯの長さを伸ばすことの欠点は、先行のコンフィギュレーションにより書き込まれたＩＲＡＭの内容が他のＩＲＡＭにおける後のコンフィギュレーションによって再利用される見込みが高まることである。キャッシュコヒーレンスのプロトコルによって、状況を明確にすることができる。とはいえ、この状況はもっと簡単に解決することができる。何らかの新たなＩＲＡＭエリアと別のＩＲＡＭバンクにおける現在ダーティなＩＲＡＭ内容とのオーバラップを検出すれば、変更されたＩＲＡＭの書き戻しが完了するまで、新たなＩＲＡＭは単純にはロードされない。したがって新たなコンフィギュレーションの実行は、適正なデータが得られるまで遅延される。
【００８９】
短い（単一のエントリの）ＦＩＦＯのためにはオーバラップはほとんどあり得ない。それというのもコンパイラは通常、プリロードをスキップするため次のコンフィギュレーションの場所で先行のコンフィギュレーションの出力ＩＲＡＭ内容をそのままにしておくからである。コンパイラは、ＩＲＡＭ／ベクトルレジスタのための融合アルゴリズムを使用する。融合アルゴリズムは、レジスタアロケーションにおけるレジスタ融合のために使用されるのと同じである。
【００９０】
リードオンリーＩＲＡＭ
実行するコンフィギュレーションにより使用されるメモリが他のＩＲＡＭのためのプリロードコマンドのソースであるかぎり、ＸＰＰパイプラインのストールが発生する：プリロードをスタートさせることができるのは、コンフィギュレーションが完了したときであり、内容が変更されたならばメモリ内容がキャッシュに書き込まれたときである。パイプラインストールの数を低減するために有利であるのは、付加的なリードオンリーＩＲＡＭを加えることである。ＩＲＡＭがリードオンリーであるならば内容を変更することができず、他のＩＲＡＭへのデータのプリロードを遅延なく進めることができる。このためにはプリロード命令に対する拡張が必要とされる：ＸＰＰプリロードおよびＸＰＰプリロードクリーン命令のフォーマットを組み合わせて単一の命令フォーマットを形成することができ、このフォーマットは２つの付加的なビットをもち、これによってＩＲＡＭが読み出されるのか、および／または書き込まれるのかが表される。デバッグをサポートするため、ＩＲＡＭポートにおいて違反がチェックされ、必要であれば例外が発せられる。
【００９１】
２．５．３  データディストリビューションおよびデータ認識のサポート
ＩＲＡＭはブロック指向の構造であり、これはＰＡＥアレイによってどのような順序でも読み出すことができる。しかしながらアドレス生成によって複雑さが加わり、実際のコンパイルに使用できるＰＡＥの個数が低減されてしまう。したがって一番よいのは、ＩＲＡＭを直線的な順序でアクセスすることである。メモリ階層も同様にブロック指向であって、これによればキャッシュミスを防ぐためコード中の直線的なアクセスパターンが推奨される。
【００９２】
ＩＲＡＭ読み出しポートによって、ＩＲＡＭとＰＡＥとの間の帯域幅がサイクルあたり１ワードの読み出しに制限されるので、このボトルネックを取り除くために有利であるのはデータを複数のＩＲＡＭにわたって配分することである。メモリ階層のトップはデータのソースであり、したがってアクセスパターンが変更されてもデータ局所性が破壊されないかぎり、キャッシュミスの量が増えることはない。
【００９３】
多くのアルゴリズムは、ブロック読み出しおよび単純なアドレス計算を利用するため定義に従い直線的な順序でメモリをアクセスする。他の大部分の事例において、また、ＩＲＡＭとＰＡＥとのデータ帯域幅を広げるためにループタイリングが必要とされる事例において、最適な順序でデータがアクセスされるようコードを変換することができる。残りの多くの事例において、コンパイラはデータレイアウトの再配置（たとえばアレイマージ）によってアクセスパターンを変更することができ、その結果、最終的に望ましいパターンでデータがアクセスされるようになる。依存性ゆえに、またはデータレイアウトが固定されていることから、これらの最適化のうちのいずれも利用できない場合に、パフォーマンス改善の目的でまだ２つの可能性がある：
データデュプリケーション
データが複数のＩＲＡＭにおいてデュプリケートされる。これによってＩＲＡＭ読み出しポートのボトルネックが回避され、複数のデータアイテムをサイクルごとに入力から読み出すことができるようになる。
【００９４】
共通の欠点を伴いながら複数のオプションが可能である。すなわちその欠点とは、データデュプリケーションは入力データにしか適用できないことである。出力ＩＲＡＭは明らかに、オーバラップしたアドレス範囲をもつことができない。
【００９５】
・異なるターゲットＩＲＡＭを指定する複数のＩＲＡＭプリロードコマンドを使用する
このようにすれば、キャッシュミスは最初のプリロードに対してしか発生しない。他のすべてのプリロードはキャッシュミスを伴わずに行われることになり、すべての付加的なロードのためにメモリ階層のトップからＩＲＡＭへデータを転送する時間だけが必要とされる。このことは、キャッシュミスと付加的な転送時間の和がコンフィギュレーションの実行時間を超えないときだけ有利である。
【００９６】
・複数のＩＲＡＭへコンカレントにロードするためのＩＲＡＭプリロード命令を使用する
複数のＩＲＡＭにおいて同一のデータが必要とされるので、それらのＩＲＡＭすべてへ同じ値を書き込むことによってそれらをコンカレントにロードすることができる。その結果、ターゲットＩＲＡＭごとにクリーンなＩＲＡＭインスタンスが探されることになり、それらすべてがバスに接続され、データがバスに書き込まれることになる。この命令に付随する問題点とは、宛先のためにいっそう大きな即値フィールドが必要とされることである（ＸＰＰ６４であれば４ｂｉｔではなく１６ｂｉｔ）。したがって、いっそう大きいＸＰＰ配列のためにＩＲＡＭの個数が増えれば、この命令フォーマットはいっそう高い率で大きくなっていく。
【００９７】
この命令のインタフェースは以下の通りである：
XPPPreloadMultiple (int IRAMS, void *StartAddress, int Size)
この命令は、第１のパラメータに例外をもつXPPPreloadClean命令として振る舞う。第１のパラメータはＩＲＡＭである。これは即値（定数）である。この値はビットマップであり、このビットマップにおける各ビットのために、その数をもつＩＲＡＭがロードオペレーションに対するターゲットとなる。この場合、データデュプリケーションは読み出しデータだけにしか適用できないので、「クリーンな」バージョンは存在しない。
【００９８】
データ並び替え
データ並び替えによって、データ対するアクセスパターンだけが変更される。読み出されるデータ量は変更されない。したがってキャッシュミスの個数は同じままである。
【００９９】
・付加的な機能をハードウェアに加える：
・プリロード命令にベクトルストライドを加える
ベクトルロードオペレーションにおいてたとえば行列の列をベクトルレジスタにロードするため、ストライド（メモリ内の２つの要素間の変位）が使用される。
【０１００】
これは依然として直線的なパターンである。プリロード命令にストライドを与え、そのストライドをＩＲＡＭ識別状態に加えることによって、これをハードウェアとして実装することができる。この命令に付随する１つの問題点は、ＩＲＡＭロードあたりに発生する可能性のあるキャッシュミスの個数が高まることである。最悪のケースでは、ストライドがキャッシュラインサイズと等しくかつすべてのデータキャッシュ内になければ、ロードされた値ごとに１つのキャッシュミスが生じる可能性がある。しかしすでに述べたように、ミスの総数は同じままであり、ディストリビューションが変わるのである。これは相変わらず不所望な作用である。
【０１０１】
他の問題点は、実装が複雑であることおよび場合によってはスループットが制限されることである。それというのも、メモリ階層における各階層間のデータパスがブロック転送のために最適化されているからである。隣り合わないワードを転送するのであれば、幅広いバスが最適なかたちでは利用されないことになる。
【０１０２】
命令のインタフェースは以下のようになる：
XPPPreloadStride (int IRAM, void *StartAddress, int Size, int Stride)
XPPpreloadCleanStride (int IRAM, void *StartAddress, int Size, int Stride)
この命令は、他の命令を付加的にもつXPPPreload / XPPPreloadClean命令として振る舞う。４番目のパラメータがベクトルストライドである。これは即値（定数）である。これは、指定されたＩＲＡＭへｎ番目の値のみをそのつどロードするためキャッシュコントローラに伝達される。
【０１０３】
・ランタイム時のデータ並び替え、テンポラリコピーの導入
・ＲＩＳＣ上
ＲＩＳＣは、簡単なアドレス計算のためにサイクルごとに１ワードの最大レートでデータをコピーすることができ、もっと複雑な計算であればいくらか低いレートでこれが行われる。
【０１０４】
メモリ階層であれば、ソースがメモリ（以前に使用されていたならばキャッシュ）から１回読み出され、テンポラリコピーに書き込まれ、これもキャッシュ内に存在することになる。これによれば、テンポラリのために使用されるメモリ量によってメモリ階層における圧迫が高まる。テンポラリは頻繁に再利用されるスタックメモリ上に割り当てられるので、ダーティなメモリエリアが再定義されてからそれがメモリに書き戻される見込みがよくなる。よって、メモリへの書き戻しオペレーションは無関係である。
【０１０５】
・ＸＰＰコンフィギュレーションの経由
ＰＡＥアレイはサイクルごとに各ＩＲＡＭから１つの値を読み出したりそこへ書き込んだりすることができる。このためＩＲＡＭの半分を入力として用い、ＩＲＡＭの半分を入力として用いるならば、アドレス生成のためにＰＡＥアレイを使用してサイクルごとに８つの値までを（あるいはＩＲＡＭの個数によってはそれ以上）を並び替えることができる。入力と出力はＩＲＡＭ内に存在するので、そのデータを使用するコンフィギュレーションの前に並べ替えが行われるか後に行われるかは問題ではない。
【０１０６】
ＩＲＡＭのチェーン
ＰＡＥによってもさらに展開はできないが利用されないままのＩＲＡＭが依然として存在するならば、データの付加的なブロックをそれらのＩＲＡＭにロードすることができ、付加的なセレクタによって２つのＩＲＡＭをチェーンすることができる。これによっても展開ほどにはスループットは高まらないけれども、展開が不可能であるときはいつでも、長いパイプラインのスタートアップ遅延を隠蔽するのには役立つ。
【０１０７】
２．６  ソフトウェア／ハードウェアインタフェース
デザインパラメータの変更およびハードウェアに対する相応の変更に従い、ハードウェア／ソフトウェアインタフェースが変更された。以下では、最も重要な変更およびその処理について述べる。
【０１０８】
２．６．１  明示的なキャッシュ
ここで提案するキャッシュは通常のキャッシュではなく、パフォーマンス結果を考慮しなければ、そのオペレーションはトランスペアレントであるためプログラマ／コンパイラには不可視のものである。ここで提案するキャッシュは明示的なキャッシュである。その状態はソフトウェアによって維持されるものである。
【０１０９】
キャッシュコンシステンシおよびプリロード／コンフィギュレーション／ライトバックのパイプライン
キャッシュコンシステンシの責任はソフトウェアがもつ。ここで可能であるのは、同じメモリエリアまたはオーバラップしたメモリエリアをキャッシングする複数のＩＲＡＭをもたせることである。ＩＲＡＭのうちの１つだけしか書き込まれていないかぎり、このことは完璧にＯＫである。このＩＲＡＭだけがダーティになり、メモリにライトバックされることになる。ただし１つよりも多くのＩＲＡＭが書き込まれるならば、どのデータがメモリに書き込まれることになるのかが定義されない。これはソフトウェアのバグである（非決定性の動作）。
【０１１０】
コンフィギュレーションの実行はＩＲＡＭのプリロードおよびライトバックとオーバラップするので、プリロード／コンフィギュレーションシーケンスを生成可能であり、これにはデータハザードが含まれる。キャッシュコントローラとＸＰＰアレイは効率的にパイプライン化された別個の機能ユニットとみなすことができるので、それらのデータハザードは通常の命令パイプラインのパイプラインハザードと等価である。通常のパイプラインの場合のように、これを解決するために２つの可能性がある：
・ハードウェアインタロック：
インタロックはキャッシュコントローラによって行われる。ＩＲＡＭｘにおけるダーティなまたは使用中のアイテムが他のＩＲＡＭプリロードのために使用されているメモリエリアとオーバラップしていることをキャッシュコントローラが検出した場合、そのプリロードをストールしなければならず、これによって目下のコンフィギュレーションおよびプリロードの実行を効率的にシリアライズする。
【０１１１】
・ソフトウェアインタロック
キャッシュコントローラによってもインタロックが強いられないのであれば、コードジェネレータは潜在的なインタロックを配慮する明示的な同期命令を挿入しなければならない。プロシージャ間およびモジュール間のエイリアス解析およびデータ依存関係解析によって、そのことが該当するのか否かを判定することができる一方、必要とされる同期命令の影響力を緩和させるのにスケジューリングアルゴリズムが役に立つ。
【０１１２】
いずれのケースでも、キャッシュミスに起因するパイプラインストールのケースでも、さもなければ無駄にされてしまう計算パワーをＳＭＴによって利用することができる。
【０１１３】
明示的なキャッシュのためのコード生成
ソフトウェアインタロックによって発行される明示的な同期命令とは別に、コンパイラによって以下の命令を発行しなければならない。
・コンフィギュレーションプリロード命令、これはそのコンフィギュレーションにより利用されることになるＩＲＡＭプリロード命令に先だって発行される。この命令は、命令スケジューラによってできるかぎり早期にスケジューリングされるべきものである。
・ＩＲＡＭプリロード命令、これも命令スケジューラによってできるかぎり早期にスケジューリングされるべきものである。
・コンフィギュレーション実行命令、これはそのコンフィギュレーションのためのＩＲＡＭプリロード命令に続いて発行される。この命令は、そのプリロード命令の累積レイテンシの推定最小値と推定最大値との間でスケジューリングされるべきものである。
・ＩＲＡＭ同期命令、この命令は、命令スケジューラによってできるかぎり遅くスケジューリングされるべきものである。この命令は、デュプリケートされ場合によってはＩＲＡＭ内で変更されるデータエリアに対して生じる可能性のあるＲＩＳＣの何らかのアクセスよりも前に挿入されなければならない。典型的にはこれらの命令は、ＸＰＰ上の長いチェーンの計算に続くことになり、したがってパフォーマンスをそれほど減少することにはならない。
【０１１４】
他の機能ユニットに対する非同期性
他の機能ユニット（主としてLd/Stユニット）の命令がＩＲＡＭ内の場合によってはダーティなまたは使用中のメモリエリアにアクセスできるならば、コンパイラによってXppSync()を発行しなければならない。このことによって命令ストリームとキャッシュ内容の同期が強制され、データハザードが回避される。徹底的なプロシージャ間（inter-procedurals）およびモジュール間（inter-modular）の配列エイリアス解析によって、これらの同期命令の頻度が許容レベルに制限される。
【０１１５】
２．７  その他の実装
先行のデザインに関して、パイプラインの占有を保持するため複数回デュプリケートされてＩＲＡＭがシリコン中に存在している。これによって、いつでも完全には占有されていないシリコンエリアが多くなり、このことが生じるのは殊に、ＰＡＥアレイが使用されていないときであるが、これに加えて、アレイ内に存在するＩＲＡＭすべてはコンフィギュレーションによっても使用されないときには常に生じる。また、デュプリケーションによって、ＩＲＡＭの長さを拡張するのも難しくなる。なぜならばすでに大きいＩＲＡＭエリアのトータルサイズが比例して大きくなるからである。
【０１１６】
いっそう効率的なシリコン実装のため、ＩＲＡＭを１次キャッシュに組み込むべきであり、これによってこのキャッシュが大きくなる。つまりこのことは、ＰＡＥアレイのすべてのＩＲＡＭポートをまかなうため１次キャッシュを拡張する必要があることを意味する。このようにすればＸＰＰとＲＩＳＣによっって、１次キャッシュがいっそう効率的なやり方で共有されることになる。ＸＰＰが実行されるときはいつも、ＲＩＳＣから必要とされるのと同じ大きさのキャッシュスペースをＸＰＰが手に入れることになる。ＲＩＳが単独で実行されるときは常に、パフォーマンス向上のため多数の付加的なキャッシュスペースをもつことになる。
【０１１７】
ＰＡＥアレイは、サイクルごとに各ＩＲＡＭポートから１ワードを読み出し各ＩＲＡＭポートへ１ワード書き込む能力を有している。プログラマビリティを制約することなく、これをサイクルあたり１つの読み出しアクセスまたは１つの書き込みアクセスに制限することができる：同じサイクルで同じエリアにデータを書き込むべきときには、他のＩＲＡＭポートを使用することができる。これによって使用されるＩＲＡＭポートの個数が増加するが、このことはめったにない環境においてのみ生じる。
【０１１８】
最悪のケースではこれによってＰＡＥサイクルあたり１６個のデータアクセスが残される。１６個のＩＲＡＭポートのための１６個のメモリエリアすべてが同じ連想バンクにマッピングされるという最悪のケースに基づき、キャッシュのための最小アソシアティビティは１６ウェイセットアソシアティビティとなる。これによって、まれではあるが生じる可能性のある最悪のケースの事例のためのキャッシュの置き換えが回避される。
【０１１９】
ＰＡＥアレイサイクルあたり１６個のアクセスをサポートするために２つのファクタが役に立つ：
・ＰＡＥアレイのクロック周波数は一般に、２〜４の係数だけＲＩＳＣのクロック周波数よりも低くすべきである。その理由は、スイッチマトリクスを備えたコンフィギュアラブルルーティングチャネルにあって、これはポイント・ツー・ポイントのアルミニウムまたは銅の固体のトレースと同じように高い周波数をサポートできないからである。
【０１２０】
つまり、場合によってはオーバラップが存在するならば、すべての書き込みの前にすべての読み出しが行われるかぎり、２つから４つのＩＲＡＭポートアクセスを単一のキャッシュポートによってシリアルに処理することができる。このことはオーバラップがあり得るものとし、すべてのアクセスの優先順位を守り、読み出しアクセスに高い優先順位を与えることによって実現することができる。
・低いアソシアティビティキャッシュの２つ、４つまたは８つのバンクとしてキャッシュにアクセスすることにより、２，４または８というファクタが可能となる。
【０１２１】
サイクルを４つに分けるならば、４ウェイアソシアティビティの４つのバンクが最適となる。４つの連続するサイクル中、４ウェイアソシアティビティの各バンクによって４つの異なるアクセスを行わせることができる。４ウェイまで、同じバス（バンク）に接続されている隣り合うＩＲＡＭポートを使用することによりデータのデュプリケーションを処理することができる。それ以上のデータデュプリケーションのためには、XppPreloadMultiple()というキャッシュコントローラ命令を使用してデータを明示的にデュプリケートしなければならない。同じメモリエリアに対する１６個の読み出しアクセスのための最大データデュプリケーションは、４という目下のデータデュプリケーションファクタによってサポートされる：バンクごとに１回のコピー。これによっても、セクション２．５で提案したデザインのための１６という実際のデータデュプリケーションのようにＲＡＭの効率に悪影響は及ぼされない。
【０１２２】
【数５】
2005535055.tif 000006
【０１２３】
キャッシュコントローラはＲＩＳＣと同じ速度で動作している。ＸＰＰはそれよりも低い（たとえば４分の１の）速度で動作している。したがってＰＡＥアレイから１６個の読み出しリクエストが生じるという最悪のケースのためには、キャッシュコントローラの４つのサイクルでＲＩＳＣからの付加的な４つの読み出しリクエストとともに行う必要がある。したがってフルスピードの１つのバスを、４つのＩＲＡＭポート読み出しポートをサービスするために用いることができる。４ウェイアソシアティビティを使用すれば、サイクルあたり４つのアクセスをサービスすることができ、これは４つのアクセスすべてが同じ連想ブロックにマッピングされるアドレスに行くとしても可能である。
ａ）ＲＩＳＣは依然として１６ウェイセットアソシアティビティのキャッシュビューをもっており、４ウェイセットアソシアティビティの４つのバンクすべてに並列にアクセスする。データデュプリケーションゆえに、複数のバンクがヒットを返すことが可能である。このことは優先順位エンコーダによって考慮されなければならず、これによればただ１つのバンクだけにデータバスに対する権限が与えられる。
ｂ）ＩＲＡＭポートアクセスをサービスするバンクからＲＩＳＣがブロックされる。それに従い待ち状態が挿入される。
ｃ）ＲＩＳＣは、２ポートキャッシュの第２のキャッシュアクセスポートをＲＡＭインタフェースと共有し、この場合、アクセスのために各ＲＡＭ転送間のサイクルが用いられる。
ｄ）ＲＩＳＣによって排他的に使用される第５の４ウェイセットアソシアティビティバンクによってキャッシュが拡張される。（他のバンクが目下のＸＰＰコンフィギュレーションによって使用されないのときのみ、他のバンクがアクセスされる。ここで問題はブロックされたバンクのダーティなラインである）。
−＞２ポートＲＡＭ、現在の読み出しＯＫ、ＳＷ同期／ＨＷアービタにより同じキャッシュラインに対し現在のＲ／Ｗが回避される。
【０１２４】
別の問題は、１つの読み出しが場合によっては書き込みと同じメモリロケーションをアドレッシングしてしまう可能性のあることである。値の読み出しはオペレーションの順序に依存するので、その順序は固定である：すべての書き込みはすべての読み出し後に行われなければならないが、読み出しと書き込みが実際にはオーバラップしていなければ、次のサイクルの読み出し前に行われる。データデュプリケーションに伴いこのことが問題となる可能性のあるのは、実際にはデータの１つのコピーのみが変更されたときだけである。したがってデータデュプリケーションによって変更が禁止される。
【０１２５】
２．７．１  プログラミングモデル変更
データインタフェース
専用のＩＲＡＭが設けられていないこのデザインによれば、ＩＲＡＭへの入力データのロードおよび同じアドレスにマッピングされている異なるＩＲＡＭへの出力データの書き込みは不可能であり、したがってコンフィギュレーション全体を通じて変更されていないオリジナルの入力データ上で動作する。
【０１２６】
専用のＩＲＡＭが設けられていなければ、書き込みによってキャッシュ内容がじかに変更され、これは後続の読み出しによって読み出される。これによってプログラミングモデルが著しく変更される。したがって付加的ないっそう綿密なコンパイラ解析が必要とされる。
【０１２７】
２．７．２  実装の詳細の隠蔽
XppPreloadMultiple命令の宛先フィールドにおける実際のビット数は実装に依存する。これはキャッシュバンク数とそれらのアソシアティビティに依存し、これはキャッシュ周波数に対するＸＰＰ ＰＡＥアレイのクロック周波数の除数によって決定される。しかしこのことはアセンブラによって隠避することができ、このアセンブラはＩＲＡＭポートをキャッシュバンクに変換し、これによってビット数がＩＲＡＭポート数からバンク数に低減される。ユーザにとっては、各キャッシュバンクが２の累乗で始まる隣り合うＩＲＡＭポートセットをサービスすることを知っていれば十分である。したがって最もよいのは、デュプリケートされたエリアに対する読み出しポート数よりも大きい２の最大の累乗で始まる隣り合うポートのデータデュプリケーションである。
【０１２８】
３  プログラム最適化
３．１  コード解析
このセクションでは、プログラム上で実行可能な解析について説明する。これらの解析は種々の最適化によって使用される。ここではプログラム中のデータとメモリロケーションと関係について述べる。詳細については複数の文献［２，３，５］を参照されたい。
【０１２９】
３．１．１  データフロー解析
データブロー解析によってプログラム全体にわたるスカラ値の流れが調べられ、その目的は、プログラムがそのデータをどのように操作しているかに関する情報を得ることである。この情報はデータフロー方程式によって表現することができ、この方程式はオブジェクトｉに対する以下のような一般的な形態をもっており、ここでオブジェクトｉは解くべき問題に依存して命令であってもよいし、基本ブロックであってもよい。
Ex[i] = Prod[i]Y (In[i] - Supp[i])
これは、オブジェクトi, Ex[i]の実行終了時に得られるデータはi, Prod[i]によって生成され、あるいはi, In[i]の開始時には生きていたが、i, Supp[i]の実行中は削除されなかったことを意味している。
【０１３０】
この方程式を以下のような複数の問題を解決するために用いることができる。
・到達定義の問題
・Def-Use連鎖（定義点と使用点の連鎖）とUse-Def連鎖（使用点と定義点の連鎖）、これによれば到達可能なすべてのuse（使用点）のdefinition（定義点）と到達可能なすべてのdefinition（定義点）のuse（使用点）がそれぞれ表される。
・プログラムのあるポイントにおいて利用可能な式
・プログラムのあるポイントにおいて生きている変数
これらの解決は複数のコンパイルフェーズ、解析あるいは最適化により使用される。
【０１３１】
ここでは一例として、あるプログラムの変数におけるDef-Use連鎖を計算する問題を挙げる。この情報は、たとえばスカラ変数に対するデータ依存関係解析に際して使用できるし、あるいはレジスタアロケーションに際して使用できる。Def-Use連鎖は１つの変数の各定義に割り当てられ、これはその定義からのすべての可視のuse（使用）の集合である。先に挙げたデータフロー方程式は基本ブロックに適用され、これによって１つのブロックから別のブロックへ制御フローグラフに沿って通過する変数が検出される。以下の図面において、変数ｘのための２つの定義が生成されている：Ｂ１中のＳ１およびＢ３中のＳ４。したがってＢ１の出口でみつけることのできる変数はEx(B1)={x(S1)}であり、Ｂ４の出口でみつけることのできる変数はEx(B4)={x(S4}である。さらにEx(B2)=Ex(B1)となる。なぜならばＢ２では変数が定義されていないからである。これらの集合を利用してわかるのは、Ｓ２およびＳ３におけるｘの使用はＢ１におけるxの定義に依存すること、Ｓ５におけるｘの使用はＢ１とＢ３におけるｘの定義に依存することである。この場合、定義に対応づけられたDef-Use連鎖はD(S1) = {S2, S3, S5} かつD(S4) = {S5}となる。
【０１３２】
【数６】
2005535055.tif 000007
【０１３３】
３．１．２  データ依存関係解析
データ依存関係グラフによって表されるのは、同じデータを書き込むオペレーションと読み出すオペレーションとの間に存在する依存関係である。このグラフはそれらのセマンティクス妥当性をテストするため、スケジューリングのような最適化や所定のループ最適化のために使用される。グラフの各ノードは命令を表し、辺はデータ依存関係を表す。これらのデータ依存関係を３つのタイプとすることができる：変数が読み出される前に書き込まれるならば真（またはフロー）依存関係、変数が書き込まれる前に読み出されるならば反依存関係、変数が２回書き込まれるならば出力依存関係である。この場合、もっと形式的な定義である［３］。
【０１３４】
定義
ＳとＳ′を２つのステートメントとし、Ｓ′はＳに依存し、ＳδＳ′iffで表す：
（１）ＳはＳ′の前に実行される。
（２）∃ν∈VAR:ν∈DEF(S)I USE(S') vν∈USE(S)I DEF(S') vν∈DEF(S)I DEF(S')
（３）この場合、ＳがＴよりも前に実行されＴがＳ′よりも前に実行されるようなステートメントＴは存在せず、ν∈DEF(T)である。
ここでVARはプログラムの変数の集合であり、DEF(S)は命令Ｓにより定義される変数の集合であり、USE(S)は命令Ｓにより使用される変数の集合である。
【０１３５】
さらにステートメントがループ中にあれば、依存関係をループインディペンデントであるかまたはループキャリーの依存とすることができる。この概念によって、依存関係の距離の定義が導入される。依存関係がループインディペンデントであれば、このことは同じイタレーションにおいて異なるステートメントの２つのインスタンス間に依存関係が発生し、距離は０であることを意味する。これとは対照的に、２つの異なるイタレーションにおける２つのインスタンス間に依存関係が発生すれば、ループキャリー依存であり、距離はそれら２つのインスタンスのイタレーション数の差に等しい。
【０１３６】
依存関係の方向という概念によって距離の概念が一般化され、これは依存関係の距離が一定ではないときまたは精確には計算できないときにこれが一般に使用される。依存関係の方向は、ＳのインスタンスがＳ′のインスタンスのイタレーションの前のイタレーションにあるときにＳとＳ′との間の依存関係があれば＜で表され、２つのインスタンスが藻な侍医らレーションにあれば＝で表され、ＳのインスタンスがＳ′のインスタンスのイタレーションの後のイタレーションであれば＞で表される。
【０１３７】
ループネストのケースでは、ループネストの各レベルについて１つの要素とともに距離と方向ベクトルが用いられる。以下の図面にはこれらすべての定義が描かれている。データ依存関係のグラフは多数の最適化によって使用され、それらの適用が妥当であるか否かを判定するのにも有用である。たとえばループは、そのデータ依存関係グラフがいかなるサイクルも含んでいなければベクトル化することができる。
【０１３８】
【数７】
2005535055.tif 000008
【０１３９】
【数８】
2005535055.tif 000009
【０１４０】
３．１．３  プロシージャ間のエイリアス解析
エイリアス解析の目的は、プログラム中、変数や配列のような複数のオブジェクトが同じメモリロケーションを複数の名前で参照している（エイリアス）か否かを判定することである。エイリアスはデータ依存関係解析およびコード最適化の適用に強力なインパクトをもっている。エイリアスは、すべてのフィールドが同じメモリエリアを参照しているＣ言語のunionのようにスタティックに割り当てられたデータによって発生する可能性があるし、あるいは解析の一般的なターゲットであるダイナミックに割り当てられたデータによって発生する可能性がある。ｐがｂの別名であるようなエイリアスの典型的なケースを図１３に示す。
【０１４１】
【数９】
2005535055.tif 000010
【０１４２】
エイリアス解析は、制御フローを考慮するかしないかに依存していっそう正確にもなるしあまり正確でもなくなる。考慮するならばそれはフローセンシティブと呼ばれ、考慮しふなければそれはフローインセンシティブと呼ばれる。フローセンシティブなエイリアス解析によれば、どのブロック内でパスに沿って２つのオブジェクトがエイリアスとなっているかを検出できる。これはいっそう精密であるため、いっそう複雑であり、計算がいっそう煩雑である。通常はフローインセンシティブな情報で十分である。この観点が図１４に示されており、この場合、フローインセンシティブな解析によってｐがｂのエイリアスであることはわかるけれども、フォローセンシティブな解析であれば、ブロックＢ２でのみｐがｂのエイリアスであることがわかる。
【０１４３】
さらにエイリアスはmustエイリアスとmayエイリアスに分類される。たとえばフローセインセンシティブにmayエイリアス情報を考慮する場合、ｘとｙが場合によっては異なる回数で同じメモリロケーションを参照してもよいならば、かつそのときにかぎり、ｘはｙのエイリアスである。また、フローインセンシティブにmustエイリアス情報を考慮する場合、ｘとｙが１つのプロシージャの実行を通して同じストレージロケーションを参照しなければならないならば、かつそのときにかぎり、ｘはｙのエイリアスである。図１４の事例において、フローインセンシティブにmayエイリアス情報を考慮するならば、ｐはｂのエイリアスというままであるが、フローインセンシティブにmustエイリアス情報を考慮するならば、ｐがｂのエイリアスであるというのは維持されない。使用のためのこの種の情報は解決する問題に依存する。たとえば冗長な式またはステートメントを取り除きたいのであれば、mustエイリアスを使用しなければならないけれども、データ依存関係グラフを形成したいのであれば、mayエイリアスが必要となる。
【０１４４】
【数１０】
2005535055.tif 000011
【０１４５】
最終的に、このエイリアスは非ローカルな変数およびパラメータの受け渡しにより引き起こされるエイリアスを検出できるよう、インタープロシージャ（interprocedural）でなければならない。後者の事例は図１５に示されており、ここでｉとｊはこの関数呼び出し全体にわたりエイリアスとなっており、ｋはパラメータとして２回、渡される。
【０１４６】
【数１１】
2005535055.tif 000012
【０１４７】
３．１．４  プロシージャ間の値のレンジの解析
この解析によって、変数がとる値のレンジをみつけることができる。この解析を、デッドコード削除、ループ展開等のような最適化を適用するのに役立たせることができる。したがってたとえば、条件命令におけるテストが満たされそうであるのか否かを判定することができるし、あるいはループネストのイタレーションレンジを判定することができる。
【０１４８】
この解析はインタープロシージャでなければならず、なぜならば以下のサンプルのようにたとえばループバンドがパラメータとして渡される可能性があるからである。この場合、コードの解析によってわかるのは、配列ａにより実行されるループ内でＮは少なくとも１１と等しいこと、配列ｂにより実行されるループ内ではＮは最大でも１０と等しいことである。
【０１４９】
【数１２】
2005535055.tif 000013
【０１５０】
値のレンジの解析は、言語のセマンティクスからは引き出せない別の値の制約を与えることでプログラマによってサポートすることができる。これはプログラムまたはコンパイラに既知のassert機能によって行える。
【０１５１】
３．１．５  アライメント解析
アライメント解析により、分散型メモリアーキテクチャに関するデータレイアウトが扱われる。Saman Amarasingheは以下のように述べている：「データメモリは論理的には直線的なセルのアレイであるにしても、ハードウェアによるその実現を多次元配列とみなすことができる。この配列において１つの次元を定めればアライメント解析によって、その次元における単一の値を常に解決するメモリロケーションが同定されることになる。たとえば、対象とする次元がメモリバンクであればアライメント解析によって、メモリ参照が常に同じバンクをアクセスするか否かが同定されることになる」。このことは以下の図面の第２の部分に該当し、これは［１０］に示されており、そこでは青で描かれたすべてのアクセスは同じメモリバンクに対して発生しているのに対し、第１の部分ではアクセスは並んだ状態にはない。さらに彼は以下のことを付け加えている：「アライメント情報は、コンパイラによりコントロールされたメモリ最適化の様々なバラエティにおいて有用であり、これによってプログラマビリティ、パフォーマンス、エネルギー消費が改善されることになる」。
【０１５２】
【数１３】
2005535055.tif 000014
【０１５３】
アライメント解析はたとえば、データの良好な配分パターンを見つけるのに役立たせることができ、さらには自動データディストリビューションツールにも有用である。自動アライメント解析ツールは、プロシージャ内でアクセスされる配列に対するアライメントの提案を自動的に生成することができ、したがってこれによりデータディストリビューションの問題が簡単になる。さらにこれを、ダイナミックな再アライメントを考慮するプロシージャ間解析によって拡張することができる。
【０１５４】
アライメント解析を、あとで示すようにデータレイアウト自体ではなくコードを直接変換するループアライメントに適用することもできる。さらに別の解決策をＰＡＣＴ ＸＰＰのために使用することができ、これはアライメントされたコードを著しく効率的に処理することができるということに基づいている。これは以下の条件命令を加えることから成る。すなわちこの命令により、ループボディ内のアクセスにそのループボディにおける所要数のピーリングされたイタレーションが続くようアライメントされているかがテストされ、その場合、アライメントされたループボディおよびいくつかの補償コードである。この場合、ＰＡＣＴ ＸＰＰによって実行されるのはアライメントコードだけであり、残りはホストプロセッサによって実行される。アライメント解析がいっそう精密になれば（プロシージャ間またはモジュール間で行われれば、条件コードをいっそう少ししか挿まなくてよくなる。
【０１５５】
３．２  コード最適化
ここで説明する最適化および変換の大部分は文献［４］に詳しく示されており、さらに［２，３，４］にも示されている。
【０１５６】
３．２．１  一般的な変換
このセクションでは、ストレートフォワードコードおよびループボディに適用可能ないくつかの一般的な最適化について示す。これらはコンパイラにおいて現れるだけでなく、このドキュメントの続きにおいても言及される。
【０１５７】
定数伝播
この最適化によれば、プログラム全体にわたりこれを用いることで定数値が式に伝播される。このようにして多数の計算をコンパイラによってスタティックに行うことができ、これによれば実行中に行うべき作業が少なくなる。最適化のこの部分は定数畳み込みとしても知られている。
【０１５８】
【数１４】
2005535055.tif 000015
【０１５９】
コピー伝播
この最適化によれば、コード中の同じ変数の冗長なコピーが除去されることでコードが単純化される。それらのコピーはプログラマ自体によって生成されたものであるかもしれないし、あるいは他の最適化によって生成される可能性がある。この最適化によってレジスタの圧迫およびレジスタからレジスタへの移動命令の個数が低減される。
【０１６０】
【数１５】
2005535055.tif 000016
【０１６１】
デッドコード削除
この最適化によって、決して実行されることのないコード部分が削除される。条件が常に真または偽である条件をもつ条件ステートメントの分岐にあるならば、あるいはイタレーション回数が常にゼロであるループボディであるならば、そのコードは決して実行されない。
【０１６２】
決して使われない変数を更新するコードも使用されることはなく、同様に削除可能である。ある変数が決して使われないならば、それを更新するコードおよびその宣言も削除できる。
【０１６３】
【数１６】
2005535055.tif 000017
【０１６４】
前方置換
この最適化はコピー伝播の汎化である。変数の使用が定義式と置き換えられる。これはデータ依存関係解析ならびにループ変数の使用を可視的にすることによる他の変換の適用を簡単にするために用いることができる。
【０１６５】
【数１７】
2005535055.tif 000018
【０１６６】
イディオム認識
この変換によってコードの一部分が認識され、それらをコンパイラに既知の関数の呼び出し、あるいは絶対値計算のためのコードのように煩雑さの少ないコードシーケンスと置き換えることができる。
【０１６７】
【数１８】
2005535055.tif 000019
【０１６８】
３．２．２  ループ変換
ループの正規化
この変換によって保証されるのは、ループのイタレーション空間が常に（入力言語に依存して）０または１と等しい低いバンドおよび１のステップ伴うことである。これはオポチュニティを見つけるため、および内側ループ依存関係解析を容易にするため、ループ融合前に使用することができ、正規化されたループに適用する必要のある依存関係テストを使用できるようにもなる。
【０１６９】
【数１９】
2005535055.tif 000020
【０１７０】
ループ逆転
この変換によって、あるループのイタレーション空間のスキャンされる方向が変更される。これは通常、ループ最適化およびループインタチェンジなど他の変換とともに用いられる。なぜならばこれによって依存関係ベクトルが変化するからである。
【０１７１】
【数２０】
2005535055.tif 000021
【０１７２】
ストレングスリダクション
この変換によって、ループ内の式が等価であるが煩雑さの少ない式と置き換えられる。これはループ変数とは別の誘導変数において、それらを削除できるよう使用することができる。
【０１７３】
【数２１】
2005535055.tif 000022
【０１７４】
誘導変数削除
この変換によって、ループから誘導変数を取り除くためにストレングスリダクションを使用することができ、したがってこれにより計算数が低減され、ループ解析が簡単になる。これにより、変数の更新に起因する依存サイクルも除去され、ベクトル化が可能となる。
【０１７５】
【数２２】
2005535055.tif 000023
【０１７６】
ループインバリアントコードモーション
この変換によって、計算結果がすべてのイタレーションにおいて同じであればそれらの計算がループの外側に動かされる。これによって、ループボディ内の計算数を低減できる。完全にネストされたループを得る目的でこの最適化を逆のやり方で導入することができ、そのようなループは別の最適化によって処理するのが簡単になる。
【０１７７】
【数２３】
2005535055.tif 000024
【０１７８】
ループアンスイッチング
この変換により、条件命令における条件がループインバリアントであればその命令がループの外側に動かされる。その場合、条件分岐は、条件ステートメントにおける適切なオリジナルのステートメントをもつオリジナルのループによって構成されることになる。さらにこれによれば、ループボディにおける制御フローを除去し、かつそこから不必要な計算も除去することによって、ループの並列化が可能となる。
【０１７９】
【数２４】
2005535055.tif 000025
【０１８０】
ifコンバージョン
この変換は、条件命令をもつループボディに適用される。これにより制御依存性がデータ依存性に変えられ、その場合、ベクトル化を行えるようになる。これは複数の基本ブロックをもつループボディを処理するため、ループアンスイッチングとともに使用することができる。配列式の現れる可能性のある条件が、ガードと呼ばれる論理項と置き換えられる。予測実行がサポートされるプロセッサはこの種のコードをダイレクトに実行することができる。
【０１８１】
【数２５】
2005535055.tif 000026
【０１８２】
ストリップマイニング
この変換によってオペレーションの粒度を調整することができる。これは一般に、内側ループネストにおける独立した計算の個数を選択するために用いられる。イタレーションカウントがコンパイル時点に既知でなければ、リソース制約を満たす固定のイタレーションカウント内側ループを生成するために用いることができる。これはループ配分またはループインタチェンジのような他の変換とともに使用することができる。これはループセクショニングとも呼ばれ、ストリッピングとも呼ばれるサイクルシュリンキングはストリップマイニングの特殊形である。
【０１８３】
【数２６】
2005535055.tif 000027
ループタイリング
この変換により、イタレーション空間をタイルに分割するためにループレベルを導入することでループネストのイタレーション空間が変更される。これはストリップマイニングの多次元の汎化である。これは一般にメモリ再利用の向上に使用されるけれども、プロセッサ、レジスタ、ＴＬＢまたはページ局所性を向上させることもできる。これはループブロッキングとも呼ばれる。
【０１８４】
イタレーション空間のタイルのサイズは、各タイル内で必要とされるデータがキャッシュメモリ内でフィットするよう選択され、これによってキャッシュミスが低減される。粗粒度のコンピュータの場合にはタイルのサイズを、ループボディの並列オペレーションの個数がコンピュータにおけるプロセッサの個数とフィットするよう選定できる。
【０１８５】
【数２７】
2005535055.tif 000028
【０１８６】
ループインタチェンジ
この変換は、（探索される効果に依存して）データ制約を含むループレベルの内側または外側に動かすためにループネストに適用される。これによれば、
依存関係のないループの内側または依存関係のあるループの外側に動かすことでベクトル化が可能になり、または、
最も広い範囲をもつ依存関係のないループの内側に動かすことでベクトル化を改善することができ、または、
内側ループ内のループインバリアントな式の個数を増加させることができ、または、
依存関係のないループをループネストの外側に動かすことで並列パフォーマンスを向上させることができ、これによって各イタレーションの粒度が増加し、かつ妨害を成す同期合わせの個数が低減される。
【０１８７】
【数２８】
2005535055.tif 000029
【０１８８】
ループ一重化／折り畳み
この変換によって、１つのループネストが結合されて単一のループが形成される。これによりループのスケジューリングが改善され、かつループのオーバヘッドも低減される。折り畳みは一重化のいっそう簡単な形態であり、この場合、配列の次元数も同様に低減される。折り畳みによって、ネストされたループおよび多次元配列のオーバヘッドが低減される。メモリ全体にわたり一定のストライドで反復するループネストに折り畳みを適用することができ、他の場合にはループ一重化がいっそう良好なアプローチである。最も奥のループのイタレーションレンジを増やすことで、ベクトル化を有利にするためにこれを用いることができる。
【０１８９】
【数２９】
2005535055.tif 000030
【０１９０】
ループ融合
ループジャミングとも呼ばれるこの変換によって、２つの連続するループがマージされる。これによりループオーバヘッドが低減され、命令レベル並列性が増加し、レジスタ、キャッシュ、ＴＬＢまたはページの局所性が改善され、さらに並列ループのロードバランスが向上する。その際、依存関係を管理するため条件命令を導入することによりアライメントを考慮することができる。
【０１９１】
【数３０】
2005535055.tif 000031
【０１９２】
ループディストリビューション
ループ融合とも呼ばれるこの変換により、ループボディが大きすぎる場合または依存関係の理由で１つのループを複数の部分に分割することができる。新たな複数のループのイタレーション空間は元のループのイタレーション空間と同じである。ループスプレッディングはいっそう洗練されたディストリビューションである。
【０１９３】
【数３１】
2005535055.tif 000032
【０１９４】
ループ展開／展開およびジャム
この変換によれば、いっそう大きいループボディを得るために元のループボディがレプリケートされる。１つのループを部分的にまたは全体的に展開することができる。ループを大きくすることで並列性のためにいっそう多くのオポチュニティを得るために用いられ、これによってレジスタまたはキャッシュの使用も改善され、さらにループオーバヘッドも低減される。外側のループを展開するループおよびそれに続いて誘導された内側のループをマージすることは、展開およびジャムとも呼ばれる。
【０１９５】
【数３２】
2005535055.tif 000033
【０１９６】
ループアライメント
この最適化によって、ループボディ内にアライメントされた配列アクセスが得られるようコードが変換される。これによればループキャリー依存性がループインディペンデント依存性に変換され、これにより１つのループからいっそう大きい並列性を抽出できるようになる。これは目標を達成するためループピーリングのような種々の変換を用いることができるし、あるいは条件ステートメントを導入することができる。この変換をループ融合といっしょに使用することができ、それによれば２つのループネスト内の配列アクセスがアライメントされることでこの最適化が可能となる。以下の例では、配列ａに対するすべてのアクセスがアライメントされた状態になる。
【０１９７】
【数３３】
2005535055.tif 000034
【０１９８】
ループスキューイング
この変換は、ループネストの並列化を可能にするために用いられる。これはループインタチェンジとの組み合わせで有用である。これはスキューファクタ,f,で乗算された外側ループインデックスを内側ループ変数の境界に加え、ついで同じ量をループ内部の内側ループ変数のそのつどの使用から減算することによって実行される。
【０１９９】
【数３４】
2005535055.tif 000035
【０２００】
ループピーリング
この変換によれば、ループボディ内の依存性を避けるため１つのループにおける少数の開始イタレーションまたは終了イタレーションが除去される。除去されたそれらのイタレーションは別個に実行される。ループ融合をできるよう、隣接ループのイタレーション制御を整合させるためにこれを使用することができる。
【０２０１】
【数３５】
2005535055.tif 000036
【０２０２】
ループ分割
この変換によれば、別のループネストの生成によりイタレーション空間が複数の部分に分割される。これはインデックスセット分割とも呼ばれ、並列化を妨げる依存関係ゆえに一般使用される。新たなループのイタレーション空間は元のもののサブセットである。これをループピーリングの生成とみなすことができる。
【０２０３】
【数３６】
2005535055.tif 000037
【０２０４】
ノード分割
この変換により１つのステートメントが複数の部分に分割される。これはノードの過度に高い粒度ゆえに依存関係グラフにおける依存関係サイクルをブレークさせて、ステートメントのベクトル化を可能にするために用いられる。
【０２０５】
【数３７】
2005535055.tif 000038
【０２０６】
スカラエクスパンション
この変換によれば１つのループ内のスカラが配列と置き換えられ、これによってループボディにおける依存性が除去され、ループネストの並列化が可能となる。そのスカラがループの後に使用されるのであれば、補償コードを加える必要がある。
【０２０７】
【数３８】
2005535055.tif 000039
【０２０８】
配列コントラクション／配列シュリンキング
この変換はスカラエクスパンションの逆変換である。これが必要とされるのは、スカラエクスパンションによって過剰に大きいメモリ要求が生じるときである。
【０２０９】
【数３９】
2005535055.tif 000040
【０２１０】
スカラ置換
この変換により、１つのループ内におけるインバリアントな配列参照がスカラと置き換えられる。この配列の要素は内側ループの前にスカラにロードされ、それが変更されたならば、内側ループの後に再びストアされる。これはループインタチェンジといっしょに使用することができる。
【０２１１】
【数４０】
2005535055.tif 000041
【０２１２】
リダクション認識
この変換によって、ループ内のリダクションを処理できるようになる。リダクションは、スカラ値を配列から計算する演算である。これをたとえばベクトルのドット積、合計または最小値とすることができる。この場合目的は、できるかぎり多くのオペレーションを並列に実行できるようにすることである。１つのやり方は、部分結果のベクトルレジスタを累算し、その後、それをリダクションしてシーケンシャルなループをもつスカラを形成することである。ここで最大の並列化は、ツリーによってベクトルレジスタのリダクションを行うことによって達成される。その際、素子のペアが合計され、ついでそれらの結果のぺが合計される、という具合にして行われる。
【０２１３】
【数４１】
2005535055.tif 000042
【０２１４】
ループプッシュ／ループエンベッド
この変換により、１つのループ内の呼び出しが呼び出された関数内のループと置き換えられる。これはプロシージャ間最適化である。これによってループネストの並列化が可能となり、プロシージャ呼び出しに起因するオーバヘッドが除去される。ループプッシュとともにループディストリビューションを使用することができる。
【０２１５】
【数４２】
2005535055.tif 000043
【０２１６】
プロシージャインライン化
この変換により、あるプロシージャに対する呼び出しがそのプロシージャ自体のコードと置き換えられる。これはプロシージャ間最適化である。これによりループネストを並列化し、プロシージャ呼び出しに起因するオーバヘッドを除去できるようになり、局所性を改善することができる。
【０２１７】
【数４３】
2005535055.tif 000044
【０２１８】
ステートメント並べ替え
この変換によれば、データ依存関係グラフを変更してベクトル化を可能にするため、ループボディの命令がスケジューリングされる。
【０２１９】
【数４４】
2005535055.tif 000045
【０２２０】
ソフトウェアパイプライン化
この変換によれば、ループボディの種々のインスタンスの命令をスケジューリングすることでループボディが並列化される。これは命令レベル並列性を向上させるための効果的な最適化である。これはループ展開といっしょに使用できる。以下の例の場合、各々が１サイクルしかとらないプリロードされた命令を相前後して発行することができる。この時間はメモリエリアをリクエストするのに間に合うにすぎない。それらを実際にロードするのには不十分である。そのためには、データを実際にもっているキャッシュレベルに依存して多くのサイクルがかかる。コンフィギュレーションの実行も同様に動作する。コンフィギュレーションは単一のサイクル内で発行され、すべてのデータが存在するまで待機する。その後、多くのサイクルにわたりコンフィギュレーションが実行される。ソフトウェアパイプライン化によって、１つのコンフィギュレーションの実行が次のコンフィギュレーションのためのプリロードとオーバラップされる。このようにしてＸＰＰアレイを、ロード／ストアユニットに対し並列にビジー状態に保持することができる。
【０２２１】
【数４５】
2005535055.tif 000046
【０２２２】
ベクトルステートメント生成
この変換により命令が、複数のデータを並列に実行可能なベクトル命令と置き換えられる。
【０２２３】
【数４６】
2005535055.tif 000047
【０２２４】
３．２．３  データレイアウト最適化
次に、いっそうの多くの並列性を抽出する目的で、またはキャッシュミスのようなメモリの問題を回避する目的で、データレイアウトを変更する最適化について説明する。
【０２２５】
スカラのプライベート化
この最適化は、並列性の量を増加させ処理要素間の不必要な通信を回避するために用いられる。スカラが１つのループボディにおいて一時的な変数のようにしか使用されないのであれば、各処理要素はそのコピーを受け取ることができ、このプライベートなコピーとの通信を達成することができる。
【０２２６】
【数４７】
2005535055.tif 000048
【０２２７】
配列のプライベート化
この最適化は、スカラに対してではなく配列に対して動作する点を除いてスカラのプライベート化と同じである。
【０２２８】
配列のマージ
この最適化によれば、複数の配列のデータをマージすることで配列のデータレイアウトが変換され、それらの配列が１つのループネスト内でアクセスされるようになる。このようにすればキャッシュミスを避けることができる。配列のレイアウトをループネストごとに異ならせることができる。以下はクロスフィルタの例であって、この場合、配列ａへのアクセスが配列ｂへのアクセスとインタリーブされている。その次の図は両方の配列のデータレイアウトを表しており、この場合、ａ（緑色）のブロックがｂ（黄色）のブロックとマージされている。使用されていないメモリスペースは白で表されている。したがって配列ａと配列ｂを含むデータブロックは、メモリからデータを取得するときにキャッシュにロードされるので、キャッシュミスは回避される。これについての詳細は文献［１］に示されている。
【０２２９】
【数４８】
2005535055.tif 000049
【０２３０】
３．２．４  最適化の適用例
これまで述べてきたように、ベクトルステートメントを生成する前および生成した後にも数多くの最適化を実行することができる。１つのプログラムのすべてのループネストについて最適な解決策を生じさせることになる一連の最適化を見つけ出すことは、やはりリサーチの分野である。それゆえここでは、ベクトル化可能なループネストを生じさせるための妥当なヒューリスティックを得られるようにするこれらの最適化の使用法についてのみ提案することができる。コードをベクトル化するため、Allen-Kennedyアルゴリズムを利用することができ、このアルゴリズムによれば、ベクトルステートメントが生成される前にステートメントの並べ替えおよびループディストリビューションが用いられる。これをループインタチェンジ、スカラエクスパンション、インデックスセット分割、ノード分割、ループピーリングによって補強することができる。これらすべての変換は、データ依存関係グラフに基づく。あるステートメントは、それが依存関係サイクルの一部分でなければベクトル化可能である。したがってサイクルをブレークするために最適化が実行され、あるいは完全に可能でなければ、依存関係サイクルをもたないループネストを生成するために最適化が実行される。
【０２３１】
ここでは、プロセス全体を４つの主要なステップに分割することができる。最初に、ループボディ内部のプロシージャ呼び出しを解析することでプロシージャを再構成し、それらを除去するよう試みることになる。ついでいくつかのハイレベルのデータフロー最適化がループボディに適用され、それらの制御フローが変更され、それらのコードが単純化される。第３のステップは、完全なループネストを形成し、内側ループレベルを確実にベクトル化可能にすることで、ベクトル化のためのループネストを準備することにある。アーキテクチャをターゲットとする最適化を実行することができ、これによってデータ局所性が最適化される。さらに述べておきたいのは、他の最適化およびコード変換をこれらの異なるステップの間に実行することができ、これはループネストをさらに最適化するのにも役立つ。
【０２３２】
したがって第１のステップによってプロシージャインライン化とループプッシュが適用され、これによりループボディのプロシージャ呼び出しが除去される。次に第２のステップが用いられ、このステップはループインバリアントコードモーション、ループアンスイッチング、ストレングスリダクションならびにイディオム認識から成る。第３のステップを複数の最適化サブセットに分けることができる。はじめにループリバーサル、ループ正規化、ならびに正規化されたループネストを取得するためのifコンバージョンが適用される。これによって、データ依存関係グラフを形成できるようになる。ついで依存関係によってループネストのベクトル化が妨げられるのであれば、変換を適用することができる。たとえば依存関係がいくつかのイタレーションにしか発生しないのであれば、ループピーリングまたはループ分割を適用することができる。ノード分割、ループシュリンキング、スカラエクスパンション、またはステートメント並べ替えを他のケースにおいて適用することができる。この場合、ループインタチェンジが依存関係サイクルのないループレベルの内側に移動する。ゴールは、できるかぎり外側で依存関係サイクルを担うループレベルの完全にネストされたループをもつようにすることである。ついでループ融合、リダクショ認識、スカラ置換／配列コントラクションおよびループディストリビューションを適用して、後続のベクトル化をさらに改善することができる。ベクトルステートメント生成を、たとえば少なくともAllen-Kennedyアルゴリズムを使用して実行することができる。最後のステップを、ループタイリング、ストリップマイニング、ループ展開のような最適化、ならびにターゲットプロセッサを考慮したソフトウェアパイプライン化とすることができる。
【０２３３】
第３のステップにおける最適化の個数は多いが、それらのすべてが各ループネストに適用されるわけではない。ベクトル化とデータ依存関係グラフという目標に従い、それらのうちのいくつかが適用される。最適化の適用をガイドするためにヒューリスティックを使用することができ、必要であればそれらの最適化を複数回適用することができる。以下ではこれについて例を挙げて説明する。
【０２３４】
【数４９】
2005535055.tif 000050
【０２３５】
最初のステップにおいて、２つのプロシージャ呼び出しのインライン化が可能であることが見つけられることになり、その場合、ループボディの条件命令を取り除くためにループアンスイッチングが適用される。第２のステップはループ正規化によって始まり、データ依存関係グラフが解析される。１つのサイクルを、それが第２のレベルによってのみ実行されることから、ループインタチェンジの適用によってブレークすることができる。２つのレベルが交換されるので、内側レベルがベクトル化可能である。この前にまたはその後に、ループディストリビューションが適用される。ループ融合を適用できるのは、ｉにおけるループが慣用的な冗長コード除去最適化によって条件命令から引き出されるときである。最後に、結果として得られたループに対しベクトルコードを生成することができる。
【０２３６】
詳しくはプロシージャインライン化後、以下の通りとなる。
【０２３７】
【数５０】
2005535055.tif 000051
【０２３８】
【数５１】
2005535055.tif 000052
【０２３９】
４  ＰＡＣＴ ＸＰＰ用コンパイラの仕様
４．１  イントロダクション
キャッシュドＲＩＳＣ−ＸＰＰアーキテクチャ（cached RISC-XPP architecture）によってコードに対しその完全なポテンシャルが活用され、これは高いデータ局所性ならびに高い計算力を特徴としている。このアーキテクチャのためのコンパイラが考慮しなければならないのは、このようなデザインの制約である。コンパイラの第１の目的は、計算上コストのかかる演算を最も内側のループに集中し、それらに対しできるかぎり多くのデータ局所性を形成することである。
【０２４０】
コンパイラには通常の解析と最適化が含まれている。エイリアス解析のようなプロシージャ間解析は殊に有用であるので、すべての最適化に対しグローバルな情報を確実に伝播できるようにするためにグローバルな最適化ドライバが必要である。以下のセクションでは、ＰＡＣＴ ＸＰＰがコンパイラに及ぼすやり方について集中して説明する。
【０２４１】
４．２  コンパイラの構造
図５１には、ＲＩＳＣプロセッサとＰＡＣＴ ＸＰＰとを含むシステム用のコードを生成するためにコンパイラが実行していく必要のあるメインステップが示されている。次のセクションではＸＰＰコンパイラ自体に焦点を合わせるけれども、はじめに他のステップについて簡単に述べておく。
【０２４２】
【数５２】
2005535055.tif 000053
【０２４３】
４．２．１  コード準備処理
このステップは入力としてプログラム全体を受け取り、通常のコンパイラフロントエンドとみなすことができる。その際、ＰＡＣＴ ＸＰＰにより実行されるべきできるかぎり多くのループネストをコンパイラが抽出できるようにするために、コード解析と最適化を適用することでコードが準備処理されることになる。重要な最適化はイディオム認識、コピー伝播、デッドコード削除、およびデータフロー解析やエイリアス解析など他のすべての通常の解析である。
【０２４４】
４．２．２  パーティショニング
パーティショニングによって、ホストプロセッサによりプログラムのどの部分が実行されるのか、ＰＡＣＴ ＸＰＰによってどの部分が実行されるのかが決定される。
【０２４５】
以下の３つのケースにおいてホストにより１つのループネストが実行される：
・ループネストが十分に整形されていない場合
・実行すべきオペレーションの個数がＰＡＣＴ ＸＰＰにおいて実行される価値がない場合
・ＰＡＣＴ ＸＰＰにおけるループネストのマッピングを得ることができない場合
ループネストが十分に整形されていると呼ばれるのは、ループ境界およびすべてのループステップが一定であり、ループ誘導変数が既知であり、かつループネストに対しただ１つの入口とただ１つの出口しか存在しないときである。
【０２４６】
別の問題点は、ループ境界が一定であるがコンパイル時点では既知でないループネストとともに生じる。ループタイリングによってこの問題を克服することができ、これについては以下で詳しく説明する。それにもかかわらず、ループ境界が小さすぎると、ＰＡＣＴ ＸＰＰにおいてループネストを実行する価値がなくなる可能性がある。ループが十分に長いか否かをテストする条件命令を導入することができ、ループネストの２つのバージョンが生成される。ループ境界が適切であれば、一方はホストプロセッサ上で実行されることになり、他方はＰＡＣＴ ＸＰＰ上で実行されることになる。これによってループ変換の適用も簡単になる。それというのもループ境界における仮定ゆえに可能な補償コードが単純になるからである。
【０２４７】
４．２．３  ＲＩＳＣコード生成およびスケジューリング
ＸＰＰコンパイラがパーティショニングフェーズにより選択されたループのためのＮＭＬコードを生成した後、メインコンパイルプロセスは、コンフィギュレーションを管理する命令が挿入されているホストプロセッサにより実行されるコードを処理する必要がある。これは以下の２つのステップの目標である：
・ＲＩＳＣコード生成
・ＲＩＳＣコードスケジューリング
第１のものはホストプロセッサを生成し、第２のものは、たとえばソフトウェアパイプラインを利用していっそう良好なスケジューリングを探すことでそれをさらに最適化する。
【０２４８】
４．３  ループのためのＸＰＰコンパイラ
図５２には、ＸＰＰコンパイラの内部処理について記載されている。これはＸＰＰループ最適化に含まれるプログラム変換の間の複合的な共働、一時的なパーティショニングフェーズ、ＮＭＬコード生成およびＰＡＣＴ ＸＰＰ上におけるコンフィギュレーションのマッピングである。
【０２４９】
【数５３】
2005535055.tif 000054
【０２５０】
プロセッサアレイ上で実行可能な最も内側のループボディを生成しようと試みるために、ＰＡＣＴ ＸＰＰにおいてターゲットとされる最初のループ最適化が適用される。これが該当するならば、ＮＭＬコード生成フェーズが呼び出され、そうでなければ、同じループに対する複数のコンフィギュレーションを得るため一時的なパーティショニングフェーズが適用される。ＮＭＬコード生成およびマッピングフェーズの後、コンフィギュレーションがＰＡＣＴ ＸＰＰに整合しないということが発生する可能性がある。その場合、ＮＭＬコード生成またはマッピングの失敗の理由を考慮して、ループ最適化が再び適用される。ループ最適化のこの新たな適用によってもコードが変化しなければ、一時的なパーティショニングが適用される。さらにＮＭＬコード生成およびマッピングに対する試みの回数を覚えておき、試みが多すぎるならば依然として解決が得られず、プロセスを中止し、ホストプロセッサによってループネストが実行されることになる。
【０２５１】
４．３．１  一時的なパーティショニング
オペレーション数すなわち１つのループネスト内で実行すべきコンフィギュレーションのサイズが単一のコンフィギュレーションにおいて実行可能なオペレーション数を超えているならば、ＰＡＣＴ ＸＰＰ用に生成されたコードが一時的なパーティショニングによって複数のコンフィギュレーションに分割される。この変換はループディスサーブと呼ばれる［６］。ついでこれらのコンフィギュレーションは、元のループのイタレーションレンジに対応する実行数をもつ複数のコンフィギュレーションのループに統合される。
【０２５２】
４．３．２  ＮＭＬコードの生成
このステップは入力としてＸＰＰループ最適化により生成されたコードの中間形態を、それについて形成されたデータフローグラフといっしょに受け取る。その後、ツリーパターンまたはＤＡＧパターンマッチング技術を使用してＮＭＬコードを生成することができる。
【０２５３】
４．３．３  マッピングステップ
このステップによれば、ＡＬＵ，ＦＲＥＧ，ＢＲＥＧにオペレーションを配置し、バスを介してデータをルーティングすることによって、ＰＡＣＴ ＸＰＰ上にＮＭＬモジュールがマッピングされる。
【０２５４】
４．４  ＸＰＰループ最適化ドライバ
次に、ＰＡＣＴ ＸＰＰのために使用されるループ最適化について述べる。この最適化の目的は、ループネストからできるかぎり多くの並列性を抽出することであり、それによって効率的にＡＬＵ−ＰＡＥを活用しながらＰＡＣＴ ＸＰＰ上でそれらのループネストを実行し、ＩＲＡＭによりメモリボトルネックを回避することにある。以下のセクションでは、それがどのように組織されているのか、最適化を適用するためにアーキテクチャをどのように考慮するのかについて説明する。
【０２５５】
４．４．１  システムの組織化
以下に示す図５３には、ループ最適化の組織化について描かれている。この変換は６つのグループに分けられる。他のスタンダードな最適化および解析はその中間に適用される。各グループは複数回呼び出される可能性がある。また、必要であれば、複数のグループにわたるループを生じさせることができる。各ドライバループのためのイタレーション数は一定の値とすることができ、あるいは最適化自体によってコンパイル時点に決定することができる（たとえば所定のコード品質に到達するまで繰り返される）。ループの最初のイタレーションにおいて、ループネストをＰＡＣＴ ＸＰＰのためにしようできるか否かをチェックすることができ、これは主としてループ境界をチェックするためのものである。たとえば、ループネストが十分に整形されておりかつデータ依存関係グラフによって最適化が妨げられないがループ境界が未知であるならば、第１のイタレーションにおいて、処理がいっそう簡単でありいっそう良好に最適化可能な最も内側のループを得るためにループタイリングが適用され、第２のイタレーションにおいて、ＰＡＣＴ ＸＰＰのために最も内側のループを効果的に最適化するためにifコンバージョン、ループインタチェンジならびに他の最適化を適用することができる。それにもかかわらずこのことは、次章で示す例によればこれまで必要とされていない。
【０２５６】
グループＩによれば、いかなるプロシージャ呼び出しもループネスト内で発生しないようになる。グループＩＩによれば、解析を容易にするためループインバリアント命令および条件命令を除去することによってループボディが準備される。グループＩＩＩによれば、データ依存関係解析に適したループネストが生成される。グループＩＶには、ベクトル化に適したデータ依存関係グラフを得るためループネストを変換する最適化が含まれている。グループＶには、最も内側のループがＰＡＣＴ ＸＰＰ上で確実に実行できるようにする最適化が含まれている。グループＶＩには、ループボディから並列性をさらに抽出する最適化が含まれている。グループＶＩＩには、ハードウェア自体の使用の最適化をいっそう考慮した最適化が含まれている。
【０２５７】
各グループにおいて最適化の適用は、解析結果およびループの特性に依存する。たとえば、グループＩＶにおける変換のすべてが適用されるわけではないことは明らかである。これは事前に計算されたデータ依存関係グラフに左右される。
【０２５８】
【数５４】
2005535055.tif 000055
【０２５９】
４．４．２  ループ準備処理
ＸＰＰコンパイラにおけるグループＩ，ＩＩ，ＩＩＩの最適化によって、プロシージャ呼び出し、条件命令、ループ制御変数以外の誘導変数をもたないループボディが生成される。したがって、最も内側のループがＰＡＣＴ ＸＰＰ上での実行に適しているようなループネストが得られる。データ依存関係解析および他のコード変換の適用を容易にするため、イタレーションレンジが正規化される。
【０２６０】
４．４．３  データ依存関係グラフの変換
グループＩＶの最適化は、データ依存関係グラフに関してベクトル化に適した最も内側のループを得るために実行される。とはいえ通常のベクトル化との相違は、通常はコードのいかなるベクトル化も妨げる依存関係サイクルによってもＰＡＣＴ ＸＰＰ用のループネストの最適化は妨げられない点にある。あるサイクルが反依存関係ゆえのものであれば、［７］で述べられているようにコードの最適化を避けたくはないことになる。また、同じ式に対するループキャリーの真の依存性によってのみ構成されているならば、依存関係サイクルによってもＰＡＣＴ ＸＰＰのためのベクトル化は妨げられないことになる。距離ｋをもつサイクルがデータ依存性グラフ中に発生するならば、レジスタにｋ個の値を保持することでこれを処理することができる。この最適化は、サイクルシュリンキングと同じクラスである。
【０２６１】
それにもかかわらず、依存性グラフに起因する制限が存在する。いくつかの依存関係距離が一定でないかまたは既知でなければ、ループネストを処理することはできない。僅かな依存関係によってしかループネスト全体の最適化が妨げられないのであれば、慣用的なベクトル化アルゴリズムを使用することによってこれを克服することができる。そのようなアルゴリズムによれば、データ依存関係グラフにおける強く結ばれたコンポーネントがトポロジー的にソートされ（ステートメント並び替え）、ついでループディストリビューションが適用される。このようにして、ＰＡＣＴ ＸＰＰにより処理可能なループネストとホストプロセッサにより処理されるいくつかのループネストを得ることができる。
【０２６２】
４．４．４  アーキテクチャに関するパラメータの影響
ハードウェア固有のいくつかのパラメータによって、ループ変換の適用に影響が及ぼされる。ループボディにより実行されるオペレーション数およびメモリアクセス数がステップごとに推定される。これらのパラメータによってループ展開、ストリップマイニング、ループタイリングに影響が及ぼされ、さらにループインタチェンジ（イタレーションレンジ）にも影響が及ぼされる。
【０２６３】
以下で示すテーブルには、最適化の適用に影響を及ぼすパラメータがリストアップされている。それらの各々について２つのデータが与えられている。この２つのデータとは、ループから計算された開始値と、最適化適用後にパラメータが到達すべきまたは超えてはならない値である制限値とである。ベクトル長は最も内側のループのレンジを表し、すなわちループボディ内でアクセスされる配列の要素数を表す。再利用されるデータセットのサイズは、キャッシュに整合させなければならないデータ量を表す。Ｉ／Ｏ，ＩＲＡＭ、ＡＬＵ、ＦＲＥＧ，ＢＲＥＧは、それぞれがＰＡＣＴ ＸＰＰを構成するＩＲＡＭ，ＡＬＵ，ＦＲＥＧ，ＢＲＥＧの個数を表す。データフローグラフ幅は、同一のパイプラインステージにおいてパラレルに実行可能なオペレーション数を表す。データフローグラフ高さはパイプラインの長さを表す。コンフィギュレーションサイクルは、パイプラインの長さおよびもっぱらコントロールのためのサイクル数である。各最適化の適用によって、
・パラメータの値を低減することができる（−）
・パラメータの値を増大させることができる（＋）
・パラメータ（ｉｄ）に影響を及ぼす可能性がない、あるいは
・目標サイズにフィットするようパラメータを整合させることができる（フィットさせることができる）
さらにコンフィギュレーションにおけるコントロールのためにいくつかのリソースを保持しておく必要がある。つまり最適化によっても、各リソースの７０〜８０％を超える要求を出さないようにすべきである。
【０２６４】
【表１】
2005535055.tif 000056
【０２６５】
ここでは以下の説明において付加的な表記が使用される。nは利用可能な処理要素の総数であり、rはデータフローグラフの幅、inは１サイクル中の入力値の最大数、outは１サイクル中で可能な出力値の最大数である。ＰＡＣＴ ＸＰＰの場合、nはコンフィギュレーションに利用可能なＡＬＵ，ＦＲＥＧ，ＢＲＥＧの個数であり、rは同一パイプラインステージにおいてパラレルにスタートさせることのできるＡＬＵ，ＦＲＥＧ，ＢＲＥＧの数であり、inおよびoutは利用可能なＩＲＡＭの数である。ＩＲＡＭは１つの入力ポートと１つの出力ポートを有しているので、ＩＲＡＭの数はそのまま入力データと出力データとなる。
【０２６６】
ループボディのオペレーション数は、すべての論理演算と算術演算を足すことによって計算される。入力値の個数は、アドレス演算を無視した命令のオペランド数である。出力値の個数は、アドレス演算を無視した命令の出力オペランドの個数である。並列オペレーションの個数を求めるためには、入力値と出力値の個数ならびにデータフローグラフを考慮しなければならない。次に、アーキテクチャに関するパラメータに及ぼされる各々の変換の作用について詳しく説明する。
【０２６７】
ループインタチェンジ
ループインタチェンジが適用されるのは、最も内側のループが過剰に狭いイタレーションレンジをもつときである。このようなケースではループインタチェンジによって、いっそう有利なイタレーションレンジをもつ最も内側のループをもたせることができる。さらにメモリ内のデータレイアウトによっても影響が及ぼされる可能性がある。この場合、２つのループをインタチェンジさせるのがデータ局所性に対し有利となる可能性があり、これによればキャッシュ内の配列をアクセスするためのいっそう有用な手法が得られ、したがってキャッシュミスが回避される。当然ながら、先に述べたようにデータ依存関係によっても影響が及ぼされる。
【０２６８】
【表２】
2005535055.tif 000057
【０２６９】
ループディストリビューション
ＰＡＣＴ ＸＰＰに整合させるにはループボディが大きすぎるとき、ループディストリビューションが適用される。その主要な作用は、コンフィギュレーションによって必要とされる処理要素を低減することである。ＩＲＡＭに対する要求の低減は副作用にすぎない。
【０２７０】
【表３】
2005535055.tif 000058
【０２７１】
ループ折り畳み
ループ折り畳みは、ループボディがいっそう多くのメモリリソースを使うようにするために利用できる。複数のディメンションがマージされるので、イタレーションレンジが大きくなり、所要メモリも同様に大きくなる。
【０２７２】
【表４】
2005535055.tif 000059
【０２７３】
ループタイリング
多次元ストリップマイニングのようにループタイリングはすべてのパラメータによって影響を受け、これはＩＲＡＭに整合させるにはイタレーション空間が著しく大きすぎるときに殊に有用であり、あるいはイタレーション空間が境界づけられていないならば（セクション４．４．６参照）、最大実行時間を保証するために殊に有用である。この場合、ＰＡＣＴ ＸＰＰのリソースつまりＩＲＡＭとキャッシュラインサイズに関して、ループボディを整合させることができる。ストリップマイニングとループタイリングのためのタイルサイズを以下のようにして計算することができる：
タイルサイズ＝ループボディに利用可能なリソース／ループボディに必要とされるリソース
ループボディのために利用可能なリソースは、このコンフィギュレーションのためのＰＡＣＴ ＸＰＰのリソース全体である。１つのタイルサイズは、処理要素のためのデータおよび他の１つに対して計算することでき、したがって最終的なタイルサイズはそれら２つの間のうちの１つである。たとえばアクセスされるデータの量がキャッシュ容量よりも大きければ、ループタイリングは以下のように適用することができる。
【０２７４】
【数５５】
2005535055.tif 000060
【０２７５】
【表５】
2005535055.tif 000061
【０２７６】
ストリップマイニング
ストリップマイニングは、最も内側のループのメモリアクセス量をＩＲＡＭ容量にフィットさせるために用いられる。処理要素は通常、問題をなさない。なぜならばＰＡＣＴ ＸＰＰは、どのような単一のループボディの実行にも十分であろう６４個のＡＬＵ−ＰＡＥを有しているからである。とはいえデータと同様、オペレーション数も考慮することができる。
【０２７７】
【表６】
2005535055.tif 000062
【０２７８】
ループ融合
ループボディによって十分なリソースが利用されなければ、ループ融合が適用される。このケースでは、利用可能なリソースの大部分を使うコンフィギュレーションが得られるよう、複数のループボディをマージすることができる。
【０２７９】
【表７】
2005535055.tif 000063
【０２８０】
スカラ置換
ループボディによって必要とされるメモリ量を、常にＩＲＡＭに整合させるべきである。この最適化によれば、ＩＲＡＭに格納されているはずの配列の参照によって表現されるいくつかの入力データまたは出力データが、ＦＲＥＧに格納されているかまたはバス上に保持されているスカラと置き換えられる。
【０２８１】
【表８】
2005535055.tif 000064
【０２８２】
ループ展開
ループ展開、ループ折り畳み、ループ融合ならびにループディストリビューションは、ループネストのボディにおけるオペレーションの個数およびそれらのオペレーションのデータ入力およびデータ出力の個数によって影響が及ぼされる。なぜならばそれらによってループボディのサイズが変更されるからである。オペレーションの個数は常にnよりも小さくなければならず、入力データおよび出力データの個数は常にinおよびoutよりも小さくなければならない。
【０２８３】
【表９】
2005535055.tif 000065
展開およびジャム
展開およびジャムは、外側のループを展開しそれに続いて内側のループをマージすることによって行われる。この場合、内側ループ内における入力メモリアクセス数ｍおよび出力メモリアクセス数ｐに関して展開度ｕを計算する必要がある。この場合、以下の不等式が維持されなければならない：
【０２８４】
【数５６】
2005535055.tif 000066
さらに新たな内側のループのオペレーション数もＰＡＣＴ ＸＰＰに整合させる必要がある。
【０２８５】
【表１０】
2005535055.tif 000067
【０２８６】
４．４．５  ハードウェア改善に向けた最適化
このステップにおいて、ＰＡＣＴ ＸＰＰ固有の他の最適化を行うことができる。これらの最適化は主として、メモリの問題ならびにデータフローの考慮に係わるものである。これはシフトレジスタ合成、（スカラのプライベート化と同様の）入力データデュプリケーション、あるいはループパイプライン化のケースである。
【０２８７】
シフトレジスタ合成
この最適化は、ループボディ実行中に発生する配列アクセスに係わる。配列の複数の値が異なるイタレーションに対して生きている場合、必要とされる時点ごとにメモリをアクセスするのではなくそれらをレジスタに格納するのが便利である。同じ値は生きているイタレーションの個数に依存して異なるレジスタに格納しなければならないので、１つの値が複数のレジスタを共有し、その値は１つのレジスタから他のレジスタへイタレーションごとに流れる。要素ごとに同じ値をもつ配列アクセスに割り当てられるベクトルレジスタについても同様である。この最適化は、１つの値を１つのレジスタに格納する必要がある場合に、レジスタを表すノードを挿入することによりデータフローグラフにおいてそのまま実行される。ＰＡＣＴ ＸＰＰの場合、これはデータレジスタへの格納に対応する。詳細な説明は文献［１］に示されている。
【０２８８】
シフトレジスタ合成は主として、値が生きた状態にある少量から中程度の量のイタレーションに適している。パイプラインの長さは値をバッファリングすべきイタレーションごとに増加するので、以下の方法は１つの入力配列における各アクセス間の距離が中程度から長い距離の場合にいっそう良好に適している。
【０２８９】
それにもかかわらずこの方法は画像処理アルゴリズムに対してきわめて良好に動作し、そのようなアルゴリズムは主としてピクセルをそのピクセル自体とその周囲のピクセルの解析によって変化させるものである。
【０２９０】
【表１１】
2005535055.tif 000068
【０２９１】
入力データデュプリケーション
この最適化はシフトレジスタ合成と直交している。同じ配列における異なる要素が同時に必要とされるならば、レジスタにその値が格納される代わりに同じ値が異なるＩＲＡＭにコピーされる。シフトレジスタ合成に対する利点はパイプラインの長さが短くなることであり、したがって並列性が増加し、さらには適用範囲が無制限になることである。他方、移動すべきデータ量によっては、キャッシュＩＲＡＭのボトルネックによりこの解決策のパフォーマンスに影響が及ぼされる可能性がある。とはいうもののここではキャッシュＩＲＡＭ転送は、メモリ階層の残りの部分における転送に対し無視できるものであるとする。
【０２９２】
【表１２】
2005535055.tif 000069
【０２９３】
ループパイプライン化
この最適化は、データフローグラフに遅延を挿入することによってオペレーションを同期合わせすることから成る。これらの遅延はレジスタである。ＰＡＣＴ ＸＰＰの場合、このことはそれらを利用してオペレーションを遅延させるためにデータレジスタに値を格納することに相応する。これはｘｍａｐにより実行されるパイプラインバランシングと同じである。
【０２９４】
【表１３】
2005535055.tif 000070
【０２９５】
ツリーバランシング
この最適化は、ループボディを表すツリーのバランスをとることから成る。これによってパイプラインの深さが低減され、したがってイタレーションの実行時間が減少し、並列性が増加する。
【０２９６】
【表１４】
2005535055.tif 000071
【０２９７】
４．４．６  コンフィギュレーション実行時間の制限
コンフィギュレーションの実行時間をコントロールする必要がある。これはストリップマイニングとループタイリングによってコンパイラにおいて保証され、これによればＩＲＡＭ容量よりも多い入力データが１つのサイクル中にＰＡＣＴ ＸＰＰに到来しないよう配慮される。このようにしてＰＡＣＴ ＸＰＰ上で実行される最も内側のループのイタレーションレンジが制限され、ひいては実行時間が制限される。さらにパーティショニングによって保証されるのは、ランタイムに計算可能な実行カウントをもつループがＰＡＣＴ ＸＰＰ上で実行されるようになることである。この条件はforループにとっては些細なことであるけれども、実行カウントをスタティックには求めることのできないwhileループにとっては以下に示すような変換を適用することができる。その結果、内側のforループをＰＡＣＴ ＸＰＰによって処理することができる。
【０２９８】
【数５７】
2005535055.tif 000072
【０２９９】
５  ケーススタディ
５．１  ３ｘ３エッジ検出器
５．１．１．  オリジナルコード
ソースコード
【０３００】
【数５８】
2005535055.tif 000073
【０３０１】
５．１．２  前変換
プロシージャ間の最適化
最初のステップでは通常、関数インライン化やループプッシュのようなプロシージャ間の変換が行われる。ループボディ内ではプロシージャ呼び出しはないので、これらの変換はこの例では適用されない。
【０３０２】
パーティショニング
パーティショニングアルゴリズムによって、どのコードをＲＩＳＣプロセッサで実行させ、どのコードをＸＰＰで実行させるのかが選択される。ＸＰＰ上で実行させるためには内側のループだけしか考慮しないので、基本ブロックにはループネストの深さを用いて注釈をつけている。したがってループ内にはない基本ブロックは別にされている。さらにループボディ内の関数呼び出しによって、ＸＰＰ上で実行させるために考慮すべきループが妨げられる。
【０３０３】
本願発明によるベンチマークによればループネスト１と３は、関数呼び出しであるがゆえにＲＩＳＣホスト上で実行されるものとしてマークされる。以下のセクションにおいてはそれらはもはや考慮されない。
【０３０４】
なお、このコンパイル段階では、残りのループネストをＸＰＰのために合成できるか否かは予測できない。ＸＰＰ上で明確に実行不可能なものはすでに別にしており、他のものをそれに追随させてもよく、その理由はＲＩＳＣ ＣＰＵ上でコードを実行することは、本願のストラテジにおいて常に再保証になるからである。
【０３０５】
ループ解析および正規化
上述のコードはすでに正規化されている。それにもかかわらず人間の書いたコードは以下のようになっている可能性がある。
【０３０６】
【数５９】
2005535055.tif 000074
【０３０７】
人間の読み手は一目でわかるとはいえ、コンパイラにとってはループが十分に整形されていることは明白ではない。それゆえループを正規化しようとする。
【０３０８】
オリジナルコードの誘導変数をiと称し、それぞれインクリメント値sおよび上方および下方のループ境界Iおよびuを伴う場合、誘導変数i'および上方の境界u'（下方の境界I'は定義により0）を伴う正規化されたループは以下のように変換される：
・上方の境界は計算によりu' = (u-I)/sとなる。
・iのすべての発生は1+i'*sと置き換えられる。
【０３０９】
上述のコードに適用するならば、下方境界v1 = 1、上方境界vu = 14（<15 つまり整数演算の<= 14)、インクリメント値vs = 1をもつループステートメントfor(v=1; v < VERLEN - 1; v++)は、
for(vn=0; vn <= (vu - v1)/vs; vn++)
と変換されるかまたは単純に、
for(vn=0; vn <= 13; vn++)
と変換される。'h-loop'は同等に変換され、オリジナルコードが出される。
【０３１０】
イディオム認識
第２のステップにおいてイディオム認識により、ループボディ内のabs()とmin()の構造が見つけられる。なお、ＸＰＰはabsオプコードをもっていないにもかかわらず、それを簡単に合成することができ、したがって内部表現を簡単にするために生成することができる（さもないとifコンバージョンによってこのケースを取り扱わなければならず、これによって複雑さが増してしまう）。
【０３１１】
したがってイディオム認識後のコードは以下のようになる（abs()とmin()はコンパイラに既知の関数であり、これらはそのままＸＰＰオプコードにマッピングされるかまたはあらかじめ定義されたＮＭＬモジュールにマッピングされる）。
【０３１２】
【数６０】
2005535055.tif 000075
【０３１３】
【数６１】
2005535055.tif 000076
【０３１４】
ここでは、パイプラインベクトル化を妨げるループキャリア依存関係が存在しない。ループに依存しないスカラ依存関係によってもパイプラインは妨げられない。なぜならば変換によっても読み取りおよび書き込みの順序が妨害されないからである。さらに前方式置換／デッドコード除去によってスカラ完全性が取り除かれる。
【０３１５】
５．１．３  プリコード生成変換
ループネスト後にはhtmp, vtmpおよびsumを使用しないことで、前方式置換をデッドコード除去に加えて行うことができ、これによって計算全体が１つのステートメントに置き換えられる。
【０３１６】
【数６２】
2005535055.tif 000077
【０３１７】
その後、スカラアクセスは完全に消滅する。
【０３１８】
ＩＲＡＭへのマッピング
配列アクセスはＩＲＡＭにマッピングされる。この段階でＩＲＡＭの個数は任意に選ばれ、ＸＰＰ ＩＲＡＭへの実際のマッピングはあとで行われる。
【０３１９】
したがってここではp1[v+x][h+y]およびp2[v+x][h+y]がiramN[y]にリネームされる（たとえばp1[v+2][h]はiram2[0]）。したがってコードは以下の通りとなる。
【０３２０】
【数６３】
2005535055.tif 000078
【０３２１】
ツリーバランシング
図５６に描かれている式のツリーには、ツリーのマッチング前に行われる他の有用な最適化について示されている。ツリーの深さによって合成されたパイプラインの長さが決定されるので、他の単純化によってこの深さを低減することができる。メインとサブのツリーの両方で可換のadd式のオペランドを入れ替え（インタチェンジ）可能であり、これによってツリー全体の深さが低減される。
【０３２２】
【数６４】
2005535055.tif 000079
【０３２３】
図５７には、結果として得られたツリーが示されている。
【０３２４】
５．１．４  ＸＰＰコード生成
パイプライン合成
すでに述べたように、パイプラインはツリーマッチャーのダイナミックなプログラミングによって合成される。シーケンシャルなプロセッサとは対照的に、これによれば命令およびレジスタ参照が生成されるのではなく、ＰＡＥオプコードとポートコネクションが生成される。図５８にはメイン計算ネットワークが示されている。この図には入力データ準備ネットワークは示されていない。図５９には合成されたシフトレジスタの事例が示されている一方、図５８ではデュプリケートされた入力データによる変形が入力チャネルごとに単に１つのＩＲＡＭによって構成されている。
【０３２５】
これは直接的であるとはいえ、ここではベクトルレジスタアドレスの異なるオフセットにどのようにアクセスするのかという疑問が残る。また、ＲＡＭ−ＰＡＥはデュアルポートで構成されているけれども、異なるアドレスを同時に読み取ることはできないのは明白である。
【０３２６】
異なるアドレスをシーケンシャルに生成し、かつ読み出しオペランドをデータフローの異なる分岐にデマルチプレクスするコンフィギュレーションを合成するのは効率的ではないので、他の配置を行わなければならない。
【０３２７】
サブセクション４．４．５で示した入力データをアクセスするための２つの可能性によれば、ＲＩＳＣ疑似コードおよびＸＰＰを利用した以下のコードが生成される。ＲＩＳＣコア上で実行される擬似コードは以下のようなものである。
【０３２８】
【数６５】
2005535055.tif 000080
【０３２９】
【数６６】
2005535055.tif 000081
【０３３０】
【数６７】
2005535055.tif 000082
【０３３１】
以下のテーブルにおいては、配置およびルートならびにシミュレーションのための値が比較されている。なお、２つのＭＡＣユニットおよびハードウェアループサポートを備えた一般的なＲＩＳＣ ＤＳＰは、同じコードのために約４００００サイクルを必要とする。この比較によってもキャッシュミスの理由はわからない。さらに自明であるように、ここでは入力値の個数は著しく僅かであり、ＤＳＰ計算時間はこの個数に比例する。他方、ＸＰＰのパフォーマンスは入力値の個数とともに改善する。したがってＸＰＰのパフォーマンスは、イメージサイズが大きくなるにつれていっそう素晴らしいものとなる。
【０３３２】
【表１５】
2005535055.tif 000083
【０３３３】
５．１．５  並列性の増強
合成後、内側ループを計算するコンフィギュレーションによって、シフトレジスタ合成のために２７個のＡＬＵと４つのＩＲＡＭを、データデュプリケーションのために２１個のＡＬＵと９個のＩＲＡＭがそれぞれ利用される。ＸＰＰ６４コアであるとすれば、これによってさらに最適化するための多くの空間が残される。とはいうものの、並列性を高めるすべての最適化が実行されてから合成が行われるので、必要とされるリソースおよび変換の利点を非常に注意深く推測することが重要である。さらにそれらが適正な値を推定するための両方の入力の準備とならなければならない。
【０３３４】
ループ展開
内側のループを完全に展開しても十分な結果は得られない。その理由は入力および出力の個数が劇的に増加するからである。つまりデータデュプリケーションを適用することはできず、さらにシフトレジスタ合成によれば、データフローグラフごとに著しく長いパイプラインの生成によって並列性の利点の大部分が使い尽くされてしまうことになる。内側のループの部分的な展開は適用できないとはいえ、導入されるエリアの不利な点に対するいっそうの利点が得られる見込みはない。
【０３３５】
外側のループの展開も適用できない。なぜならばこれによってさらにコンフィギュレーションが生成されるからである。とはいえ関連する変換によってこのループネストにおいて良好なジョブをなすことができる。
【０３３６】
展開およびジャム
展開およびジャムのアルゴリズムによって並列性が高められ、ＩＲＡＭの利用も改善される。これによって、ＩＲＡＭの出力および計算結果の理想的な再利用とともにイタレーションのペアがもたらされる。このアルゴリズムによって外側のループが部分的に展開され、最初の内側のループが融合される。展開およびジャムが実行される前に、いわゆる展開およびジャムのファクタを決定する必要があり、これによれば外側ループの展開ファクタが決定される。これは主としてＡＬＵの個数（ＸＰＰ６４であれば６４個）によって影響が及ぼされ、計算により、
【０３３７】
【数６８】
2005535055.tif 000084
となる。したがってソースコードは以下のように変換されることになる。
【０３３８】
【数６９】
2005535055.tif 000085
【０３３９】
この変換によって、p1[v+3][h], p1[v+3][h+2], p1[v+3][h+1]およびp1[v+1][h+1]に対し付加的なアクセス（アクセスパターンにおける前者のホール）が生じ、さらにp2[v+2][h+1]に対する書き込みアクセスが生じる。つまりこのことは、２つのＩＲＡＭはシフトレジスタ合成（１つの入力、１つの出力）以上のことであり、５つのＩＲＡＭはデータデュプリケーション（４つの入力、１つの出力）以上のことであり、他方、パフォーマンスが２倍になることを意味する。
【０３４０】
【表１６】
2005535055.tif 000086
【０３４１】
シミュレートされた結果を上記のテーブルに示す。なお、「データデュプリケーション」と記された２つの列の相違について説明する。最初のものはＩＲＡＭを配置するためにｘｍａｐを用いている一方、２番目のものはグリーディアルゴリズムgreedy algorithmを使用してＩＲＡＭを配置しており、このアルゴリズムによれば（可能であるかぎり）１つのラインにおける同じ演算子のオペランドであるＩＲＡＭが配置される。第２の解決策によれば、イタレーションサイクルが１８だけ改善される。このことから、最終的なパフォーマンスに対しＩＲＡＭの配置が大きな影響力をもっていることがわかる。
【０３４２】
慣用的な展開およびジャムアルゴリズムは、外側のループをプレループと奇数のループカウントを処理する展開可能なメインループとに分割するためにループピーリングを使用する。たとえばｎ＝１２８であるとすれば、展開およびジャムの係数の計算により、
【０３４３】
【数７０】
2005535055.tif 000087
となる。外側のループカウント（１４）は４の倍数ではないので、アルゴリズムは最初の２つのイタレーションを実質的にピーリングし、最後に２つのループを融合して内側ループボディに対するガードを加える。この場合、コードは以下のようになる（ガードが強調されている）。
【０３４４】
【数７１】
2005535055.tif 000088
【０３４５】
５．１．６  パラメータ化ファンクション
ソースコード
ベンチマークソースコードは、実世界のアプリケーションの形式で書かれることはほとんどない。通常、処理する画像サイズに従う入出力配列のためのパラメータをもつ関数にカプセル化されることになる。
【０３４６】
したがってソースコードは以下のようになる：
【０３４７】
【数７２】
2005535055.tif 000089
【０３４８】
これによれば、コンパイラに対しいくつかの付加的な特徴が要求される。
・プロシージャ間の最適化および解析
・プログラマによる指示（たとえばコンパイラに既知のassert(VERLEN %2==0)によって、イタレーションのピーリングや条件付きの実行を伴わずに展開およびジャムを実際に行えるようになる）。
【０３４９】
配列に対するアルゴリズムの最適な整合
HORLENおよびVERLENはコンパイル時点で既知ではないので、それら未知のパラメータによってパイプラインベクトル化を妨げるいくつかの制約が引き起こされる。ＩＲＡＭが１つの行におけるすべてのHORLEN入力値を保持できないことをコンパイラは前提としなければならず、したがってパイプラインベクトル化が不可能になってしまう。
【０３５０】
内側ループのストリップマイニング
ストリップマイニングによって内側ループが１つのストリップにわたって実行されるループに分割され、これは複数のストリップにわたるループイタレーションのストリップによってＩＲＡＭが保持できるのと同じサイズとなるよう選定される。当然ながらストリップループの上限は、場合によっては不完全な最後のストリップのために調整しなければならない。ストリップマイニング後、オリジナルコードは以下のようになる（外側のｖループは無視）：
【０３５１】
【数７３】
2005535055.tif 000090
【０３５２】
ＩＲＡＭサイズのストリップサイズを２５６とすれば、１つのストリップのために以下のシミュレーション結果を得ることができる。これらの値は計算すべきストリップの個数で乗算する必要がある。
【０３５３】
【表１７】
2005535055.tif 000091
【０３５４】
ＲＩＳＣ ＤＳＰのためにはこの量のデータのために約１４７万サイクルが必要である。上述のようにこれらの値にはキャッシュミスペナルティが含まれておらず、実際値よりも実は過小評価されている。さらにデータデュプリケーションによってもパフォーマンスは改善されていないこともわかる。その理由は、配置およびルーティングが悪いことであると思われる。
【０３５５】
５．２  ＦＩＲフィルタ
５．２．１  オリジナルコード
ソースコード：
【０３５６】
【数７４】
2005535055.tif 000092
【０３５７】
この場合、定数ＮとＭはプリプロセッサによりそれらの値に置き換えられる。データ依存関係グラフは以下の通りである：
【０３５８】
【数７５】
2005535055.tif 000093
【０３５９】
以下にテーブルを示す：
【０３６０】
【表１８】
2005535055.tif 000094
【０３６１】
５．２．２  第１の解決策
メモリを節約したいケースでは簡単な解決策は、内側ループの展開ならびにパイプラインにおける配列ｘの値を遅延させるためにシフトレジスタ合成を使用することである。ループに作用が及ぼされる前またはＩＲＡＭに対する要求が高められる前は、他のいかなる最適化も適用されない。ループ展開後、以下のコードが得られる：
【０３６２】
【数７６】
2005535055.tif 000095
【０３６３】
この場合、テーブルは以下のようになる：
【０３６４】
【表１９】
2005535055.tif 000096
【０３６５】
データ解析によれば、y[0]=f(x[0],...,x[7]), y[1]=f(x[1],...,x[8],...,y[i]=f(x[i],...,x[i+7])であることがわかる。yの連続する値はたいてい、ｘの同じ連続する値に依存する。ＩＲＡＭに対する不必要なアクセスを回避するため、yの次の値の計算に必要とされるxの値がレジスタに保持される。この事例では、このシフトレジスタ合成のために７つのレジスタが必要とされる。これはＰＡＣＴ ＸＰＰでは、それらをＦＲＥＧに保持することによって達成されることになる。この場合、以下に示すデータフローグラフが得られる。入力値のために１つのＩＲＡＭが用いられ、出力値のために１つのＩＲＡＭが用いられる。パイプラインを満たすために最初の８回のサイクルが用いられ、この場合、スループットはサイクルあたり１つの出力値となる。コードを以下に示す：
【０３６６】
【数７７】
2005535055.tif 000097
【０３６７】
最終的なテーブルを以下に示す。サイクルあたり２つの命令が発行される標準的なスーパスカラプロセッサに対し、予期されるスピードアップは１３．６となる。
【０３６８】
【表２０】
2005535055.tif 000098
【０３６９】
いっそう大きいループ境界をもつ変形例
ここではいっそう長いループ境界のものとし、ＮとＭの値を１０２４および６４にセットする。
【０３７０】
【数７８】
2005535055.tif 000099
【０３７１】
上述のループ最適化ドライバに続いて、内側ループのイタレーションレンジを低減するためループタイリングが適用される。
【０３７２】
【数７９】
2005535055.tif 000100
【０３７３】
ついで内側ループにループ展開を適用することにより以下の通りとなる：
【０３７４】
【数８０】
2005535055.tif 000101
【０３７５】
最終的に、定数のように乗算によりじかに処理されるのではなく他のＩＲＡＭから係数を読み出す必要があることを除いて、上述のものと同じデータフローグラフが得られる。シフトレジスタ合成後、コードは以下の通りとなる：
【０３７６】
【数８１】
2005535055.tif 000102
【０３７７】
以下のテーブルは、ベクトル長ならびにサイクルごとに２つの命令が発行される標準的なスーパスカラプロセッサに対するスピードアップが１７．５であること以外、前述のものと同じである。
【０３７８】
【表２１】
2005535055.tif 000103
【０３７９】
５．２．３  いっそう並列的な解決策
これまで示してきた解決策によれば、ループ内で多数の並列性が与えられていない。ここではデータフローグラフ生成前にループを明示的に並列化させるよう試すことができる。当然ながら、いっそうの並列性とは、メモリ階層においていっそう大きな圧迫が生じることを意味する。最初に示したデータ依存関係グラフの場合、ループキャリーのみの依存関係はＳ′における依存関係であり、これはy[i]への参照によってのみ引き起こされる。ここでは、いっそう適切なデータ依存関係グラフを得るためにノードスプリットが適用される。この場合、以下のようになる：
【０３８０】
【数８２】
2005535055.tif 000104
【０３８１】
ついでtmpに対してスカラ式が実行され、これによってそれにより引き起こされる反ループキャリー依存関係が除去され、以下のコードが得られる：
【０３８２】
【数８３】
2005535055.tif 000105
【０３８３】
パラメータテーブルは以下の通りである：
【０３８４】
【表２２】
2005535055.tif 000106
【０３８５】
ついで、ベクトル化可能なループとベクトル化不可能なループが得られるようループディストリビューションが適用される。
【０３８６】
【数８４】
2005535055.tif 000107
【０３８７】
先行のテーブルと比較する目的で、以下に示すパラメータテーブルは２つの内側ループに相応する。
【０３８８】
【表２３】
2005535055.tif 000108
【０３８９】
この場合、アーキテクチャを考慮しなければならない。最初のループは完全に並列である。つまり１つの時点に２*８＝１６個の入力値が必要とされる。これはＰＡＣＴ ＸＰＰのＩＲＡＭの個数に対応するので申し分ない。したがって最初の内側ループをストリップマイニングする必要がない。第２のループが普通であれば、これもまたストリップマイニングする必要がない。第２のループはリダクションであり、これによりベクトルの和が計算される。これはリダクション認識最適化によって容易に見つけられ、以下のコードが得られる：
【０３９０】
【数８５】
2005535055.tif 000109
【０３９１】
上述のように、最も内側のすべてのループとただ１つのテーブルとy[i]を計算する最後の命令についてただ１つテーブルを示す。
【０３９２】
【表２４】
2005535055.tif 000110
【０３９３】
最終的にループ展開が内側ループに対して適用され、オペレーションの個数が常にＰＡＣＴ ＸＰＰの処理要素数よりも少なくなる。
【０３９４】
【数８６】
2005535055.tif 000111
【０３９５】
その際、内側ループを表す以下のデータフローグラフが得られる。
【０３９６】
【数８７】
2005535055.tif 000112
【０３９７】
この場合、パラレルに実行されるレイヤごとにＰＡＣＴ ＸＰＰ上でマッピングすることができ、したがってイタレーションごとに４つのサイクルと１５個のＡＬＵ−ＰＡＥが必要とされ、それらのうち８個がパラレルに必要とされる。グラフはすでに同期合わせされているので、スループットはパイプラインを満たすために４つのサイクル後、サイクルごとに１つのイタレーションとなる。この場合、係数は乗算を実行するＡＬＵにより一定の入力として受け取られる。
【０３９８】
この解決策の欠点は、１６個のＩＲＡＭを使用することおよび入力データを特別な順序で格納しなければならないことである。係数をＡＬＵごとの定数のように処理すれば、必要とされるＩＲＡＭの個数を低減することができる。プログラムのデータ局所性ゆえに、データはすでにキャッシュ内に存在するものとすることができる。キャッシュからＩＲＡＭへのデータ転送を効率的に行うことができるので、ＩＲＡＭ内でデータが準備完了状態になるのを待つことなくＰＡＣＴ ＸＰＰ上でコンフィギュレーションを実行することができる。パラメータテーブルは以下の通りとなる：
【０３９９】
【表２５】
2005535055.tif 000113
【０４００】
いっそう長い境界による変形例
１つのビットにもっと重きを置くようにするために、ＮとＭの値を１０２４と６４にセットする。
【０４０１】
【数８８】
2005535055.tif 000114
【０４０２】
データ依存関係グラフは上述のものと同じである。この場合、いっそう都合のよいデータ依存関係グラフを得るために、ノードスプリットを適用する。
【０４０３】
【数８９】
2005535055.tif 000115
【０４０４】
さらにコンパイルプロセスを進め、アーキテクチャに関するパラメータに依存した最適化のセットに到達する。その際、そのままであると過度に多くのオペレーションをパラレルに実行しなければならないので、イタレーション空間を分割するようにしたい。したがって２つのループに対してストリップマイニングが実行される。この場合、１つの時点で１６個のデータしかアクセスできず、したがって第１のループゆえに係数は２つのループに対して６４*２／１６＝８となる（なぜならばＰＡＣＴ ＸＰＰ上で同じ時点に両方を実行したいということを常に考慮しているからである）。
【０４０５】
【数９０】
2005535055.tif 000116
【０４０６】
【数９１】
2005535055.tif 000117
【０４０７】
この場合、最も内側のループはＰＡＣＴ ＸＰＰにおいてそのままカウンタによってインプリメントされる。ＩＲＡＭはＦＩＦＯモードにおいて使用され、常にループ内で配列のアドレスに従い満たされる。ＩＲＡＭ０，ＩＲＡＭ２，ＩＲＡＭ４，ＩＲＡＭ６およびＩＲＡＭ８には配列ｃが含まれている。ＩＲＡＭ１，ＩＲＡＭ３，ＩＲＡＭ５およびＩＲＡＭ７には配列ｘが含まれている。配列ｃには６４個の要素が含まれており、つまりＩＲＡＭごとに８つの要素が含まれている。配列ｘには１０２４個の要素が含まれており、つまりＩＲＡＭごとに１２８個の要素が含まれている。配列は、それがグローバル配列でありかつアドレスが一定であるため、メモリにダイレクトに書き込まれる。この定数は、コンフィギュレーションのアドレスカウンタを初期化するために用いられる。最終的なパラメータテーブルは以下の通りとなる：
【０４０８】
【表２６】
2005535055.tif 000118
【０４０９】
とはいうものの、このバージョンは先行のものよりも効率的ではないことを述べておく。同じデータをキャッシュから異なるＩＲＡＭにロードしなければならないため、コンフィギュレーションによって計算を開始させることができるようになる前に多くの転送を行わなければならない。コード生成ストラテジの選定にあたり、コンパイラはこのオーバヘッドを考慮しなければならない。つまりこのことは、第１の解決策がコンパイラによって選定されることになる解決策であることも意味している。
【０４１０】
５．２．４  他の変形例
ソースコード
【０４１１】
【数９２】
2005535055.tif 000119
【０４１２】
この事例において自明であるのは、データ依存関係グラフがtmpに対する依存性ゆえに周期的なことである。したがってスカラエクスパンションがループに対して適用され、以下で示すように実際にＦＩＲフィルタの第１のバージョンと同じコードが得られる。
【０４１３】
【数９３】
2005535055.tif 000120
【０４１４】
５．３  行列乗算
５．３．１  オリジナルコード
ソースコード：
【０４１５】
【数９４】
2005535055.tif 000121
【０４１６】
５．３．２  前変換
インライン化可能な関数呼び出しが存在しないので、プロシージャ間のコード移動が行われる。４つのループネストのうち/* 乗算 */というコメントの付されたループネストは、ＸＰＰ上で部分的に実行するための候補にすぎない。他のすべてのものはループボディ内の関数呼び出しであり、したがってコンパイラにおいて候補としてきわめて明瞭に除かれる。
【０４１７】
依存関係解析
【０４１８】
【数９５】
2005535055.tif 000122
【０４１９】
データ依存関係グラフには、パイプラインベクトル化を妨げる依存関係は示されていない。Ｓ２からそれ自身へのループキャリーの真の依存性は、文献［１］に示されているようにauxのフィードバックによって処理することができる。
【０４２０】
リバースループインバリアントコードモーション
１つの完全なループネストを得るために、Ｓ１とＳ３をｋループの中に移動させる。したがって割り当てを完全にするために適切なガードが生成される。この変換後のコードは以下のようになる。
【０４２１】
【数９６】
2005535055.tif 000123
【０４２２】
スカラエクスパンション
ここでの目標は、キャッシュを最良に利用するためにループネストをインタチェンジさせて配列アクセスを改善することである。不利なことにauxを含むガードステートメントによって、ループによりキャリーされるバックワードのループキャリー反依存関係が引き起こされる。スカラエクスパンションによってこれらの依存性が断たれることになり、これによってループインタチェンジが可能となる。
【０４２３】
【数９７】
2005535055.tif 000124
【０４２４】
キャッシュ再利用のためのループインタチェンジ
メインループのビジュアライズによれば、配列アクセスのためのイタレーション空間が示されている（図６１）。Ｃ配列は行優先順に配置されているので、キャッシュラインは配列の行で配置される。一瞥して最適化が不要のようであって、その理由は１つの列を越えるのに少なくとも１つの配列アクセスが要求されるからである。とはいうものの、この仮定によれば、アクセスレートが重要であるというこも損なわれる。いっそ近い調査によればjのイタレーションごとに配列Ｒがアクセスされる一方、ｋのイタレーションごとに配列Ｂがアクセスされ、これにより常にキャッシュミスが引き起こされる（この考察においてauxは無視する。その理由は、それをメモリへ書き込むことまたはメモリから読み出すことは予想されないからである。つまりループネストの外側に定義点defまたは使用点useは存在しない）。
【０４２５】
【数９８】
2005535055.tif 000125
【０４２６】
最良のループネストの探索は比較的単純である。アルゴリズムによってネストにおける各ループが最も内側のポジションに単純にインタチェンジされ、これにはいわゆる最も内側のメモリコスト項と注釈が付けられる。このコスト項は既知のループ境界に対する定数であり、または未知のループ境界に対するループ境界の関数である。この項は３つのステップで計算される。
・１番目に、最も内側のループボディにおける各参照のコストを計算することにより以下のようになる。
【０４２７】
・参照が（目下の）最も内側のループのループ誘導変数に依存していなければ１になる。
【０４２８】
・参照がループ誘導変数に依存しており、キャッシュレイアウトに関して隣接しないエリアを越えるならば、ループカウントになる。
【０４２９】
・参照がループ誘導変数に依存しかつ隣接するディメンションを越えるならば（Ｎ・ｓ）／ｂ、この場合、それぞれＮはループカウントであり、Ｓはステップサイズ、ｂはキャッシュラインサイズである。
・２番目に、各参照コストが他のループ各々に対するファクタによって重み付けられる。これは、
・参照がループインデックスに依存していなければ１である。
【０４３０】
・参照がループインデックスに依存していればループカウントである。
・３番目に、すべての参照コストのコストを合計することによってループネストのコスト全体が計算される。
【０４３１】
最も内側のループとしてループごとにアルゴリズムを呼び出した後、最小コストのものがもっとも内側のものとして選ばれ、次に外側のものが次のものとして選ばれる、という具合に行われる。
【０４３２】
【表２７】
2005535055.tif 000126
【０４３３】
このテーブルには行列乗算のための値が示されている。j項は最小であるので（もちろんｂ＞１とする）、jループが最も内側として選ばれる。そして次に外側のループはkであり、最も外側のループはiである。このためループインタチェンジ後に結果として生じるコードは以下の通りとなる：
【０４３４】
【数９９】
2005535055.tif 000127
【０４３５】
図６２には改善されたイタレーション空間が示されている。つまりこの最適化によっても本来ＸＰＰのためには最適化されないが、主としてキャッシュヒットレートが最適化され、したがってパフォーマンス全体が改善される。
【０４３６】
展開およびジャム
キャッシュアクセスの挙動が改善された後には、リダクション識別に対する可能性が消滅する。これは、１つのものが他のものを排除する変換に関する典型的な例である。それにもかかわらず、展開およびジャムによってなおいっそうの並列性が得られる。したがって外側のループが展開ファクタによって部分的に展開される。このファクタは主として２つの計算の最小値によって選ばれる。
・  # 利用可能なＩＲＡＭ／  # 内側ループボディ内で使用されるＩＲＡＭ
・  # 利用可能なＡＬＵリソース／  # 内側ループボディ内で使用されるＡＬＵリソース
この例の場合、"A"と"B"に対するアクセスはk（展開されることのないループ）に依存する。したがってそれらは計算において考慮しなければならない。"aux"および"R"に対するアクセスはkには依存しない。したがってそれらを利用可能なＩＲＡＭから減算することができるけれども、分母に加算する必要はない。それゆえＩＲＡＭリソースにより得られる展開ファクタのために（ＸＰＰ６４であれば）計算により１４／２＝７となる。
【０４３７】
他方、ループボディには２つのＡＬＵオペレーションが含まれ（１つの加算、１つの乗算）、これによりほぼ６４／２＝３２の展開ファクタとなる。（これはきわめて不正確な見積もりである。なぜならば、展開ファクタを減少させる制御ネットワークにより費やされるリソースも見積もっていないし、たとえばＢＲＥＧ−ＰＡＥも加算器を有しており、これによって展開ファクタが増加することも考慮していないからである。これらのことは上述の例には作用を及ぼさないにしても、プロダクションコンパイラでは展開ファクタの計算にあたり当然ながらこのことを考慮しなければならない。）このためＩＲＡＭにより生じる制約の方がはるかに優勢である。
【０４３８】
展開ファクタを選んだならば、ループトリップカウンタをそのファクタの倍数となるよう調整する必要がある。kループは１５というループカウントを有しているので、１番目のイタレーションをピーリングし、残りのループを展開する。
【０４３９】
【数１００】
2005535055.tif 000128
【０４４０】
リバースループインバリアントコードモーションによって、ループインバリアントコードがここで７回デュプリケートされる内側ループに配置されるということから、デッドコード削除によってこれらのデュプリケートのいつかを免れることができる可能性がきわめて高い。したがってコードは以下のように短くされる：
【０４４１】
【数１０１】
2005535055.tif 000129
【０４４２】
内側ループのジャムを行う前に、kループの最初のイタレーションがピーリングされ自身のコンフィギュレーションが生成されるようになることを考慮しなければならない。１つのコンフィギュレーションに整合するよう展開およびジャムのファクタが計算されているので、この副作用を避けなければならない。可変のステップサイズでkループを実行させるのは何の問題もないので、kループが再び融合され、ステップサイズが調節され、ステートメントがガードされる。その結果、以下の通りとなる：
【０４４３】
【数１０２】
2005535055.tif 000130
【０４４４】
５．３．３  ＸＰＰコード生成
最も内側のループを１つのコンフィギュレーションにおいて合成することができ、これによれば入力データのための１４個のＩＲＡＭ、auxを一時的に格納するための１つのＩＲＡＭ、ならびに出力配列Ｒのための１つのＩＲＡＭが使用される。さらに、データフローを指示するためkの値をＸＰＰへ送る必要がある。このことはストリーミング入力によって行うことができる。図６３には、合成されたコンフィギュレーションのデータフローグラフが示されている。
【０４４５】
【数１０３】
2005535055.tif 000131
【０４４６】
以下のコードは、ＲＩＳＣプロセッサ上で実行される擬似コードを示すものである。
【０４４７】
【数１０４】
2005535055.tif 000132
【０４４８】
シミュレートされたコンフィギュレーションを以下のテーブルによって示す。完全な乗算のためには、プリロードおよびコンフィギュレーションなしで約３１２０サイクルが必要とされる。２つのＭＡＣユニットおよびハードウェアサポートループを備えた典型的なＲＩＳＣ−ＤＳＰコアであれば（データがゼロレイテンシの内部メモリにある場合）、２６０００サイクルを必要とする。ここでプリロードおよびキャッシュミスのための時間を無視しているとはいえ、この値は標準ＲＩＳＣコアに比べて２００〜３００％の改善を約束するものである。
【０４４９】
【表２８】
2005535055.tif 000133
【０４５０】
５．４  ビタビエンコーダ
５．４．１  オリジナルコード
ソースコード：
【０４５１】
【数１０５】
2005535055.tif 000134
【０４５２】
５．４．２  プロシージャ間最適化およびスカラ変換
インライン可能な関数コールはないため、プロシージャ間のコード移動は行われない。
【０４５３】
表現の簡略化、強さの低減（strength reduction）、ＳＳＡリネーミング、コピー一重化（copy coalescing）およびイディオム認識（idiom recognition）の後、コードはつぎのようになる（便宜上、命令文の順序は並び替えられている）。イディオム認識により、min()を組み合わせることと、decisionおよび＿decisionに対する比較結果を使用することとがわかることに注意されたい。しかしながら計算結果はＣで表すことができないため、コメントとして記す。
【０４５４】
【数１０６】
2005535055.tif 000135
【０４５５】
【数１０７】
2005535055.tif 000136
【０４５６】
５．４．３  初期化
第１のループ（vp->dp->w[0〜7]を０にセットする）はＲＩＳＣにおいて最も効率的に実行される。
【０４５７】
５．４．４  バタフライループ
（BFLY()マクロを展開した）第２のループは、ＸＰＰコンパイラにとって関心の対象であり、さらなる検証が必要である。
【０４５８】
【数１０８】
2005535055.tif 000137
【０４５９】
データフローグラフはつぎの通りである（今のところ、ＩＲＡＭアクセスはほとんどｃｈａｒアクセスであるという事実を無視する）。実線はデータフローを表しており、これに対して破線はイベントフローを表している。
【０４６０】
【数１０９】
2005535055.tif 000138
【０４６１】
【表２９】
2005535055.tif 000139
【０４６２】
いくつか問題があることが直ちにわかる。すなわちＩＲＡＭ７は同じアドレスを１６回、読み出しおよび再書き込みするのに完全に忙殺されている。タイルサイズ１６のループタイリング（loop tiling）により、「冗長なロードストア除去（redundant load store elimination）」が得られ、すなわち値を一旦読み込んでビットを一時的に蓄積し、この内側のループの終わりにこの値をＩＲＡＭに書き込むチャンスが得られるのである。つぎに初期化ループとのループ融合（loop fusion）により、第１ループにおいてセットされる０値をvp->dp->w[i]（ＩＲＡＭ７）の読み出しに伝搬することができ、第１ループ全体を除去できる。またタイルサイズ１６のループタイリングにより、シフト値に対する＆３１なる表現を除去することができる。それは新しい内側のループは、０から１６までで実行され、値域の解析によって＆３１なる表現は、もはや値域を制限しないことがわかるからである。
【０４６３】
残りの入力ＩＲＡＭはすべてキャラクタ（８ビット）ベースである。したがってネットワークを分解して、３２ビットストリームを４つの８ビットストリームに分けなければならない。これらの８ビットストリームはその後、マージされる。これにより、３つのシフトと、３つのａｎｄと、３つのマージがキャラクタＩＲＡＭ毎に追加される。ループ本体をアンロール（unroll）する場合にはマージを除去することができる。しかしながらアンローリングは、ＡＬＵの利用可能性に起因して、またＩＲＡＭ６がすでに１６ビットベースであるという事実に起因して２回のアンローリングに制限される。１回のアンローリングには「１６によるシフト」およびｏｒが必要であり、これによってサイクル毎に３２ビットが書き込まれる。さらなるアンローリングはパイプラインスループットを増大させることはない。したがって本体は１回だけアンロールされてマージの１レイヤが除去されるのである。これによって２つの別個のパイプラインが得られ、各パイプラインは、マージによって直列化され、ＩＲＡＭから得られる３２ビット値の２つの８ビットスライスを処理するのである。
【０４６４】
変更したコードはつぎのようになる（アンローリングおよび分解は分かりやすくするために省略した）。
【０４６５】
【数１１０】
2005535055.tif 000140
【０４６６】
変更したデータブローグラフはつぎのようになる（アンローリングおよび分解は分かりやすくするために省略した）。
【０４６７】
【数１１１】
2005535055.tif 000141
【０４６８】
またつぎのグラフは１つのＩＲＡＭに対するネットワークの分解である。アンローリングのレベル毎の最下位レベルのマージは省略される。
【０４６９】
【数１１２】
2005535055.tif 000142
【０４７０】
【表３０】
2005535055.tif 000143
【０４７１】
５．４．５  再正規化
正規化には、入力をスキャンして最小値を求める第１のループと、この最小値をすべての要素から減算する第２のループとが含まれる。第１のループのすべての繰り返しと、第２のループのすべての繰り返しとの間ではデータに依存性がある。したがってこれらの２つのループはマージまたはパイプライン化することができない。これら個別に処理される。
【０４７２】
最小値のサーチ
第３のループは、バイトアレイにおける最小値サーチである。
【０４７３】
【表３１】
2005535055.tif 000144
【０４７４】
リダクション識別（reduction recognition）により、minmetricに対する依存関係が除去され、これによって４回のアンロールが可能になり、３２ビットのIRAM幅が利用される。３つのSHIFTおよび３つのＡＮＤ演算を使用して８ビットストリームに分解するために分解ネットワークを付け加えなければならない。ツリーバランシング（tree balancing）により、min()演算が再配分され、ツリーの高さが最小化される。
【０４７５】
【表３２】
2005535055.tif 000145
【０４７６】
またリダクション識別により、minmetricに対するループキャリードな依存関係（loop carried dependence）が除去され、これによってループタイリング、その後にアンローリングおよびジャム（jam）が可能になり、並列性が向上する。タイリングサイズに対する最大値は、１６ＩＲＡＭ／２ＩＲＡＭ ＝ ８である。定数伝播およびツリー再バランシングより、最終的なマージ表現の依存性の高さ（dependence height）が低減される。
【０４７７】
【数１１３】
2005535055.tif 000146
【０４７８】
【表３３】
2005535055.tif 000147
【０４７９】
再正規化
第４ループは、第３ループの最小値をアレイの各要素から減算する。リードモディファイライト操作を２つのＩＲＡＭに分解しなければならない。そうでなければＩＲＡＭポートのスループットが制限される。
【０４８０】
【表３４】
2005535055.tif 000148
【０４８１】
ループキャリードな依存関係はない。データサイズはバイト単位であるため、内側のループは、ＩＲＡＭのバンド幅要求を上回ることなしに４回アンロールすることができる。３２ビットストリームを４つの８ビットストリームに分解して個々の結果を共通の３２ビット結果ストリームに再結合するネットワークが挿入される。
【０４８２】
【表３５】
2005535055.tif 000149
【０４８３】
アンロールおよびジャムは、第３ループと同様にループタイリングの後、適用することができるが、ループタイリングは、分解および結合ネットワークによって使用されるＢＲＥＧによって制限される。算出されたタイリングサイズ（アンローリングファクタ）は６４ＢＲＥＧ／１２ＢＲＥＧ ＝ ５であり、これは４によって置き換えられる。それは少ないオーバーヘッドで同じスループットが得られるからである。
【０４８４】
【数１１４】
2005535055.tif 000150
【０４８５】
【表３６】
2005535055.tif 000151
【０４８６】
５．４．６  最終的なコード
最終的につぎのようなコードに到達する。
【０４８７】
【数１１５】
2005535055.tif 000152
【０４８８】
【数１１６】
2005535055.tif 000153
【０４８９】
【数１１７】
2005535055.tif 000154
【０４９０】
性能の考察
この例においてデータの局所性は高くない。各入力データ項目は、ちょうど１回読み出される。再正規化の場合だけ、new＿metricアレイが再読み出しおよび再書き込みされる。ＰＡＥアレイをフルに利用するため、（代数的な同値性を使用して依存関係を断つリダクション識別に関連して）ループタイリングを使用した。場合によっては（最小値サーチ）これにより、極めて短いベクトル長が得られる。これはコンフィギュレーションの実行時間を低減するがダメージになることはなく、またメモリ階層の最上部からＩＲＡＭへの転送時間はそのままである。関数をコールする外側のループが既知の場合、ベクトル長は増大することがある。（外側のループをアンロールして、ベクトル長を比較的長いままにすることにより、付加的なデータを使用して、ＩＲＡＭの充填度を増大させることができる）。これは、全体的なパイプラインセットアップ時間を低減することによってコンフィギュレーション性能をさらに向上させることになる。
【０４９１】
この例に対するＸＰＰの性能と、仮想的なスーパースカラＲＩＳＣアーキテクチャと比較する。ここで仮定するのは２の平均発行幅（issue width）であり、これはこのＲＩＳＣが平均して２つの演算を並行して実行することを意味する。この推計は５．４．２のソースコードに対して命令をカウントすることによって行われる。
【０４９２】
【表３７】
2005535055.tif 000155
【０４９３】
５．５  MPEG2エンコーダ／デコーダ
５．５．１  量子化／逆量子化（quant.c）
量子化ファイルには８×８マクロブロックを量子化および逆量子化するルーチンが含まれている。これらの関数はブロック間および非ブロック間に対して異なり、またさらにエンコーダはMPEG1およびMPEG2逆量子化の間で異なる。
【０４９４】
これによって全部で６つの関数が得られ、これらはすべて関数インライン化の候補である。それはこれらがここではＸＰＰの能力を使用しないからである。
【０４９５】
すべての関数は同じレイアウトを有するため（いくつかのチェック、マクロブロックで動作して量子化行列によって量子化するメインループ）、「iquant＿intra」、すなわちブロック間の逆量子化を中心に述べることにする。それはこれが、他のプロシージャにあるすべて要素を含んでいるからである（non＿intra量子化のループ本体は比較的複雑であるが、コンパイラの複雑さを増大させない）。ソースコードにおいて、mpeg1部分はすでにインライン化されている。これは、関数が静的に定義されており、それ自体に関数コールを含まないために簡単明瞭である。したがってコンパイラはこれをインライン化し、また無用関数の除去により、定義全体が取り除かれる。
【０４９６】
オリジナルコード
【０４９７】
【数１１８】
2005535055.tif 000156
【０４９８】
プロシージャ間最適化
ループ本体を解析することにより、これらがＸＰＰに容易に収容され、またここまでは資源を最大限に使用しないことがわかる。この関数はモジュールputseq.cから３回コールされる。モジュール間の関数のインライン化により、関数コールのためのコードは消滅し、関数によって置き換えられる。したがって
【０４９９】
【数１１９】
2005535055.tif 000157
のようになる。
【０５００】
基本変換
大域変数mpeg1はループ内で変わらないため、アンスイッチングにより、ｊループの外側に制御文を移動し、２つのループのネストを形成する。
【０５０１】
【数１２０】
2005535055.tif 000158
【０５０２】
さらに以下の変換を行う。すなわち、
・ピープホール最適化によって、１６による除算を右シフト４つに簡約する。ＸＰＰに対する除算を含むループ本体を考慮しないため、これは重要である。
・イディオム認識により、「飽和」コメントの後の命令文を
dst[ｉ] ＝ min(max(val, -2048), 2047)
に簡約する。
【０５０３】
並列性の増大
ここで並列性を増大させたい。プロシージャ間の値域の解析により、block＿countが値６，８または１２の値だけを取り得ることがわかった場合、ｊ−ｉループのネストは、アンロールおよびジャムの候補である。したがってその値域[６，１２]であり、２で割り切れるという付加的な属性を伴う。このため、ファクタ２によるアンロールおよびジャムが適用可能である（資源の制約によってより大きな値が選択されることがある）。ループキャリードな依存関係は存在しないため、この変換は安全である。
【０５０４】
すなわちこのソースコードは、第１の繰り返しの手動によるピール（peel）を強要するのである。第１ブロック値に対して計算される値は、他の繰り返しとは全く異なり、またこのループの制御文は伝統的なプロセッサにおいて性能低下を起こす主因であるため、このピーリングは行わなくてはならない。これはアンロールおよびジャムを妨げないが（それは第１の繰り返しのピールされたものと、このループの残りとの間に依存関係がないからである）、変換がこのようなケースを扱えるように準備する必要がある。
【０５０５】
アンロールおよびジャムの後、ソースコードはつぎのようになる（ネストのうちの１つだけが示されており、ピールされた第１の繰り返しは前に移動されている）。
【０５０６】
【数１２１】
2005535055.tif 000159
【０５０７】
さらなる並列性はインデックス集合の分解によって得られる。ＤＤＧにおいてサイクルの依存関係を断つためにふつうに使用されるように、これをここで使用して、ｉループを２つに分解して、２つのサブコンフィギュレーション（サブコンフィギュレーションは、互いに干渉しない独立したネットワークを制約するコンフィギュレーションに対する一時的な名称として選択したものである）がデータの相異なるブロックに作用するようにすることができる。したがってｉループは２つ以上のループに分解され、これらはデータの相異なる部分集合に同時に作用する。
【０５０８】
データタイプの処理
ＦＩＲフィルタ、エッジ検出器およびマトリクス乗算ベンチマークはすべて、ＸＰＰに完全に適合するデータタイプを使用する（ＸＰＰアーキテクチャデータビット幅になるようにｉｎｔのサイズを選択したと仮定する。その他はいずれも有利な結果に結び付かない）が、これとは異なり、MPEG2コーデックではデスクトップアプリケーション用のプロセッサによく使用されるすべてのデータタイプが使用される。Intelのｘ８６およびこれに相当するアーキテクチャについていうと、ｃｈａｒ，shortおよびｉｎｔのサイズはそれぞれ８，１６および３２である。ＸＰＰが３２のビット幅を有すると仮定すると、より小さなデータタイプに対して対策を講じなければならない。
【０５０９】
このため、各パケットがより短いデータタイプの２個または４個の値を含むデータパケットのストリームを２つまたは４つのストリームに分解する。十分な資源が残っていれば、これによって性能が低下することはない。分割されたストリームの各々はそれ自体の計算ネットワークに送信されるため、各サイクルで２つのshortまたは４つのｃｈａｒの値が処理される。しかしながらこれによってエリアが犠牲になる。それはしばしば必要であるように分解−マージされる要素の他に全体的なデータフローグラフを複写しなければならないからである。以下ではshort値がどのように処理されかが示されている。このパケットは、シフト演算によってハイ部分とロー部分とに分解され、計算分岐の後、マージされる。この変換が正当であることは、アーキテクチャデータタイプよりも小さいデータタイプと同じ大きさのアンローリングファクタでのループアンローリングによる変換が正当であるのと同じである。
【０５１０】
残念ながらこれで終わりではない。さらにコンパイラは、より短いデータタイプに対してオーバ／アンダーフローを形成する各中間結果が、より大きなデータタイプと同じようになることを保証しなければならないのである。このためにはクリッピング演算を挿入なければならず、このクリッピング演算により、このネットワークが真の１６または８ビット値でそれぞれ計算することを保証する。
【０５１１】
【数１２２】
2005535055.tif 000160
【０５１２】
コンフィギュレーションサイズによってループ本体全体を複写できないか、または依存関係によってこれが阻止される場合でも、これらの分解した値を再びマージできる可能性はある。これは当然のことながら前の解決手段に対して性能の低下を引き起こす。それはここではスループットが１（short）値／サイクルにしかならないからである。以下にはどのようにマージを行うかが示されている。２つのネットワークを介して並列に流す代わりに値は直列化されて、このネットワークの後、再び非直列化される。
【０５１３】
【数１２３】
2005535055.tif 000161
【０５１４】
５．５．２  逆離散コサイン変換（idct.c）
ｉｄｃｔアルゴリズムは、MPEG2ビデオ伸張アルゴリズムに使用される。これは周波数表現のビデオ画像の８×８ブロックに作用して、これらをオリジナルの信号の形態に逆変換する。MPEG2デコーダは変換関数を含んでおり、この関数は、周波数変換された画像のすべてのブロックに対して、オリジナルのイメージを復元するためｉｄｃｔをコールする。
【０５１５】
ｉｄｃｔ関数は２つのｆｏｒループからなる。第１のループはidctrowをコールし、第２のループはidctcolをコールする。全体的なループのネスト構造内で関数のインライン化が可能であり、これによって関数コールが消去されるため、もはや数字コードが関数コールによって中断されることがない。ループのネストの間で関数コールを除去する別のやり方は、呼び出し側から呼び出し先にループを押し出すループ埋め込み（loop embedding）である。
【０５１６】
オリジナルコード（idct.c）
【０５１７】
【数１２４】
2005535055.tif 000162
【０５１８】
第１ループはブロックの値を１行ずつ変更する。その後、変更したこのブロックはさらに１列ずつ変換される。列処理を開始できるようになる前にはすべての行を終了していなければならない。
【０５１９】
【数１２５】
2005535055.tif 000163
【０５２０】
依存関係の解析により、行処理と列処理との間の真のデータの依存関係が検出される。このため、列の処理は、すべての行が処理されるまで遅延しなければならないのである。最も内側のループ本体idctrowおよびidctcolはほぼ同じである。これらは８個の入力値（idctcolの場合は列の値またidctcolの場合は行の値）に数値計算を行う。８個の出力値が計算されて（列／行として）書き戻される。idctcolは、値を書き戻す前に付加的にクリッピングを適用する。これがidctcolを中心に述べる理由である。
【０５２１】
【数１２６】
2005535055.tif 000164
【０５２２】
【数１２７】
2005535055.tif 000165
【０５２３】
Ｗ１〜Ｗ７は、プリプロセッサによって置き換えられる数値定数に対するマクロである。ｉｃｌｐアレイは、結果を８ビット値にクリッピングするのに使用される。これは、ｉｄｃｔが最初にコールされる前にinit＿idct関数によって完全に定義される。
【０５２４】
【数１２８】
2005535055.tif 000166
【０５２５】
特殊なタイプのイディオム認識（関数識別）は、ＸＰＰにおいて効率的に実現できる、コンパイラに既知の関数により、各アレイ要素の計算を置き換えることができる。コンパイラが全体プログラムメモリエイリアシング解析を備えている場合、ｉｃｌｐアレイのすべての使用を、コンパイラに既知の関数のコールで置き換えることできる。択一的には開発者が、コンパイラに既知のsaturation関数コールにより、ｉｃｌｐアレイアクセスを手動で置き換えることができる。２つのＡＬＵを使用したsaturate(val,n)に対する実現例をつぎにＮＭＬ回路図で示す。この場合、ｉｃｌｐ[ｉ]のようなアレイアクセスをsaturate(i,256)によって置き換えることができる。
【０５２６】
【数１２９】
2005535055.tif 000167
【０５２７】
idctcolにおける／＊ショートカット＊／のコードは、ｘ１〜ｘ７がゼロの場合、列処理を高速化する。これによって、ループのネストの適切に形成された構造が切り離される。ｉｆ条件は、ループ不変でなく、ループアンスイッチングは適用できない。しかしながらそれにもかかわらず、ショートカット処理の後のコードはＸＰＰに有利である。ＸＰＰに対してｉｆ条件を合成することができる（２つのブロックの推測的な処理および条件に基づく選択）が、これはＰＡＥを無駄にするだけであり、性能上の利益が得られることはない。したがってidctrowおよびidctcolにおける／＊ショートカット＊／のコードは、手動で除去しなければならない。つぎのコードの断片は、ＸＰＰ制御に対する付加的なキャッシュ命令によるidctrowループのインライン化バージョンを示している。
【０５２８】
【数１３０】
2005535055.tif 000168
【０５２９】
ＸＰＰのコンフィギュレーションはループ実行中に変化しないため、不変コードの移動により、XPPPreload(IDCTROW＿CONFIG)がループから外に移動される。
【０５３０】
ＮＭＬコード生成
データフローグラフ
計算の終わりのクリッピングに起因してidctcolはより複雑であるため、データフローグラフ表現に対する代表的なループ本体としてidctcolを採用することにした。
【０５３１】
つぎのグラフはIDCTCOLUMN＿CONFIGに対するデータフローグラフを示している。ヒューリスティックな手法をこのグラフに適用して、ＸＰＰにおいて必要な資源を推測しなければならない。この例ではヒューリスティックな手法により、つぎの結果が得られる。
【０５３２】
【表３８】
2005535055.tif 000169
【０５３３】
有利なことにこのデータフローグラフはXPP64に収容でき、ループ分離（loop dissevering  ループ本体を適切な断片に分解すること。XPP-VC: A C Compiler with Temporal Partioning for the PACT-XPP Architecture, J.M.P.Cardoso and Markus Weinhardt）なしに続行することができる。
【０５３４】
【数１３１】
2005535055.tif 000170
【０５３５】
アドレス生成
ループ本体を完全に合成するためには、データアクセスに対するアドレス生成の問題に対処しなければならない。
【０５３６】
IDCTCOLUMN＿CONFIGに対して各行のｎ番目の要素、つまり（０，８，１６〜１，９，１７〜７，１５，２３〜）のアドレスの並びを選択しなければならない。このようにアドレス生成するために２つのカウンタマクロを使用する。上側のカウンタは８つずつインクリメントし、下側のカウンタは１つずつインクリメントする。ＩＲＡＭの出力はIDCTCOLUMNのデータフローグラフに転送される。１つの列のすべての（８つの）行要素が利用可能な場合、ＳＷＡＰはデータフローグラフの入力側にスイッチスルーされて新しい列に対する計算が開始される。
【０５３７】
【数１３２】
2005535055.tif 000171
【０５３８】
IDCTROW＿CONFIGに対してアドレス生成は極めて簡単である。それはＩＲＡＭがすでに適切な順序でブロックを（アクセスしなければならない順序で１行１行）含んでいるからである。ここでもＸＰＰチュートリアルに記載したＳＩＵＰ（stepped iterative up）カウンタマクロを使用することにより、線形のアドレス表現をＮＭＬコードに一般的な手法でマッピングすることができる。IDCTROW＿CONFIGが２次元アレイをアクセスするとき、相応するＮＭＬコードにおいて２つのＳＩＵＰカウンタが必要である。列要素は１行１行でアクセスして、上側のカウンタのインクリメントが１であり、下側のカウンタのインクリメントが８であるようにしなければならない。しかしながらこのアクセスパターン（０〜５，６，７７，８，９〜６３）に対するＮＭＬコードを簡約して、単一のカウンタにする（またはＦＩＦＯモードのＩＲＡＭアクセスにする）ことができる。
【０５３９】
書き込みアクセスに対するアドレス生成も同じように実現される。この付加的なコードを考慮するために資源を更新しなければならない。最悪のケースではこれには２＊（８＋８＋２＊１）個のＦＲＥＧと、さらに２＊（２＋１）個のＢＲＥＧが必要であるが、これはＸＰＰにおいてなお利用可能である。
【０５４０】
ＩＲＡＭの使用がクリティカルでない場合、データを複数のＩＲＡＭに分散して、ＸＰＰアレイへのメモリスループットを改善することができる。このタスクはＲＩＳＣコアまたはより洗練されたＸＰＰキャッシュコントローラによって行わなければならない。
【０５４１】
ＸＰＰ利用のさらなる拡張
冒頭に述べたようにｉｄｃｔは、ビデオイメージのすべてのデータブロックに対してコールされる（transform.cにおけるループ）。この状況により、ＸＰＰの利用をさらに改善することができる。
【０５４２】
idctcolのデータフローグラフを詳細に見ると、これが極めて深いパイプラインを形成することがわかる。IDCTROW＿CONFIGがＸＰＰにおいて８回だけ動作することに着目すると、ここの実施例において最適以下のものがあることが明らかである。ここでこれは、６４個の要素（１列の８個の要素×８）だけがこのパイプラインを介して処理されることと、つぎにＸＰＰコンフィギュレーションをIDCTCOLUMN＿CONFIGコンフィギュレーションに変更して列処理を継続できる前にすべてのデータがパイプラインを離れるまで待機しなければならないこととを意味する。
【０５４３】
問題（パイプラインデプス）
上記のパイプラインは、８行×８だけを処理するのには深すぎる。わずかなデータだけを処理する場合、深いパイプラインの充填およびフラッシュは無駄である。はじめのうちパイプラインの終わりにあるユニットはアイドル状態であり、その後パイプラインのはじめにあるユニットは使用されないのである。
【０５４４】
【数１３３】
2005535055.tif 000172
【０５４５】
解決手段（ループタイリング）
ループの入れ替え（loop interchange）を使用して、行および列処理の間の依存関係をループのネストの外側のレベルに移動することは有利である。イメージの複数のブロックにおいて（transform.cの）ｉｄｃｔ関数をコールするループは、ループの入れ替えを妨げる依存関係を有しない。したがってこのループは、列および行処理のループ内に移動することができる。
【０５４６】
【数１３４】
2005535055.tif 000173
【０５４７】
いまや行および列の処理は（ループタイリングを適用することによって）より多くのデータに適用することができ、したがってパイプラインの充填およびフラッシュは無視することができる。
【０５４８】
制約（キャッシュセンシティブなループタイリング）
IDCTCOLUMN＿CONFIGによって処理されるブロックの数を決める場合にキャッシング階層を考慮しなければならない。後続のIDCTCOLUMN＿CONFIGコンフィギュレーションにおいて同じブロックが必要であることを思い起こされたい。IDCTROW＿CONFIG中に処理されるすべてのブロックがキャッシュに収まるようにしなければならない。ループタイリングはキャッシュサイズを基準に適用して、処理されたデータがこのキャッシュに収まるようにしなければならない。
【０５４９】
相異なるコンフィギュレーション間でのＩＲＡＭの再利用
この例が示すのは別のバンド幅最適化であり、これは、結果的に得られ、わずかに強化されたループタイリングの別バージョンである。メモリ階層を介してデータを行処理から列処理に転送する代わりに、コンフィグＡの出力ＩＲＡＭをコンフィグＢの入力ＩＲＡＭとして使用することによってメモリインタフェースを完全にバイパスすることができる（キャッシュセンシティブなループタイリングは、キャッシュメモリだけがアクセスされるようにする）。
【０５５０】
【数１３５】
2005535055.tif 000174
【０５５１】
全手法の結集
キャッシュセンシティブなループタイリングと、ＩＲＡＭの再利用と、関数のインライン化を適用する場合、この実施例をさらに最適化することができる。
【０５５２】
最終的にｉｄｃｔ関数は、transform.cにおいて完全にインライン化される。block＿countが例えば６であり、また６４＊６個のワードがキャッシュサイズを上回らない場合、この例をつぎのように変換することができる。
【０５５３】
【数１３６】
2005535055.tif 000175
【０５５４】
IDCTROW＿CONFIGおよびIDCOLUMN＿CONFIGにおけるアドレス生成は、（ループタイリングによって発生する）処理しなければならない異なるデータブロックサイズを反映するために変更しなければならない。これは、タイル内でブロックオフセットを生成する付加的なＳＵＩＰカウンタによって実現することができる。
【０５５５】
【数１３７】
2005535055.tif 000176
【０５５６】
つぎのテーブルには、最終的な結果のIDCTROW＿CONFIGおよびIDCTCOLUMN＿CONFIGに対するアーキテクチャについてのパラメタが含まれている。これはblock＿countブロックを記憶することのできるキャッシュに依拠している。この例では２つのコンフィギュレーションが実行されるため、２回のコンフィギュレーションサイクルが必要であり、したがって総計のコンフィギュレーションサイクルは２×(block＿count×６４＋(１２＋２×８)×２)である。
【０５５７】
【表３９】
2005535055.tif 000177
【０５５８】
性能の考察
この例では、高いデータの局所性を活用することができる。つまり多くの演算が、制限されたメモリ範囲で実行されるのである。提案されるＸＰＰ解決手段の性能と、仮想的なスーパースカラＲＩＳＣアーキテクチャとを比較する。ここでは２の発行幅を仮定する。つまりこのＲＩＳＣにより、平均して２つの演算が並列に実行されるのである。
【０５５９】
【数１３８】
2005535055.tif 000178
【０５６０】
高速化は有利であるが、単一のＲＡＭから入力データをフェッチすること（つまり処理を開始する前に８個の入力を８個のサイクルで供給しなければならない）は、達成し得る高速化を極めて低下させてしまうことは明らかである。言い換えると、１サイクル当たりに８個の入力値を処理可能なパイプラインがあるが、８サイクルおきにしかこのパイプラインにロードしていないのである。これによって８個おきのパイプラインステージだけが充填されることになる。このことはつぎに示されている。
【０５６１】
【数１３９】
2005535055.tif 000179
【０５６２】
フルの利用は、パイプラインの８個の入力値を１サイクルでロードすることによってのみ達成可能である。パイプラインへのメモリスループットを改善するための簡単な解決手段は、データの複写であり、これはハードウェアの節で記載した通りである。
【０５６３】
６個の８×８ブロックを単一のＩＲＡＭにロードする代わりにXPPPreloadMultipleコマンドを使用して、８個のＩＲＡＭに同じ内容をロードする。すなわち、
XPPPreload(0, block, 64*6);  // IRAM0は64ワードを６個のブロックから受け取る
は、
XPPPreloadMultiple(0xFF, block, 64*6);   // IRAM0〜IRAM7にブロックをロード
に変更される。
【０５６４】
これでパイプラインはフルに利用され、また１サイクル当たり８個の結果を記憶しなければならない。これは各出力値を別のＩＲＡＭに書き込むことによって達成され、ここでこの別のＩＲＡＭは付加的にさらに８個のＩＲＡＭを利用する（この例のデータの複写を使用するためにはXPP64の１６個のＩＲＡＭがすべて必要である）。IDCTROW＿CONFIGによって生成されるデータを記憶するためにつぎのように変更しなければならない。すなわち、
XPPPreloadClean(1,block,64*6); // IRAM1を消去して６ブロックに割り当てる
を
【０５６５】
【数１４０】
2005535055.tif 000180
に変更しなければならないのである。
【０５６６】
これによって中間結果に対して相異なるデータレイアウトが発生する。オリジナルのデータレータレイアウトを復元するため付加的なコンフィギュレーション（REORDER＿CONFIG）が必要である。
【０５６７】
【数１４１】
2005535055.tif 000181
【０５６８】
ここでもアドレス生成を変更して１サイクル当たりに８個の入力値をフェッチしなければならない。このために７個の付加的な加算器が必要であるが、データを８サイクル保持するためのスワップおよびラッチは省略される。
【０５６９】
データ複写およびデータ並び替えにより、最終的にこの例のコードはつぎのように変換される。
【０５７０】
【数１４２】
2005535055.tif 000182
【０５７１】
５．６  ウェーブレット
５．６．１  オリジナルコード
【０５７２】
【数１４３】
2005535055.tif 000183
【０５７３】
【数１４４】
2005535055.tif 000184
【０５７４】
５．６．２  全体ループネストの最適化
前処理およびs＿tmp1，d＿tmp1によって定数伝播を適用した後、以下のループのネストが得られる。
【０５７５】
【数１４５】
2005535055.tif 000185
【０５７６】
【数１４６】
2005535055.tif 000186
【０５７７】
この場合に最も内側のループ毎に１つずつの４つのテーブルが得られる。第１および第３のループに対するテーブルは同じであり、また第２および第４のループに対するテーブルは同じである。したがってつぎの２つのテーブルが得られる。
【０５７８】
【表４０】
2005535055.tif 000187
【０５７９】
内側の２つのループは、同じ繰り返し範囲を有さず、ループ融合の候補である。したがって第２のループの最初および最後の繰り返しをピールオフする。２つのループの間の周囲のコードは、第２ループの後に移動することできる。この場合、上記のループのネストに対して以下のコードが得られる。
【０５８０】
【数１４７】
2005535055.tif 000188
【０５８１】
【数１４８】
2005535055.tif 000189
【０５８２】
ループピーリングの後、パラメタの変更はベクトル長だけである。テーブルはつぎのようになる。
【０５８３】
【表４１】
2005535055.tif 000190
【０５８４】
内側のループの融合は正当である。それは前に第２ループに存在した命令と、前に第１ループに存在した命令との間にループキャリードな依存関係がないからである。以下のループのネストが得られる。
【０５８５】
【数１４９】
2005535055.tif 000191
【０５８６】
【数１５０】
2005535055.tif 000192
【０５８７】
ループ融合の後、同じパラメタテーブルを有する２つのループだけになる。
【０５８８】
【表４２】
2005535055.tif 000193
【０５８９】
値域の解析を行うと、コンパイラにはｎｔが値６４，３２および１６をとることがわかる。内側のループの上限はｍｉｄであり、これはｎｔの値に依存する。つぎにこの解析により、ｍｉｄが値３１，１５および７をとり得ることがわかる。定数のループ限界値を有するループは、ＰＡＣＴ  ＸＰＰにおいてより効率的に処理することができる。すなわち、ｍｉｄが定数値で置き換えられる場合、内側のループをより良好に最適化できるということである。これが発生するのは、外側のループがアンロールされる場合である。これにより、ループのネストの３つのインスタンスを有するより大きなコードが得られるが、これらインスタンスはそれぞれがコンフィギュレーションの候補である、これは一種の一時的なパーティショニングとみなすことができる。したがって外側のループは完全にアンロールされ、新たな６つのループのネストが得られる。
【０５９０】
【数１５１】
2005535055.tif 000194
【０５９１】
【数１５２】
2005535055.tif 000195
【０５９２】
【数１５３】
2005535055.tif 000196
【０５９３】
【数１５４】
2005535055.tif 000197
【０５９４】
【数１５５】
2005535055.tif 000198
【０５９５】
パラメタテーブルにおいて変化する値はベクトル長だけである。最初の２つのループに対してこれを示す。他のループに対するテーブルを得るためには、ベクトル長をそれぞれ１４および６に設定しなければならない。
【０５９６】
【表４３】
2005535055.tif 000199
【０５９７】
５．６．３  内側ループの最適化
つぎに内側の６つのループに集中する。実際にこれらのループを見ると、これらはすべて２つの入力データを必要とし、４つのデータを出力する。第１の繰り返しにさらに２つのデータが必要である。それゆえに最大８つのＩＲＡＭが第１の繰り返しに必要であり、また６つのＩＲＡＭが他の繰り返しに必要である。すなわち、これらのループを２回アンロールできることであり、この際に新しいループ本体の繰り返し毎に１４個のＩＲＡＭが必要である。以下にアンロールした内側のループだけを便宜上示す。
【０５９８】
第１ループ
【０５９９】
【数１５６】
2005535055.tif 000200
【０６００】
第２ループ
【０６０１】
【数１５７】
2005535055.tif 000201
【０６０２】
第３ループ
【０６０３】
【数１５８】
2005535055.tif 000202
【０６０４】
第４ループ
【０６０５】
【数１５９】
2005535055.tif 000203
【０６０６】
第５ループ
【０６０７】
【数１６０】
2005535055.tif 000204
【０６０８】
第６ループ
【０６０９】
【数１６１】
2005535055.tif 000205
【０６１０】
ツリーバランシングのステップを実行した後、これらのループ本体のつぎのデータフローグラフが得られる。ここでは第１ループに相応するグラフだけを示す。他のループに対するグラフを得るためには、入力および出力データだけを変更すればよい。
【０６１１】
【数１６２】
2005535055.tif 000206
【０６１２】
各入力および出力データは１つのＩＲＡＭを占有する。ｄ０およびｓ０だけがこれらのＩＲＡＭにおける値であり、したがってこの場合にマージ操作は、第１の繰り返しのｄ０ないしはｓ０と、他の繰り返しのフィードバック値との間で選択することができる。一旦パイプラインが充填されると、８個の値を１サイクルで出力することができる。これはアレイｘに対する４個の値に相応する。同じコンフィギュレーションがすべてのループに対して使用され、ＩＲＡＭにおけるデータが異なるだけである。最初の２つのループに対してだけ、結果として得られるテーブルを示す。他のテーブルも同じである。
【０６１３】
最初の２つのループに対してつぎのテーブルが得られる。またサイクル当たりに２命令が発行される標準のスーパースカラプロセッサを基準にした、予想の高速化は１５．３である。
【０６１４】
【表４４】
2005535055.tif 000207
【０６１５】
参考
慣用のプロセッサの限界はますます明らかになりつつある。ストリームベースのアプリケーションの重要性が増すことによって、粗粒度の動的リコンフィギュレーションアーキテクチャは魅力的な択一的選択肢になっている[３]，[４]，[６]，[７]。これらは、極めてリスクがありまた高価（開発およびマスクコスト）なＡＳＩＣの性能と、伝統的なプロセッサのフレキシビリティとを兼ね備えている[５]。
【０６１６】
様々な可能性があるのにもかかわらず、今日のＶＬＳＩ開発においてマイクロプロセッサアーキテクチャの基本コンセプトは２０年前と同じである。実際の構造における今日慣用のマイクロプロセッサのメイン処理ユニット、データパスは、その先行モデルと同じスタイルの指針にしたがっている。データおよび命令キャッシュと組み合わせたスーパースカラコンセプトおよびパイプライン化アーキテクチャの開発により、今日のマイクロプロセッサの性能は増大し、高い周波数レートが可能になったが、静的なデータパスの基本コンセプトはそのままである。したがって各演算は、使用するプロセッサが有する基本命令の組合せである。プロセッサコンセプトの利点は、制御が極めて支配的なアプリケーションを実行できることである。データまたはストリーム指向のアプリケーションは、この環境には適していない。順次の命令実行は、この種のアプリケーションの正しいターゲットではなく、またメモリからおよびメモリに命令／データを永続的に再転送するため、広いバンド幅が必要である。このようなハンディキャップは、さまざまな段階でキャッシュを使用することによって緩和されることが多い。中間結果を書き戻すことなしに相応にデータを操作するフィルタを順次に相互接続することにより、適切な最適化およびバンド幅の低減が得られる。実践的にはこのようなフィルタのチェーンは、論理的な手法で構成し、またランタイム時にコンフィギュレーションすべきである。命令セットを拡張する既存のアプローチは、ランタイム時に変更できないスタティックなモジュールを使用する。カスタマイズ式のマイクロプロセッサまたはＡＳＩＣは、特定の１アプリケーション環境用に最適化される。このアーキテクチャの性能利得を損なうことなく同じマイクロプロセッサコアを別のアプリケーションに使用することはほとんど不可能である。
【０６１７】
ストリームベースのアプリケーションに必要な性能を損なうことなく、機能をリコンフィギュレーションすることができ、またこのコアを概してアプリケーションに依存しないようにすることのできるフレキシブルかつ高性能のデータパスコンセプトの新たなアプローチが必要である。
【０６１８】
本発明は、ＰＡＣＴ社の動的リコンフィギュラブルＸＰＰアーキテクチャと、ＳＰＡＲＣ互換ＬＥＯＮプロセッサの静的なデータパスとの疎結合の実現という新しいコンセプトに関するものである。したがって、このアプローチは、ＸＰＰが１つのコンフィギュラブルシステムオンチップ（ＣｓｏＣ Configurable System-on-Chip）内で完全に独立した（マスタ）コンポーネントとして、プロセッサコアと、グローバル／ローカルメモリトポロジと、効率的なマルチレイヤＡｍｂａバスインタフェース[１１]と共に動作するアプローチとは異なるのである。プログラマから見ると、拡張かつ適合されたこのデータパスは、動的にコンフィギュラブルな命令セットのように見える。これは特定のアプリケーション向けにカスタマイズすることができ、実行を格段に加速することができる。このため、プログラマは、ランタイムにＸＰＰアレイにアップロートできる数多くのコンフィギュレーションを作成しなければならない。例えばこのコンフィギュレーションは、ストリーム指向のデータを計算するフィルタのように使用することができる。また、同時に複数の機能をコンフィギュレーションして、これらを並行して使用することができる。このコンセプトにより、性能の格段の向上と、所要のフレキシビリティと、パワーの低減とが約束され、一連のアプリケーションが極めて効率的に実行される。
【０６１９】
６．２  １．ＬＥＯＮ  ＲＩＳＣマイクロプロセッサ
このコンセプトを実現するために、３２ビットのＳＰＡＲＣ Ｖ８互換のマイクロプロセッサ[１]，[２]，すなわちＬＥＯＮを選択した。このマイクロプロセッサは、フリーで利用可能なシンセサイザブルＶＨＤＬモデルであり、 これはロード／ストアアーキテクチャを有しており、別個の命令およびデータキャッシュを有する５段階のパイプラインが実装されている。
【０６２０】
【数１６３】
2005535055.tif 000208
【０６２１】
ここに示したようにＬＥＯＮは、ＡＭＢＡ２．０  ＡＨＢおよびＡＰＢオンチップバスと、ハードウェア乗算器および除算器と、外部ＰＲＯＭ、スタティックＲＡＭおよびSDRAMに対するプログラマブル８／１６／３２ビットメモリコントローラと、タイマ、ＵＡＲＴ、割り込みコントローラおよび１６ビットＩ／Ｏポートなどのいくつかのオンチップ周辺装置とが完全に実装されている。簡単なパワーダウンモードも実装されている。
【０６２２】
ＬＥＯＮは、将来の宇宙ミッションのために欧州宇宙機関（ＥＳＡ European Space Agency）によって開発されている。ＬＥＯＮの性能は、ＡＲＭ９シリーズに近いが、メモリ管理ユニット（ＭＭＵ）が実装されおらず、これにより、その使用が単一メモリ空間アプリケーションに限定される。ＬＥＯＮ整数ユニットのデータパスをつぎに示す。
【０６２３】
【数１６４】
2005535055.tif 000209
【０６２４】
２．ＸＰＰ（eXtreme Processing Platform）
ＸＰＰアーキテクチャ[６]，[７]，[８]は、パケット指向通信ネットワークおよびＰＡＥ（Processing Array Element）と称される粗粒度の適応形計算素子の階層アレイに基づいている。ＸＰＰテクノロジの利点は、アレイ処理と、ユニークで強力なランタイムリコンフィギュレーションメカニズムとの組合せから生じる。コンフィギュレーションコントロールは、アレイに埋め込まれたコンフィギュレーションマネージャ（ＣＭ Configuration Manager）によって分散されるため、隣のＰＡＥがデータを処理している間に別のＰＡＥを並列に高速にコンフィギュレーションすることができる。アプリケーション全体をコンフィギュレーションして、アレイの別の部分で独立に実行することができる。リコンフィギュレーションは外部的にトリガされるか、またはアレイ内で発生する専用のイベント信号によってトリガされることもあり、これによって自己リコンフィギュレーション式の設計も可能である。ハードウェアに実現されるプロトコルを利用することにより、データおよびイベントパケットが使用されて、データのストリームが処理、生成、分解およびマージされる。
【０６２５】
ＸＰＰにはストリームベースのアプリケーション用に専用に設計されたKressArray[３]またはRaw Machines[４]などの他の粗粒度のリコンフィギュラブルアーキテクチャといくつか類似点がある。ＸＰＰを他と差別化する主な機能は、その自動パケットハンドリングメカニズムおよびランタイムおよび自己リコンフィギュレーションのための洗練された階層コンフィギュレーションプロトコルである。
【０６２６】
６．２．１  ２．１  アレイ構造
ＣＭはステートマシンと、コンフィギュレーションキャッシングのための内部的なＲＡＭとから構成される。ＰＡＣそれ自体（つぎに示した構造の最上部右側を参照されたい）は、ＣＭと、ＰＡＥおよび別のコンフィギュラブルなオブジェクトとを接続するコンフィギュレーションパスを含む。水平方向のバスはデータおよびイベントを搬送する。これはコンフィギュラブルなスイッチオブジェクトによってセグメント化して、このデバイスの周辺のＰＡＥおよび専用のＩ／Ｏオブジェクトに接続することができる。
【０６２７】
ＰＡＥは、ＰＡＥオブジェクトの集まりである。つぎに示した構造の典型的なＰＡＥ（最下部）は、垂直方向のルーティングに使用されるＢＲＥＧオブジェクト（バックレジスタ）およびＦＲＥＧオブジェクト（フォワードレジスタ）ならびに実際の計算を実行するＡＬＵオブジェクトを含んでいる。このＡＬＵは、ふつうの固定小数点算術演算と、論理演算と、乗算加算、ソートおよびカウンタなどのいくつかの固有の３入力オペコードとを実行する。ＡＬＵオブジェクトによって生成されるイベントは、ＡＬＵの結果または例外処理に依存しており、古典的なマイクロプロセッサのステートフラグに極めて類似している。例えばカウンタは、それが終了した後にだけ固有のイベントを生成する。つぎの節ではこれらのイベントがどのように使用されるかを説明する。ＸＰＰに実装されている別のＰＡＥオブジェクトは、メモリオブジェクトであり、これはＦＩＦＯモードにおいて、またはルックアップテーブル、中間結果などに対するＲＡＭとして使用することができる。しかしながらＸＰＰアーキテクチャには任意のＰＡＥオブジェクト機能を含めることができる。
【０６２８】
【数１６５】
2005535055.tif 000210
【０６２９】
６．２．２
６．２．３  ２．２  パケットハンドリングおよび同期化
上に定義したＰＡＥオブジェクトは、パケット指向のネットワークを介して通信する。２つのタイプのパケット、すなわちデータパケットおよびイベントパケットがアレイを介して送信される。データパケットは、デバイスタイプの固有の一定のビット幅を有する。通常の動作モードでは、ＰＡＥオブジェクトは自己同期的である。演算は、必要なデータ入力パケットが利用可能になるとただちに実行される。前の結果が消耗されたことを前提とすると、結果はそれが利用可能になるとただちに転送される。したがってシグナルフローグラフをＡＬＵオブジェクトに直接マッピングすることができる。イベントパケットは１ビット幅である。これらはＡＬＵの実行およびパケット生成をコントロールするステート情報を伝送する。
【０６３０】
６．２．４  ２．３  コンフィギュレーション
各ＰＡＥはローカルにその現在のコンフィギュレーション状態、すなわちそれがコンフィギュレーションの一部をなしているか否か（状態「コンフィギュレーションされている」または「フリーである」）を記憶している。ＰＡＥが一旦コンフィギュレーションされると、このＰＡＥはその状態を「コンフィギュレーションされている」に変更する。これにより、まだ別のアプリケーションによって使用されているＰＡＥをＣＭがリコンフィギュレーションしてしまうことを回避する。ＣＭは、必要なＰＡＥが利用可能になるまでコンフィギュレーションデータをその内部ＲＡＭにキャッシュする。
【０６３１】
コンフィギュレーションをロードする間、すべてのＰＡＥは、状態「コンフィギュレーションされている」になると直ちにそのアプリケーション担当分を計算し始める。部分的にコンフィギュレーションされているアプリケーションは、パケットを失うことなくデータを処理することができる。コンフィギュレーションおよび計算の並行処理により、コンフィギュレーションの遅延が隠される。
【０６３２】
６．２．５  ２．４  ＸＰＰアプリケーションマッピング
リコンフィギュレーションプリミティブを備え、ＰＡＣＴ社が所有権を有する構造言語、ＮＭＬ（Native Mapping Language）は、アプリケーションをＸＰＰアレイにマッピングするためにＰＡＣＴによって開発されたものものである。この言語により、プログラマはすべてのハードウェア機能に直接、アクセスすることができる。
【０６３３】
ＮＭＬではコンフィギュレーションはモジュールからなり、これらのモジュールは、構造ハードウェア記述言語、例えば構造化ＶＨＤＬにおけるのと同様に指定される。ＰＡＥオブジェクトは明示的に割り当てられ、オプションで配置され、またそれらの接続が指定される。階層的なモジュールにより、殊に繰り返しのレイアウトに対してコンポーネントの再利用が可能になる。さらにＮＭＬにはコンフィギュレーションハンドリングをサポートするためのステートメントが含まれる。完備したＮＭＬアプリケーションプログラムは１つまたは複数のモジュールと、初期にコンフィギュレーションされたモジュールのシーケンスと、差分変更と、プリフェッチ要求およびコンフィギュレーションにイベント信号をマッピングするステートメントとからなる。したがってコンフィギュレーションハンドリングは、アプリケーションプログラムの明示的な部分なのである。
【０６３４】
完備したＸＰＰ開発スーツ（ＸＤＳ  XPP Development Suite）はＰＡＣＴから入手可能である。ＸＰＰベースのアーキテクチャおよび開発ツールについては[６]を参照されたい。
【０６３５】
６．３  ３．  ＬＥＯＮ命令データパス拡張
システムを設計して最大限の性能が得られるようにする。ＬＥＯＮとＸＰＰとは単純かつ高性能に相互に通信可能でなければならない。ＸＰＰはデータフロー指向のデバイスであるのに対して、ＬＥＯＮはコントロールフローをハンドリングするのに適した汎用のプロセッサである[１]，[２]。したがってＬＥＯＮをシステムコントロールに使用する。これを行うため、ＸＰＰをコントロールすることのできるＬＥＯＮ整数ユニットのデータパスにＸＰＰを組み込む。
【０６３６】
【数１６６】
2005535055.tif 000211
【０６３７】
ＸＰＰアルゴリズムの演算時間は予想できないため、ＬＥＯＮデータパスへのＸＰＰの組み込みは疎結合で行われる（上に示した拡張データパスの概要を参照されたい）。したがってＸＰＰアレイはＬＥＯＮには依存しないで動作することができ、ＬＥＯＮはランタイムにＸＰＰをコントロールしてリコンフィギュレーションすることができる。ＸＰＰのコンフィギュレーションはレオンによって処理されるため、ＸＰＰのＣＭは不要であり、ＸＰＰアレイから省くことができる。コンフィギュレーションコードは、ＬＥＯＮのＲＡＭに記憶される。ＬＥＯＮは、所要のコンフィギュレーションをそのシステムＲＡＭからＸＰＰに転送して所要のアルゴリズムを配列に形成する。
【０６３８】
ＸＰＰを最大限にＬＥＯＮから独立させるため、デュアルクロックＦＩＦＯを使用してＸＰＰのすべてのポートを（入力ポートも出力ポートも）バッファリングする。デュアルクロックＦＩＦＯは、ＬＥＯＮとＸＰＰとの間のＩＯポートに実装される。この拡張されたＸＰＰベースのデータパスにデータを伝送するため、データはつぎの「ＬＥＯＮからＸＰＰへのデュアルクロックＦＩＦＯ」に示したようにＩＯポートを介して渡される。このＦＩＦＯに加えてこれらのＩＯポートは、ハンドシェーク信号および割り込み要求信号を生成するロジックを含む。ＸＰＰからデータを受信するためのＩＯポートは、データ信号の方向が逆であることを除いて「ＬＥＯＮからＸＰＰへのデュアルクロックＦＩＦＯ」と同様である。これにより、入力ポートＦＩＦＯにおいて入力データが利用可能であり、また出力ポートＦＩＦＯにおいて結果データに対するフリースペースが利用可能でありさえすれば、ＸＰＰはＬＥＯＮから完全に独立して動作することができる。ＬＥＯＮパイプラインに実現される付加的な機能は数多くあり、これによってＬＥＯＮとＸＰＰとの間のデータ伝送が制御される。
【０６３９】
【数１６７】
2005535055.tif 000212
【０６４０】
ＬＥＯＮがフルのＦＩＦＯを含むＩＯポートに書き込もうとする場合または空のＦＩＦＯを含むＩＯポートから読み出そうとする場合、トラップが生成される。このトラップはトラップハンドラによって処理することができる。ここではさらに別のメカニズム（パイプラインホールディング）が実現されており、これによってＬＥＯＮは、パイプラインをホールドして、ＸＰＰの書き込みアクセス中にＦＩＦＯのスペースが空くのを待機する、ないしはＸＰＰの読み出しアクセス中に有効なＦＩＦＯ値を待機することができる。パイプラインホールディングを使用する場合、ソフトウェア開発者は、ＸＰＰないしはＸＰＰ入力ＩＯポートがデータを含まず、出力を形成しないうちに、空のＦＩＦＯを有するＩＯポートから読み出すことを回避しなければならない。読み出した場合、デッドロックが発生して、システム全体をリセットしなければならない。
【０６４１】
空のＦＩＦＯポートから値を読み出す、またはフルのＦＩＦＯポートに値を書き込もうとする場合、ＸＰＰはＬＥＯＮに対して割り込みを生成することができる。割り込みの発生は、ＸＰＰアレイがつぎのステップを処理できないことを示している。それはこれが入力値を有しないか、または結果の値を出力できないからである。ＸＰＰによって生成されるこれらの割り込みはマスク可能である。
【０６４２】
上記のインタフェースにより、ＦＩＦＯについての情報が得られる。ＬＥＯＮは、ＦＩＦＯが含む有効値の数を読み出すことができる。
【０６４３】
ＸＰＰへのインタフェースは、ＬＥＯＮにとって専用レジスタの集合に見える（「拡張ＬＥＯＮ命令パイプライン」を参照されたい）。これらのＸＰＰレジスタは、通信レジスタと、ステータスレジスタとに分類することができる。
【０６４４】
【数１６８】
2005535055.tif 000213
【０６４５】
データ交換に対してはＸＰＰ通信レジスタが使用される。ＸＰＰは異なる３つのタイプの通信ポートを備えているため、３つのタイプの通信レジスタも存在しており、ここで各タイプは、入力部と出力部とに分かれている。
【０６４６】
処理に対するデータは、ＸＰＰデータレジスタを介してアクセスされる。データ入力およびデータ出力のポートの数ならびにデータビット幅は、実現されるＸＰＰアレイに依存する。ＸＰＰはイベントを生成しまた消費することができる。イベントは１ビット信号である。入力イベントおよび出力イベントの数も、実現されるＸＰＰアレイに依存する。
【０６４７】
ＸＰＰのコンフィギュレーションは、ＸＰＰコンフィギュレーションレジスタを介して行われる。ＬＥＯＮは（そのシステムＲＡＭに記憶されている）ファイルから所要のコンフィギュレーション値を読み出してこれをＸＰＰコンフィギュレーションレジスタに書き込む。
【０６４８】
ここで複数のＸＰＰステータスレジスタが実現されており、これによってインタフェースのステータス情報が得られて挙動が制御される。トラップハンドリンクの使用と、パイプラインホールディングの使用との間の切換は、ホールドレジスタにおいて行うことができる。ＸＰＰクロックレジスタは、ＬＥＯＮとＸＰＰとの間のクロック周波数比を含んでいる。このレジスタに書き込むことによってＬＥＯＮソフトウェアは、ＬＥＯＮクロックに対するＸＰＰクロックを設定することができる。これによって、ＸＰＰクロック周波数を所要のＸＰＰ性能に適合させることができ、結果的にシステムの電力消費に作用を及ぼすことができる。このＸＰＰクロックレジスタに０を書き込むことによってＸＰＰはオフにされる。最後にここではＦＩＦＯ毎にステータスレジスタがあり、これはこのＦＩＦＯにおいて実際に利用可能な有効値の数を含む。
【０６４９】
このステータスレジスタにより、ＬＥＯＮとＸＰＰとの間の通信において最大限のフレキシビリティが得られ、異なる通信手段が可能になる。すなわち、
−  このシステムでただ１つのアプリケーションが動作している場合、その時点ではソフトウェアをパイプラインホールドモードで開発することができる。ここではＬＥＯＮより、ＸＰＰからのデータの読み込みないしはＸＰＰへのデータの書き込みが開始される。読み出す値ないしは書き込む値がない場合、ＬＥＯＮパイプラインは、読み出しまたは書き込みが可能になるまで停止される。これはＬＥＯＮ側で電力消費を低減するために使用することができる。
【０６５０】
割り込みモードでは、ＸＰＰはＬＥＯＮのプログラムフローに影響を及ぼすことができる。したがってＩＯポートにより、ＦＩＦＯにおいて利用可能な値の実際の数に依存して割り込みが生成される。ＬＥＯＮとＸＰＰとの間の通信は、割り込みサービスルーチンにおいて行われる。
【０６５１】
ポーリングモードは、ＸＰＰにアクセスするための古典的な手法である。タイマイベントによって起動されて、ＬＥＯＮは、データを含むすべてのＸＰＰポートを読み出し、またフリーのＦＩＦＯスペースを含むすべてのＸＰＰポートに書き込む。これらのフェーズの間、ＬＥＯＮは別の計算を行うことができる。
【０６５２】
１アプリケーション内で上記のストラテジーの間でいつでも切り換えることができる。
【０６５３】
ＸＰＰは、アレイのコンフィギュレーションおよびリコンフィギュレーションを処理するコンフィギュレーションマネージャを含めて供給される。このコンセプトではこのコンフィギュレーションマネージャは必須ではない。それは、コンフィギュレーションならびに任意のリコンフィギュレーションは、ＸＰＰコンフィギュレーションレジスタを介し、てＬＥＯＮによって制御されるからである。アプリケーションに使用されるすべてのＸＰＰコンフィギュレーションは、ＬＥＯＮのシステムＲＡＭに記憶される。
【０６５４】
６．４  ４．ツールおよびコンパイラの統合化
ＬＥＯＮのSPARC 8命令セット[１]は、ソフトウェアを介して新しいＸＰＰレジスタにアクセスできるようにする命令の新しいサブセットの分だけ拡張されている。これらの命令は、SPARC命令フォーマットに基づいているが、SPARC V8標準には準拠していない。ロード／ストアアーキテクチャのSPARC規則に相応して、上記の命令サブセットは、２つの一般的なタイプに分けることができる。ロード／ストア命令は、ＬＥＯＮメモリと、ＸＰＰ通信レジスタとの間でデータを交換することができる。１命令当たりのサイクル数は、ＬＥＯＮの標準のロード／ストア命令と同じである。リード／ライト命令はＬＥＯＮレジスタ間の通信に使用される。ＬＥＯＮレジスタセットは、ＸＰＰレジスタの分だけ拡張されるため、リード／ライト命令もＸＰＰレジスタをアクセスするように拡張される。ステータスレジスタは、リード／ライト命令によってのみアクセス可能である。ＸＰＰレジスタにおける算術命令の実行はできない。値は、これらの値が算術命令のターゲットになる前に標準のＬＥＯＮレジスタに書き込まなければならない。
【０６５５】
全体システムは任意のSPARC V8互換モードで引き続き動作することができる。この動作を行うため、ＸＰＰは全く使用されないのである。
【０６５６】
ＬＥＯＮは、ＬＧＰＬの条項にしたがうLECCSクロスコンパイラシステム[９]を有する。このシステムは、binutils ２．１１およびｇｃｃ 2.59.2の修正バージョンから構成される。ソフトウェア開発者が上記の新しい命令サブセットを利用できるようにするため、binutilsのアセンブラは、実現される命令サブセットにしたがって複数の命令の分だけ拡張される。これらの新しい命令は、通常のSPARC V8ロード、ストア、リードおよびライト命令と同じニーモニックを有している。新しいＸＰＰレジスタだけをソースないしはターゲットオペランドとして使用するだけでよい。LECCSの変更は、簡単明快な拡張であるため、このクロスコンパイラシステムは、オリジナルバージョンに対して後方へのの互換性を有する。LECCSのソースコードが利用可能であることによって、上記のように新しいＸＰＰ動作の分だけツールを拡張することができる。
【０６５７】
ＸＰＰアルゴリズムの開発は、ＰＡＣＴ社によって供給される別のツールによって行わなければならない。
【０６５８】
６．５  ５．  結果的に得られるアプリケーション
最初の解析用アプリケーションとして、８×８のピクセルブロックに適用される逆ＤＣＴを実現した。すべてのシミュレーションに対し、ＬＥＯＮプロセッサについては２５０ＭＨｚのクロック周波数を、またＸＰＰついては５０ＭＨｚのクロック周波数を使用した。ＸＰＰを使用することにより、通信モードに依存してＩＤＣＴの計算が約４倍高速化される。しかしながらＸＰＰでＩＤＣＴを計算する前にこのＸＰＰをコンフィギュレーションしなければならない。以下の「ＩＤＣＴ（８×８）における性能」にはこのアルゴリズムに対するコンフィギュレーション時間も示されている。
【０６５９】
【表４５】
2005535055.tif 000214
【０６６０】
「ＩＤＣＴ（８×８）の計算時間」のグラフに示したように、ＸＰＰによってもたらされるメリットは、このＸＰＰによって計算される、リコンフィギュレーションの前のＩＤＣＴブロック数と共に増大する。複雑なアルゴリズム中のリコンフィギュレーションの数は最小化すべきである。
【０６６１】
【数１６９】
2005535055.tif 000215
【０６６２】
このシステムに実現される最初の複雑なアプリケーションは、MPEG-4のデコーディングである。ＬＥＯＮおよびＸＰＰへのアルゴリズム分割の最適化は、まだ作業中である。以下の「デコーダブロック」にはMPEG-4デコーディングアルゴリズムのブロック図が示されている。ここでは３２０×２４０ピクセルのフレームをデコードした。ＬＥＯＮは、SPARC V8標準命令を使用することによって、１フレームを23.46秒でデコードする。ＸＰＰを使用したMPEG-4の第１の実現では、ＩＤＣＴだけをＸＰＰで計算し、MPEG-4デコーディングの残りは引き続きＬＥＯＮで行われている。この場合、ＸＰＰのおかげで１フレームは17.86秒でデコードされる。これは２０％以上の性能向上である。現段階でＩＤＣＴアルゴリズムだけを高速化することによって得られるＸＰＰ性能利得は極めて小さいため、ハフマンデコーディング、逆量子化および予測デコーディングのＸＰＰ実現に取り組んでいる。このため、スタンドアロンのＬＥＯＮに対するこのコンセプトの性能向上は増大するはずである。
【０６６３】
【数１７０】
2005535055.tif 000216
【０６６４】
６．６  ６．結論
今日、現代のマイクロプロセッサの命令データパスは、伝統的なフォン・ノイマンまたはハーバードアーキテクチャ基本原理によって導かれた静的な命令セットを使用することによってその限界に達してしまっている。これらの限界の１打開策が、伝統的な静的データパスと、粗粒度の動的リコンフィギュラブルＸＰＰ（eXtreme Processing Platform）アーキテクチャとを統合化することによって達成される動的リコンフィギュラブルプロセッサデータパス拡張である。このために、与えられた命令データパスを疎で非同期に結合するメカニズムを開発して、ＵＭＣから得られるＣＭＯＳ ０．１３μｍ標準セルテクノロジに集積したのである。ここではSPARC互換のＬＥＯＮ ＲＩＳＣプロセッサを使用しており、その静的なパイプライン化された命令パスを拡張して、特定アプリケーション向けにコンフィギュレーションおよび個別化できるようにした。このコンパイラ互換の命令セット拡張により、例えば、MPEG-4などのストリーミングアプリケーション分野、ディジタルフィルタ、移動通信変調などのさまざまな使用および効率的な使用が可能になる。フレキシブルなデュアルクロックＦＩＦＯインタフェースによる上に示した結合テクニックにより、非同期的な並行性が可能になり、また例えば不要なサイクルを回避するおよび電力消費を低減するなどの実際の性能要件に依存して、コンフィギュレーションされるＸＰＰデータパスの周波数を適合化することができるのである。
【０６６５】
上に示したように、上記のコンセプトにより、汎用プロセッサのフレキシビリティと、ＡＳＩＣ性能にほとんど比肩し得る粗粒度リコンフィギュラブルデータパス構造の電力消費および性能とが組み合わされる。ここでは２つのプログラミングおよび計算パラダイム（制御主導のフォン・ノイマンおよび伝送トリガされるＸＰＰ）が、２つのクロック領域のオプションで１ハイブリッドアーキテクチャ内に統合化される。伝送トリガされるＸＰＰがリコンフィギュレーションできることによって、このシステムは、標準または特定のアプリケーションに依存しないようになる。このコンセプトによって開かれるのは、ソフトウェアラジオのようなマルチスタンダード通信デバイスを開発できる可能性であり、ここでこれは、適合化したプログラミングおよびコンパイルツールを有する１拡張プロセッサアーキテクチャを使用することによって行われる。したがってソフトウェアの更新によって新しい標準を簡単に実現できるのである。このシステムは、使用するＸＰＰ拡張部のスケーラブルアレイ構造によって設計中に調整可能（scalable）である。これにより、マルチメディア機能のほとんどない製品から、複雑な高性能システムまでに有利なアプリケーションの範囲が広がるのである。
【０６６６】
６．７  ７．参考文献
[1] The SPARC Architecure Manual, Version 8, SPARC international INC., 
http://www.sparc.com
[2] Jiri Gaisler: The LEON Processor User's Manual, http://www.gaisler.com
[3] R. Hartenstein, R. Kress, and H. Reinig.  A new FPGA architecture for word-oriented datapaths.  In Proc. FPL'94, Prague, Czech Republic, September 1994.  Springer LNCS 849
[4] E. Waingold, M. Taylor, D. Srikrishna, V. Sarkar, W. Lee, V. Lee, J. Kim, M. Frank and P. Finch.  Baring it all to software: Raw machines. IEEE Computer, pages 86-93, September 1997
[5] J. Becker (Invited Tutorial): Configurable Systems-on-Chip (CSoC): in: Proc. of 9th Proc. of XV Brazilian Symposium on Integrated Circuit Design (SBCCI 2002), Porto Alegre, Brazil, September 5-9, 2002
[6] PACT Corporation: http://www.pactcorp.com
[7] The XPP Communication System, PACT Corporation, Technical Report 15, 2000
[8] V. Baumgarte, F. Mayr, A. Nueckel, M. Vorbach, M. Weinhardt: PACT XPP - A Self-Reconfigurable Data Processing Architecture; The 1st Int'l Conference of Engineering of Reconfugurable Systems and Algorithms (ERSA'01), Las Vegas, NV, June 2001
[9] LEON/ERC32 Cross Compilation System (LECCS),
http://www.gaisler.com/leccs.html
[10] M. Vorbach, J. Becker: Reconfigurable Processor Architectures for Mobile Phones; Reconfigurable Architectures Workshop (RAW 2003), Nice, France, April, 2003
[11] J. Becker, M. Vorbach: Architecture, Memory and Interface Technology Integration of an Industrial/Academic Configurable System-on-Chip (CSoC); IEEE Computer Society Annual Workshop on VLSI (WVLSI 2003), Tampa, Florida, USA, February, 2003
６．  参考文献
[1] Markus Weinhardt and Wayne Luk.  Memory Access.  Optimization for Reconfigurable Systems. IEEE Proceedings Computers and Digital Techniques, 48(3), May 2001.
[2] Michael Wolfe.  High Performance Compilers for Parallel Computing. Addison-Wesley, 1996.
[3] Hans Zima and Barbara Chapman.  Supercompilers for parallel and vector computers. Addison-Wesley, 1991.
[4] David F. Bacon, Susan L. Grahams and Oliver J. Sharp. Compiler Transformation for High Performance Computing. ACM Computing Surveys, 26(4):32-420, 1994
[5] Steven Muchnick.  Advanced Compiler Design and Implementation.  Morgan Kaufmann, 1997.
[6] Joao M.P. Cardoso and Markus Weinhardt. XPP-VC: A C Compiler with Temporal Partitioning for the PACT-XPP Architecture.  In Proceedings of the 12th International Conference of Field-Programmable Logic and Applications, FPL'2002, volume 2438 of LNCS, pages 864-874, Montpellier, France, 2002.
[7] Markus Weinhardt and Wayne Luk.  Pipeline Vectorization.  IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, 20(2):234-248, February 2001.
[8] V. Baumgarte, F. May, A. Nueckel, M. Vorbach and M. Weinhardt. PACT XPP - A Self-Reconfigurable Data Processing Architecture.  In Proceedings of the 1st International Conference on Engineering of Reconfigurabel Systems and Algorithms (ERSA'2001), Las Vegas, Nevada, 2001.
[9] Katherine Compton and Scott Hauck.  Reconfigurable Computing: A Survey of Systems and Software.  ACM Computing Surveys, 34(2):171-210, 2002.
[10] Sam Larsen, Emmett Witchel and Saman Amarasinghe.  Increasing and Detecting Memory Address Congruence.  In Proceedings of the 2002 IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT'02), pages 18-29, Charlottesville, Virginia, September, 2002.
[11] Daniela Genius and Sylvain Lelait.  A Case for Array Merging in Memory Hierarchies.  In Proceedings of the 9th International Workshop on Compilers for Parallel Computers, CPC'01, Edinburgh, Scotland, June 27th-29th, 2001。
【０６６７】
第２主要部分
本発明の別の様相を以下に説明する。この様相は、ハイパースレッド、マルチスレッド、マルチタスク、スケジューリングの実現およびコンフィギュレーションの一部の実行その他に関するものである。
【０６６８】
WO 00/49496においてすでに、実際にランタイムに再定義することができるリコンフィギュラブルな命令を実行できるコンフィギュレーション機能ユニットを含むプロセッサを使用して、コンピュータプログラムを実行する方法が開示されている。
【０６６９】
慣用のプロセッサアーキテクチャでは、例えば、順次実行のプロセッサの結合が必要であり、および／またはデータストリーミング、ハイパースレッド、マルチスレッドなどのようなテクノロジを有効に使用して性能を向上させる場合に問題がある。例えばWO 02/50665A1のような従来技術において公知の技術では、ＣＰＵのＡＬＵと、ＦＰＧＡ、ＤＳＰなどのコンフィギュラブルデータ処理ロジックセルフィールドとの間のデータ交換に十分に効果的な作用を及ぼす手法は実現不可能であり、ここでこのデータ交換は従来技術においてレジスタを介して行われる。言い換えると、まずデータを順次にレジスタに書き込み、つぎにこれらを順次に取り出し、またこれらを順次に再記憶しなければならないのである。
【０６７０】
殊にＣＰＵに統合化されたＡＬＵでは処理できない機能をコンフィギュラブルデータ処理セルフィールド、ＤＦＰ，ＦＰＧＡまたは類似のものに実装するために使用される上記の既知の装置において、データへの外部アクセスが要求される場合には別の問題がある。このために実践的にはこのデータ処理ロジックセルフィールドは、このようなデータ処理ロジックセルフィールドによる付加的な支援のないＣＰＵのＡＬＵにおいて可能であるよりも、データをさらに効率的に処理することができるユーザ定義のオペコードを可能にするために使用される。従来技術では上記の結合は一般的にワードベースであり、ブロックベースではない。さらに本発明の重要な様相であるのは、データストリーミングのデータ処理に対してブロックベース結合が極めて有利であることが認識されたことである。いずれにせよ、殊にレジスタを介する密な結合によって可能であるよりもさらに効率的なデータ処理が極めて有利である。
【０６７１】
粗粒度および／または細粒度のロジックセルと、ロジックセル要素とからなるロジックセルフィールドを使用する別の手法の特徴は、このようなフィールドと、慣用のＣＰＵおよび／またはエンベッデッドシステムにおけるＣＰＵコアとを極めて疎に結合することである。ここでは慣用の順次実行のプログラム、例えばＣ，Ｃ＋＋または類似のもので書かれたプログラムはＣＰＵで実行することができ、その一方細粒度および／または粗粒度のデータ処理ロジックセルフィールドによるデータストリーム処理のインスタンス化（instantiation）は上記の順次実行のプログラムを介して行われる。この場合につぎのような問題がある。すなわち、上記のロジックセルフィールドのプログラミングにおいて、Ｃ言語または任意の別の順次実行の高水準言語で書かれていないプログラムを、データストリーム処理のために提供しなければならないという問題があるのである。Ｃプログラムが、慣用のＣＰＵアーキテクチャ上でも、これと共に動作するデータ処理ロジックセルフィールド上でも動作できるようにすることは望ましい。殊に、擬似的な順次のプログラム実行が、データ処理ロジックセルフィールドにおけるデータストリーミングの能力を維持すると同時に、過剰に疎に結合せずにＣＰＵを動作させる能力があるという事実があっても上記のようにすることは望ましいのである。
【０６７２】
データ処理ロジックセルフィールド内に順次データ処理を設けることがすでに公知である。例えば、DE 196 51 075，WO 98/26356，DE 196 54 846，WO 98/29952，DE 197 04 728，WO 98/35299，DE 1 99 26 538，WO 00/77652，DE 102 12 621を参照されたい。ここでは、例えば、所要の資源量を減らし、また実行時間を最適化するなどのために部分的な実行が単一のコンフィギュレーション内で達成される。しかしながらこのことは自動的につぎのようなことには結び付かない。すなわち、順次実行処理に対するふつうのマシンモデルの場合と同じように、プログラマが高水準言語コードを自動的に翻訳またはデータ処理セルフィールドに転送できるようにはならないのである。実際に順次実行マシンのモデルに対して公知の方法にしたがってデータ処理ロジックセルフィールドに高水準言語コードのコンパイル、転送または翻訳することは困難なままである。
【０６７３】
従来技術ではさらにつぎが公知である。すなわち、エリアの複数の部分における別個の機能にそれぞれ作用する複数のコンフィギュレーションを処理アレイにおいて同時に実行でき、またランタイムに別のコンフィギュレーションを妨害することなく１つまたは複数のコンフィギュレーションを変更できることが公知である。
【０６７４】
これを実現するための方法およびハードウェアに実装された手段が公知であり、これによって、アレイにロードされる部分コンフィギュレーションをデッドロックなしに実行することができる。これについてはDE 196 54 593，WO 98/31102，DE 198 07 872，WO 99/4414-7，DE 199 26 538，WO 00/77652，DE 100 28 397，WO 02/13000を参照されたい。このテクノロジにより、ある一定のやり方で、殊にある一定のマルチタスク／マルチスレッドに対し、コンフィギュレーションまたは部分コンフィギュレーションの所与のある一定の形態および関係と、ある一定の並列性とが可能になり、殊にプランニング、すなわちスケジューリングおよび／または時間利用に対する制御のプランニングが可能になるのである。さらに従来技術から、時間利用プランニング制御手段および方法がそれ自体で公知であり、少なくとも相応のコンフィギュレーションの相互関係および／またはある一定のタスクおよび／またはスレッドへのコンフィギュレーションの割り当ての下で、コンフィギュレーションおよび／またはコンフィギュレーションのシーケンスにより、マルチタスクおよび／またはマルチスレッドが可能になる。タスク、スレッド、マルチスレッドおよびハイパースレッドをスケジューリングすることを目的として、コンフィギュレーションを構成および管理するための従来技術において使用されるこのような時間利用プランニング制御手段の使用法は、それ自体で発明に値すると考えられる。
【０６７５】
本発明では、順次実行形プロセッサとリコンフィギュラブルアレイとを同時に動作させる方法において、データをこのリコンフィギュラブルアレイに、アレイに対するデータキャッシュから転送し、このデータから当該アレイにて形成された結果を宛先に書き込む。
【０６７６】
本発明の１実施形態によれば、上記の宛先は、順次実行形プロセッサの算術ユニットの上流に配置されている。
【０６７７】
また本発明の１実施形態では、上記リコンフィギュラブルアレイからのデータ出力を、少なくとも部分的に、処理ユニットのデコーディング回路の下流にある前記プロセッサユニットのデータパスに供給する。
【０６７８】
本発明の１実施形態では、上記のプロセッサの算術論理ユニットは、リコンフィギュラブルアレイから出力されるデータに対して少なくとも１つの演算を行うように適合化されている。
【０６７９】
また本発明の１実施形態では、上記算術論理回路は、乗算および／または除算および／または殊に前記リコンフィギュラブルアレイから出力されるデータに実行される演算のための回路を含んでおり、この演算には、乗算および／または除算および／または正規化（norming）が含まれる。
【０６８０】
本発明の１実施形態では、上記のリコンフィギュラブルアレイから出力されるデータは有利には上記の順次実行形処理ユニットのレジスタおよび／またはキャッシュの以外のメモリ位置に選択に書き込み可能である。
【０６８１】
また上記宛先は、算術論理ユニットの下流および／または前記処理ユニットに結合されたキャッシュの上流にある。
【０６８２】
有利な変形実施形態の少なくとも部分的な様相において、マルチタスク、マルチスレッド、ハイパースレッドなどのようなデータ処理およびプログラム実行の最近のテクノロジをサポートすることは望ましいことである。
【０６８３】
本発明の別の重要な様相は、データ処理ロジックセルフィールドによるコンフィギュレーションのロードの実行に応答して、データがこのデータ処理ロジックセルフィールドに入力されること、および／またはストアコンフィギュレーションを実行することによってデータ処理ロジックセルフィールドからデータが記憶されることにあると考えることができる。したがってロードおよび／またはストアコンフィギュレーションをつぎのようにすることが有利である。すなわち、使用されるこれらのメモリセルのアドレスが、データ処理ロジックセルフィールド内で直接または間接的に生成されるようにすると有利である。ここでこれらのアドレスは、ロードおよび／またはストアアクセスとして、すなわちリードおよび／またはライトアクセスとしてアクセスしなければならないメモリセルおよび／または位置を指示する。コンフィギュレーション内のアドレス発生器を設定することによって、複数のデータをデータ処理ロジックセルフィールドにロードすることができ、ここでこれらは内部ＲＡＭ（ＩＲＡＭ）に、および／またはＥＡＬＵのようにレジスタを有する内部セル内に、および／または別の専用のメモリおよび／または記憶手段に記憶することができる。したがってロードまたはストアコンフィギュレーションにより、ブロック単位でひいてはほぼデータストリームで、データのロードまたはストアがそれぞれ可能になる。これは殊に単一のアクセスよりも格段に高速であり、１つまたは複数のデータ処理、および／またはデータを変更するデータハンドリング、すなわちそのプリロードしたデータを処理するコンフィギュレーション処理の実行の前または実行中に行うことができる。
【０６８４】
ロジックセルフィールドが通常そうであるように十分に大きいとすると、データのローディングはその小さな部分エリアにおいて行うことができ、この間に別の部分エリアは別のタスクを実行している。例えば、本発明の出願人による別の刊行物に記載されたピンポン状データ処理において、この公知のピンポン状データ処理は、データ処理フィールドの両側に設けられたメモリセルに依拠しており、ここでは第１のデータ処理ステップにおいてデータは、一方の側のメモリからデータ処理フィールドを通って、このデータ処理フィールドの他方の側のメモリに流れ、これらのデータは中間的な結果として記憶される。この間に必要であれば、アレイはリコンフィギュレーションされてこの中間結果はさらなる処理などのために逆に流される。ここでは一方の側のメモリストリップおよび／または一方の側のメモリ部分にはロードコンフィギュレーションによって１アレイ部分にデータをプリロードすることができ、この間にこのロジックセルフィールドの他方の側のメモリ部分にはストアコンフィギュレーションを使用してデータを書き込まれる。このようなデータ処理の同時のロード／ストア方式は、データが取り出されるおよび／またはデータが記憶されるメモリエリアが空間的に分散および／または分離されていなくても可能であることに注意されたい。
【０６８５】
キャッシュからおよび／またはキャッシュへのデータのロードに作用を及ぼすことが可能である。データ処理ロジックセルフィールド内に別個の回路に設けることなく、キャッシュ制御ユニットを介して大きなメモリバンクへの外部通信を処理すると、キャッシュメモリ手段への書き込みまたは読み出しアクセスは通例極めて高速であり、遅延は（あるとしても）わずかであるため、有利である。さらに通例、ＣＰＵユニットは、ロード／ストアユニットを介して、上記のキャッシュに結合されており、データへのアクセスおよびＣＰＵコアとデータ処理ロジックセルフィールドとの間のデータの交換は高速にブロック単位で行うことができ、有利である。また例えばＣＰＵのオペコードフェッチャによってフェッチしてそこで処理しなければならない別個の命令を介して、単一のデータ毎に転送する必要がないのである。
【０６８６】
また、ＰＡＣＴ社によるものではない従来技術において公知のキャッシュを有するロード／ストアユニットだけを介してレジスタが通信する場合、これらのレジスタを介し、ＣＰＵによってデータ処理ロジックセルフィールドとＡＬＵとを結合することに比べて、上記キャッシュ結合は格段に有利である。
【０６８７】
順次実行形ＣＰＵユニットまたは複数の順次実行形ＣＰＵユニットのうちのロード／ストアユニットへ、および／またはこのロード／ストアユニットから、データ処理ロジックセルフィールドおよび／またはそのレジスタを接続するさらなるデータ接続を設けることも可能である。
【０６８８】
例えばＶＰＵまたはＸＰＰとして設けることができるデータ処理ロジックセルフィールドの別の入力／出力ポートを介してユニットをアドレスできること、および／または単一のポートの下流にある１つ以上のマルチプレクサを介してデータ処理ロジックセルをアドレスできることに注意されたい。
【０６８９】
書き込みおよび読み出しによってキャッシュエリアに対し、および／またはロード／ストアユニットに対し、および／または順次実行形ＣＰＵのレジスタへのそれ自体公知の接続に対して、ブロック単位および／またはストリームおよび／またはランダムモードでアクセスすることの他に、ＲＡＭ，ハードディスクまたは別の任意のデータ交換媒体などのような外部大量記憶装置またはアンテナなどのような入力または出力ポートへの接続を設けることも可能である。これらのユニットおよび／または記憶手段のうちのいくつかへのアクセスに対して別個のポートを設けることができる。適切なドライバ、信号調整回路などを設けなければならないことにも注意されたい。さらに排他的にではないが殊にデータ処理ロジックセルフィールドに流れ込むおよび／またはここから流れ出すデータストリームを扱うため、このフィールドのロジックセルは、ＡＬＵまたはＥＡＬＵをそれぞれ含むことができ、ここでこれらは細粒度にコンフィギュラブルでＦＰＧＡライクな小さい回路をその入力および／または出力ポートに有することができ、これは、連続したデータストリームから４ビットブロックを切り出すためであり、例えばＭＰＥＧ−４デコーディングに必要である。このようにすることは、一方では比較的大きなＰＡＥユニットをブロッキングすることなくデータストリームをセルに入力して処理するかまたは前処理する場合に有利である。またＡＬＵがＳＩＭＤとして提供される場合には殊に有利である。ここでは、例えば、３２ビットデータ幅を有する極めて幅の広いデータワードがＳＩＭＤ−ＡＬＵの手前のＦＰＧＡライクなストライプを介して分割されて、幅の広い３２ビットデータが例えば４ビットデータ幅の８つのデータワードに分かれる。これによってこれらのデータワードはＳＩＭＤ−ＡＬＵにおいて並列処理でき、システムの全体的な性能が格段に増大する。ここで前提となるのは、アプリケーションに対する配慮が必要なことである。
【０６９０】
さらに上記のＦＰＧＡライクなプレまたはポスト構造に対して参照がなされる場合、これは１ビット粒度デバイスを必ずしも参照する必要がないことに注意されたい。逆に例えば極めて細粒度の１ビット構造の代わりに４ビット構造の細粒度構造を設けることも可能である。言い換えると、上記のＡＬＵユニット、殊にＳＩＭＤ−ＡＬＵユニットの前ないしはそのデータの流れで見て下流にあるＦＰＧＡライクな入力および／または出力構造は、つねに４ビットデータワードが処理されるようにコンフィギュレーションできるのである。またカスケードを設けて、例えば到来する３２ビットデータ幅のワードが、相前後する８ビットのＦＰＧＡライクな構造によって４ビット部分に分けられるようにすることもでき、この場合、これらの４つの８ビットデータワードは、ＦＰＧＡライクな４つの８ビット幅構造で処理され、ＦＰＧＡライクな相異なる８つの４ビット幅構造の第２ストライプを設け、また必要であれば、並列な２ビットを有する相異なる１６個のＦＰＧＡライクな構造を設ける。この場合、ＦＰＧＡライクな極めて細粒度の１ビット構造と比べてオーバーヘッドが格段に低減される。これにより、コンフィギュレーションメモリなどを格段に少なくすることができ、したがってシリコン領域を節約することができる。
【０６９１】
上記の結合のすべての利点は、キャッシュを介してデータブロックストリームを使用することによって得られることに注意されたい。しかしながら殊に上記のキャッシュがスライス式に構成され、かつ複数のスライスへのアクセスが同時に、殊にすべてのスライスに同時に行われると有利である。すぐにわかる通りにこのことは、ハイパースレッド、マルチタスクおよび／またはマルチスレッドのいずれとしてであれ、データ処理ロジックセルフィールド（ＸＰＰ）および／または順次実行の１つまたは複数のＣＰＵが複数のスレッドを処理しなければならない場合は有利である。またスライスアクセスを有するキャッシュ記憶手段および／またはスライスアクセスイネーブル制御手段を設けることも有利である。例えば、それぞれの単一のスレッドに別個のスライスを割り当てることができ、これによってこのスレッドを処理する際に、相応するキャッシュ領域が、処理されるコードグループのリエントリでアクセスされるようにする。しかしながら、キャッシュは必ずしもスライスに分ける必要なく、またキャッシュがスライスに分けられているとしても、それぞれの単一のスレッドを別個のスライスに割り当てる必要はないことを理解されたい。しかしながらこれが極めて有利なやり方である。さらにすべてのキャッシュ領域が所定の時点において同時にまたは一時的に使用されていない場合もあることに注意されたい。むしろ携帯型移動電話、ラップトップ、カメラその他の典型的なデータ処理アプリケーションにおいて、全キャッシュを必要としない時間があることが予想される。このため、あるキャッシュ領域を電源から切り離すことができ、これによってエネルギー消費が格段に低減され、例えば０に近いか、または正確に０であるようにすると極めて有利である。これは、キャッシュスライスを電源から切り離すように適合されている電源分離手段によって達成可能である。この分離はクロックの低減、クロックラインの切り離し、および／または電源全体の切り離しによって行うことができる。殊にこのような分離を単一のキャッシュスライス毎に設けることができ、これは例えば、スレッド、ハイパースレッド、タスクなどが相応のキャッシュスライスに現在割り当てられているか否かを識別するようにしたアクセス識別によって行われる。このアクセス識別手段により、割り当てられていないことが指示および／または検出される場合、通例、スライスのクロックラインからの切り離しおよび／または電源ラインからの切り離しさえも選択肢として考えることができる。電源からの切り離し後の再電源投入時に直ちにキャッシュ領域にアクセスすることがあり得るため、ハードウェアが現在の半導体テクノロジで実装される限り、電源のオンまたはオフによる大きな遅延はあってはならない。
【０６９２】
本発明の別の利点はつぎのような事実にある。すなわち、データおよび／またはオペランドの転送がブロック単位でできるが、順次実行形ＣＰＵと、ＸＰＰおよび／または別のデータ処理ロジックセルフィールドとにおいて正確に同じ時間にデータ処理ステップが実行されることを保証するために特にバランス調整がいらないという事実にある。むしろ処理は独立していることが多く、これにより、殊に順次実行形ＣＰＵおよびデータ処理ロジックセルフィールドは、スケジューラにより、別個の資源とみなされることが可能である。これによって、マルチタスク、マルチスレッド、ハイパースレッドなどの既知のデータ処理プログラム分割テクノロジをただちに実現することができるのである。データパスのバランス調整が不要であるという利点は結果的に、例えば順次実行形ＣＰＵにおいて多くのパイプラインステージを含めることができ、クロック周波数および／またはクロック方式をさまざまに実現できることなどに結び付く。非同期のロジックが必要な場合には殊に有利である。本発明の別の利点は結果的に、ロードおよびストアコンフィギュレーションをデータ処理ロジックセルフィールドに設定することによってフィールド内のデータをこのフィールドにまたはこのフィールドからロードできることであり、ここでこれはもはやＣＰＵのクロック周波数、オペコードフェッチャの性能その他によって制御されないのである。言い換えると、オペコードフェッチャはもはや、疎結合を有しない場合にのようにデータロジックセルフィールドに対するデータスループットのボトルネックではないのである。
【０６９３】
本発明の殊に有利な実施形態では、公知のＣＴまたはＣＭを使用可能であり、ここでこれはFILMOその他の公知のテクノロジがハードウェアサポートおよびハイパースレッドの管理その他に適用可能になるという固有の利点を有する擬似ハイパースレッドハードウェア管理ユニットとして使用される。（ＣＴまたはＣＭは、ＸＰＰユニットにふつうに使用されており、また有利な実施形態においてそれ自体のＣＴを有する１つ以上の階層的に配置されたＸＰＰフィールドを有しており、同時に１つ以上の順次実行形ＣＰＵを使用するという事実がある）。択一的におよび／または殊に階層的な構成において、コプロセッシングインタフェースを介し、順次実行形ＣＰＵのオペコードフェッチャからコンフィギュレーションを供給することができ、これによってこの順次実行形ＣＰＵにより、ＸＰＰおよび／またはデータ処理ロジックセルフィールドコールをインスタンス化して、データ処理ロジックセルフィールドにおいてデータ処理を行うことができる。データ処理ロジックセルフィールドにまたはこのフィールドからデータをロードおよび／またはストアするためのアドレス発生器を提供する、キャッシュ結合および／またはロードおよび／またはストアコンフィギュレーションにより、ＸＰＰのデータ交換が行われる。言い換えると、データ処理ロジックセルフィールドへのコプロセッサライクな結合が可能になり、同時にキャッシュおよび／またはＩ／Ｏポート結合を介してデータストリームライクなデータのロードが行われるのである。
【０６９４】
コプロセッサ結合の手法、すなわち、データ処理ロジックセルフィールドの指示された結合により、通常、この論理セルフィールドのスケジュールが行われることになり、ここれこれは、順次実行形ＣＰＵおよび／またはスーパーバイザスケジューラユニットおよび／または相応のスケジューラ手段で行われる。このような場合、スレッド制御および／または管理は実践的には上記のスケジューラおよび／または順次実行形ＣＰＵで行われる。これがそれ自体可能であったとしても、本発明の最も簡単な実現が求められる場合には不要である。データ処理ロジックセルフィールドは、例えば、８０８６／８０８７の組合せのような標準のコプロセッサの場合に行われているのと同じように慣用のやり方でコールすることができる。
【０６９５】
殊に有利な実施形態において、コンフィギュレーションの仕方、すなわちこれがコプロセッサインタフェースによるか、同時にスケジューラとして動作するコンフィギュレーションマネージャによるか、または別の仕方によるかとは無関係に、データ処理ロジックセルフィールド内またはこのすぐ近くのメモリまたはその管理の下の、例えばＸＰＰアーキテクチャ内の専用のメモリ、すなわち、出願人においてはＲＡＭ−ＰＡＥとして知られているメモリまたは別のメモリをアドレスすることができる。したがってベクトルレジスタのような内部メモリを管理することが提案され、すなわち、ロードコンフィギュレーションを介してロードされたデータの塊が、ベクトルのように内部メモリセルのベクトルレジスタに記憶され、その後、現在のデータ処理に影響する新しいコンフィギュレーションをロードしおよび／または起動した後にこれらのレジスタにアクセスするのである。（注意しなければならないのは、データ処理コンフィギュレーションは、いくつかの相異なるコンフィギュレーションが同時に、順次にまたは波状モード（wave-like modus）で処理される場合であっても１つのコンフィギュレーションと称されることがあることである）。
【０６９６】
ここでベクトルレジスタは、結果および／または中間結果を内部のメモリセル素子または内部的に管理されるメモリセル素子に記憶するために使用可能である。ベクトルレジスタライクにアクセスされるＸＰＰのメモリ手段も使用することができ、ここでこれは、ストアコンフィギュレーションを適切なやり方でロードすることによって、すなわちここでもＩ／Ｏポートを介して直接、外部メモリ領域にデータを流すのであれ、または殊に有利にはキャッシュ領域にまたはここからデータを流すのであれ、データストリームライクなやり方でロードすることによって、処理コンフィギュレーションをリコンフィギュレーションした後に行われる。この場合にこれらは後の段階で、順次実行形ＣＰＵおよび／または別のデータ処理ロジックセルフィールドで実行される別のコンフィギュレーションによってアクセスすることができる。ここでこれが行われるのは、殊にデータ処理ロジックセルフィールドが、上記の最初の位置にこのデータを形成した場合である。
【０６９７】
殊に有利な実施形態では、少なくとも所定のデータ処理結果および／または中間結果に対して、メモリおよび／また処理したデータを記憶するメモリレジスタ手段を使用することができる。すなわち、内部メモリではなく、アクセスが確保されたキャッシュ領域、殊にスライス方式で編成されたキャッシュ領域を使用することができるのである。これは、殊にＸＰＰおよび／またはデータ処理ロジックセルフィールドと、キャッシュとの間のパスが極めて長いために信号伝送の遅延を考慮しなければならない場合に遅延が大きくなるという欠点を有することがある。それでもなおこれにより、付加的なストアコンフィギュレーションを回避することができる。また、キャッシュ領域へのこのようなデータの記憶は、１つにはデータを記憶するメモリをキャッシュコントローラに物理的に近く配置して、このメモリをキャッシュとすることによって可能になるが、択一的および／または付加的にはデータ処理ロジックセルフィールドメモリ領域の一部、すなわち内部メモリを、例えば、「ＰＡＥ上のＲＡＭ」の場合のように１つまたは複数のキャッシュメモリコントローラのコントロールの下で提供することも可能であることに注意されたい。
【０６９８】
データ処理結果を記憶する際の遅延を小さく維持する一方で、別のユニットに対する疑似的なキャッシュとして動作するメモリ領域にアクセスする際の遅延がそれほど重大でない場合には有利である。
【０６９９】
また既知の順次実行形ＣＰＵのキャッシュコントローラが、キャッシュとしてメモリ領域をアドレスする実施形態も考えられ、ここでこのメモリ領域は、データ処理ロジックセルフィールドとのデータ交換をすることなく、このデータ処理ロジックセルフィールドにおよび／またはこのフィールドの近くに物理的に配置される。これはつぎの点で有利である。すなわち、極めて少ないローカルメモリしか要しないアプリケーションがこのデータ処理ロジックセルフィールドで実行される場合、および／または利用可能なメモリ空間の全体量に比べて別のコンフィギュレーションをわずかにしか必要としない場合、これらのメモリ領域をキャッシュまたは付加的なキャッシュとして１つまたは複数の順次実行形ＣＰＵに割り当てることができる点で有利である。この場合、キャッシュコントローラを適合化して、動的にサイズが変わるキャッシュ領域を管理するようにすることができる。
【０７００】
動的キャッシュサイズ管理手段および／または動的キャッシュ管理のための動的キャッシュ管理サイズ変更手段は、殊に順次実行形ＣＰＵおよび／またはデータ処理ロジックセルフィールドにおける作業負荷を考慮することができる。言い換えると、例えば、所定の単位時間にいくつのＮＯＰが順次実行形ＣＰＵで実行されるか、および／またはいくつのコンフィギュレーションが、専用に設けられたメモリ領域の動的リコンフィギュラブルフィールドにプリロードされるかを解析することができ、これによって（waveリコンフィギュレーションによってであろうと、別のやり方によってであろうと）高速のリコンフィギュレーションが可能になる。ここに記載した動的キャッシュサイズ管理またはキャッシュサイズ管理は、極めて有利にもランタイムにダイナミックに行うことができる。すなわち、キャッシュコントローラは、瞬時のキャッシュサイズをその都度制御し、ここでこれはクロックサイクル毎にまたは１クロックサイクルグループから別のクロックサイクルグループの間に変更可能なのである。またベクトルレジスタのような内部メモリとしてのアクセスを有する、データ処理ロジックセルフィールドのアクセス管理も可能であることにも注意されたい。上で説明したようにコンフィギュレーション管理ユニットを設けることができるが、明に注意しなければならないのは、殊に今はまだ必要のないコンフィギュレーションのプリロードを可能にするこのようなユニットおよびその動作の仕方を使用して、極めて簡単にマルチタスク動作および／またはハイパースレッドおよび／またはマルチスレッドに作用を及ぼすことができる。ここでこれは例えばタスクおよび／またはスレッドおよび／またはハイパースレッドスイッチを行うためである。またここで注意しなければならないのは、スレッドまたはタスクのランタイム時に、別個のタスクおよび／またはスレッドおよび／またはハイパースレッドに対するコンフィギュレーションをＰＡＥアレイにプリロードできることである。この場合にこれにより、例えば、遅延のためにまだデータを受信していないからであろうと、他のアクセスによって資源がブロックされているからであろうと、データを待たなければならないために現在のスレッドまたはタスクが実行できない場合、別個のタスクおよび／またはスレッドに対してコンフィギュレーションをプリロードすることができる。別のタスクまたはスレッドに対してコンフィギュレーションをプリロードする場合、タイミングオーバヘッドの欠点なしにスイッチおよび変更が可能になる。それは、例えば、シャドーライク（shodow-like）にロードされるコンフィギュレーションの実行によるものである。
【０７０１】
原理的には、実行の継続が極めて高い確率で予想されかつ予想がはずれた場合にもこのテクニックを使用することができる。しかしながらこのような動作の仕方は、予想が行われない場合に最も有利である。１つまたはいくつかの純粋な順次実行形ＣＰＵを使用する場合、コンフィギュレーションマネージャはハイパースレッドマネージメントハードウェアとしても動作し、またこれを実現する。DE 198 07 872，WO 99/44147およびWO 99/44120を参照されたい。殊にＣＰＵおよび／またはいくつかの順次実行形ＣＰＵがハイパースレッドマネージメントを有しており、これによってこれらの参考文献に記載されたFILMOのような部分的な回路素子を保持する場合にはこれで十分であると考えられる。殊に、データ処理ロジックセルフィールドとの結合を有するまたはこれを有しない１つまたは複数の純粋な順次実行形ＣＰＵに対して、ハイパースレッドマネージメントと共に使用するために、FILMOを有するおよび／またはこれを有しないそこに記載されたコンフィギュレーションマネージャを使用することがここに開示されており、発明として請求されている。しかしながら本発明において、新規であり発明性を有する機能が開示されているすべてのケースにおいて、これらの機能が発明であると明に述べられる訳ではないことに注意されたい。
【０７０２】
例えばDE 102 12 621，PCT/EP 02/10572から知られている公知技術によって複数のＣＰＵを実現できることにも注意されたい。またDE 106 51 075，DE 106 54 846，DE 107 04 728；WO 98/26356，WO 98/29952およびWO 98/35299には、データ処理ロジックセルフィールドにリングおよび／またはランダムアクセスメモリ手段を有するシーケンサの実現方法が記載されているにも注意されたい。
【０７０３】
タスク、スレッドおよび／またはハイパースレッドスイッチはそれぞれ公知のＣＴ技術によって作用を及ぼすことができ、ＣＴにより、パフォーマンススライスおよび／またはタイムスライスが、ソフトウェアで実現されたオペレーションシステムスケジューラに割り当てられる。ここで資源が利用できることを前提としてこれらのスライスの間にタスクおよび／またはスレッドのどの部分を引き続いて実行するかが決定される。
【０７０４】
つぎのような例がある。すなわち、最初に第１のタスクに対してアドレスの列が生成される。このタスクの間にロードコンフィギュレーションの実行により、データ処理ロジックセルフィールドに結合されているキャッシュメモリからデータが上記のようにロードされる。データが存在すれば直ちに、第２のタスクの実行、すなわち実際のデータ処理コンフィギュレーションを開始することができる。このコンフィギュレーションはプリロードすることもできる。それは、割り込みなどがタスクスイッチを発生させていないことを前提とすると、このコンフィギュレーションが実行されることが確実だからである。ふつうのプロセスでは、キャッシュにおいてまだ利用できないデータが要求されるという周知のいわゆるキャッシュミスの問題がある。このようなケースが結合において発生する場合、本発明によれば、別のスレッド、ハイパースレッドおよび／またはタスクに切り換えることができる。ここでこれは殊に上で、ソフトウェアで実現されたオペレーションシステムの専用のスケジューラおよび／または別のハードウェアおよび／またはソフトウェアで実現された相応に動作するユニットにより、つぎに実行するものとして決定されたものであり、したがってデータ処理ロジックセルフィールドの利用可能なコンフィギュレーションメモリにプリロードされ、殊に別のコンフィギュレーションの実行中にバックグラウンドにプリロードされる。ここでこの別のコンフィギュレーションは、例えば、現在待っているデータのロードを行ったロードコンフィギュレーションである。
【０７０５】
別個のコンフィギュレーション線路を設けることができることに注意されたい。ここでこれらは、例えば、データ処理ロジックセルフィールドの粗粒度の特定のデータ処理ロジックセルを接続するために使用される通信線路とは別の線路である。この場合、タスク、スレッドおよび／またはハイパースレッドスイッチによって処理が切り換られてコンフィギュレーションが実行され、また殊に有利には分割できず、割り込み不可であり、したがって擬似アトミックなコンフィギュレーションにおいてはその終わりまで実行される。上記のスケジューラ、殊にオペレーションシステムライクなスケジューラによってあらかじめ決められたさらに別のコンフィギュレーションおよび／または対応するロードコンフィギュレーションが実行されたコンフィギュレーションが実行される。ロードコンフィギュレーションが以前に実行されているコンフィギュレーションの処理を実行する前に、相応するデータがアレイに流れ込んだか否かのテストを行うことができる。ここでこれは例えば、通例発生する遅延時間が経過したか否か、および／またはデータで実際にあるか否かをチェックすることによって行われる。
【０７０６】
言い換えると、コンフィギュレーションがまだプリロードされず、データがまだロードされておらず、および／またはデータはまだ記憶されていない時に発生する遅延時間は、スレッド、ハイパースレッドおよび／またはタスクを実行することによって埋められるおよび／またはカバーされる。ここでこれらはプレコンフィギュレーションされており、またすでに利用可能であるデータを処理するか、または書き込みに利用可能な資源に書き込むことができる。これにより、遅延時間はカバーおよび／または埋められ、また十分な数のスレッド、ハイパースレッドおよび／またはタスクを実行することが前提である場合、データ処理ロジックセルフィールドはほぼ１００％の負荷を有することになる。
【０７０７】
このシステムでは、アレイを順次実行形ＣＰＵに結合しているのにもかかわらずリアルタイムシステムを実現することができ、また殊に同時にデータストリーム機能さえも有している。リアルタイム機能を確保するため、到来するデータまたはデータの到来を都度シグナリングする割り込みには、許容された最大時間を上回ることなく応答することを保証しなければならない。これは、割り込みに応じてタスクスイッチを発生させることにより、および／または、例えば、割り込みが所定の優先度を有する場合、所定の割り込みが目下無視されるように決定することによって行うことができる。ここでこれも同様に所定の時間内で定義しなければならない。したがってリアルタイム処理が可能なこのようなシステムにおけるタスクスイッチは、通例、３つのうちの１つで行われ得る。すなわち、タスクが所定の時間の間、動作していたか（ウォッチドッグ方式）、別のアクセスによるブロックにものであれ、遅延によるものであれ資源が利用できないか、および／または割り込みが発生するケースであるかのうちの１つで行われ得るのである。
【０７０８】
これらの変形形態のうちの１つの実現の仕方により、リアルタイム処理機能が保証される。第１の択一的な形態では、ＣＴまたはスケジューラの制御下にある１資源は、切り換わって割り込みが処理される。所定の割り込みに許容された応答時間が十分に長く、これによって現在設定されているコンフィギュレーションが、割り込みなしに実行できる場合、殊に実際に割り込み処理コンフィギュレーションをプリロードできるという点でこれは問題ない。プリロードする割り込み処理コンフィギュレーションは、ＣＴまたは別の任意のインスタンスによって選択することができる。また、コンフィギュレーションのランタイムを割り込み処理が割り当てられている資源に制限することも可能である。PCT/DE 03/000942を参照されたい。
【０７０９】
割り込み発生時にこのシステムがより迅速に反応しなければならない場合、単一の資源、例えば、割り込み処理ルーチンを実行するためのデータ処理ロジックセルフィールドの部分または別個のＸＰＰユニットを確保することが有利なことがある。この場合、殊に重大な割り込みに対する割り込み処理ルーチンをプリロードすることも可能である。また割り込みが発生してはじめて割り込み処理ルーチンのローディングを直ちに開始することも可能である。各割り込みに必要なコンフィギュレーションの選択は、トリガ、波形処理（wave processing）その他によって行うことができる。
【０７１０】
上記の方法により、ロード／ストアコンフィギュレーションを使用することによって、割り込みに対して即時に反応して、コードリエントランシー（code-reentraycy）を得ることができる。ここではデータ処理コンフィギュレーション毎またはいくつかおきのデータ処理コンフィギュレーション、例えば５つまたは１０個おきのデータ処理コンフィギュレーションに続いて、ストアコンフィギュレーションを実行し、つぎにデータを書き込んだばかりのメモリアレイにアクセスするロードコンフィギュレーションを実行する。この場合に保証しなければならないのは、プレローディングを行ったコンフィギュレーションまたはコンフィギュレーションのグループが、別のストアコンフィギュレーションを完全に実行することによって終了するまで、ストアコンフィギュレーションによって使用されるメモリ領域を触らないようにすることだけである。このようにしてロード／ストアコンフィギュレーションと、まだ老朽化（overaged）していない記憶メモリの同時の保護とを直ちに実行することにより、コードリエントランシーを極めて簡単に、例えばプログラムをコンパイルすることによって生成することができる。この際に資源を確保することも有利である。
【０７１１】
さらに、割り込みに対する応答の殊に有利な実施形態は、データ処理ロジックセルフィールドに対するコードが禁止されている割り込みルーチンを使用することである。この実施形態が有利であるのは、利用可能な資源の１つが順次実行形ＣＰＵである場合である。言い換えると、割り込み処理ルーチンは、データ処理ロジックセルフィールを使用するデータ処理ステップまたはルーチンを呼び出すことなしに順次実行形ＣＰＵでのみ実行されるのである。これによって保証されるのは、データ処理ロジックセルフィールドにおける処理は割り込まれず、またこの場合、このデータ処理ロジックセルフィールドにおけるさらなる処理をタスクスイッチにしたがって行うことができることである。この割り込みルーチンは実際には、ＸＰＰコードのようなデータ処理ロジックセルフィールドコードを含まないが、それでもなお保証できるのは、リアルタイム処理機能にもはや関係のない後の時点に、このデータ処理ロジックセルフィールドが、割り込みおよび／または所定のリアルタイム要求、ステータス情報および／またはデータ処理ロジックセルフィールドを使用するデータに応答することである。
【０７１２】
第３主要部
要約−今日、現代のマイクロプロセッサのデータパスは、静的な命令セットを使用することによってその限界に達してしまっている。これらの限界の１打開策が、伝統的な静的データパスと、粗粒度の動的リコンフィギュラブルＸＰＰ（eXtreme Processing Platform）アーキテクチャとを統合することによって達成される動的リコンフィギュラブルプロセッサデータパス拡張である。このために相応するデータパスを疎で非同期に結合するメカニズムを開発して、ＵＭＣから得られるＣＭＯＳ ０．１３μｍ標準セルテクノロジに集積したのである。ここではSPARC互換のＬＥＯＮプロセッサを使用しており、その静的なパイプライン化された命令データパスを拡張して、特定アプリケーション向けにコンフィギュレーションおよび個別化できるようにした。これによって、例えばMPEG-4のストリーミングアプリケーション分野、ディジタルフィルタ、移動通信変調などにおいてさまざまな使用および効率的な使用が可能になる。ここで選択した結合テクニックにより、付加的にコンフィギュレーションされる複合的な命令の非同期的な並行動作が可能になる。ここでこれはＬＥＯＮプロセッサのプログラミングおよびコンパイル環境に組み込まれる。
【０７１３】
６．１  導入
第４主要部
１  導入
ここで説明するのは、第３節に記載したリコンフィギュラブルデータフロープロセッサ（ＲＤＦＰ reconfigurable data-flow processor）へのポートアクセス機能の分だけ拡張された、ＣまたはFORTRANのような高水準プログラミング言語（ＨＬＬ  high-level programming language）のサブセットをコンパイルする手法である。ここでこのプログラムは、ＲＤＦＰのコンフィギュレーションに変換される。
【０７１４】
この手法は、標準のホストプロセッサと、リコンフィギュラブルデータフローコプロセッサとからなるハイブリッドアーキテクチャに対する拡張コンパイラの一部として使用することができる。この拡張コンパイラは、標準ＡＮＳＩ Ｃのような完全なＨＬＬを扱う。これは内側のループのような適切なプログラム部分をコプロセッサに、また残りのプログラムをホストプロセッサにマッピングする。また個別のプログラム部分を別個のコンフィギュレーションにマッピングすることも可能であるが、これらの拡張はここの主題ではない。
【０７１５】
２  コンパイルフロー
ここではこのコンパイル手法の複数のフェーズを手短に説明する。
【０７１６】
２．１  フロントエンド
このコンパイラは、入力プログラム（例えばＣプログラム）を、抽象構文ツリー（ＡＳＴ abstact syntax tree）とシンボルテーブルとからなる内部フォーマットに翻訳する標準フロントエンドを使用する。またこのフロントエンドは、定数伝播、不要なコードの除去、共通部分式の削除などのよく知られたコンパイラ最適化も行う。詳細については[１]のような任意のコンパイラの文法テキストを参照されたい。ＳＵＩＦコンパイラ[２]は、このようなフロントエンドを有するコンパイラの１例である。
【０７１７】
２．２  コントロール／データフローグラフの生成
つぎにプログラムは、結合されたＲＤＦＰ関数からなるコントロール／データフローグラフ（ＣＤＦＧ control/dataflow graph）にマッピングされる。このフェーズはここの主題であり、４節に示されている。
【０７１８】
２．３  コンフィギュレーションコードの生成
最終的にこの最後のフェーズにおいて上記のＣＤＦＧがコンフィギュレーションコードに直接翻訳され、これがＲＤＦＰをプログラムするために使用される。ＰＡＣＴ ＸＰＰＴＭのコアに対して、このコンフィギュレーションコードはＮＭＬ（Native Mapping Language）ファイルとして生成される。
【０７１９】
３  ＲＤＦＰの機能およびコンフィギュラブルオブジェクト
この節ではＲＤＦＰの機能およびコンフィギュラブルオブジェクトを説明する。ＲＤＦＰアーキテクチャの１実施例がＰＡＣＴ ＸＰＰＴＭコアである。ここでは上記のコンパイル手法が機能するためにＲＤＦＰに最小限に必要なことだけを説明する。ここで考察するデータ型は、「データ」と称されるマルチビットワードおよび「イベント」と称される単一ビット制御信号だけである。データおよびイベントはつねに「パケット」として処理される。これについては３．２節を参照されたい。イベントパケットは、そのビット値に応じて1-eventまたは0-eventと称される。
【０７２０】
３．１  コンフィギュラブルオブジェクトおよび機能
ＲＤＦＰは、コンフィギュラブルオブジェクトのアレイおよび通信ネットワークからなる。各オブジェクトは、所定の機能を実行するようにコンフィギュレーションすることができる（下に一覧で示してある）。オブジェクトは、コンフィギュレーションが変更されるまで同じ機能を繰り返して実行する。アレイは完全に均一である必要はない。すなわち、すべてのオブジェクトがすべての機能を実行できる必要はないのである。例えばＲＡＭ機能は、他の任意の機能を実行することのできない専用のＲＡＭオブジェクトによって実現することができるのである。いくつかのオブジェクトを組み合わせて「マクロ」にし、所定の機能を実現させることも可能である。例えばいくつかのＲＡＭオブジェクトを組み合わせて、大きな記憶容量を有するＲＡＭ機能を実現することができる。
【０７２１】
データおよびイベントパケットを処理する以下の機能をＲＤＦＰにコンフィギュレーションすることができる。図式表現について図１を参照されたい。
【０７２２】
・ＡＬＵ[オペコード]：ＡＬＵは、データに一般の算術および論理演算を行う。ＡＬＵ機能（「オペコード」）は、ＨＬＬで使用されるすべての演算に対して利用可能でなければならない（そうでない場合、ＲＤＦＰにおけるＡＬＵオペコードを含まない演算を含むプログラムは、サポートされているＨＬＬサブセットから除外されるか、または既存の機能の「マクロ」によって置き換えられなければならない）。ＡＬＵ機能は２つのデータ入力側ＡおよびＢと、１データ出力側Ｘとを有する。比較器はデータ出力側の代わりにイベント出力側Ｕを有する。これらは比較が真ならば1-eventを、そうでなければ0-eventを形成する。
【０７２３】
・ＣＮＴ：データ入力側ＬＢ，ＵＢおよびＩＮＣ（下限、上限およびインクリメント）と、データ出力側Ｘ（カウンタ値）とを有するカウンタ機能である。イベント入力側STARTにおけるパケットにより、このカウンタがスタートし、イベント入力側ＮＥＸＴにより、つぎの出力値（および出力イベント）の生成が行われるか、またはＵＢに到達した場合、このカウンタが終了する。NEXTが接続されていない場合、このカウンタは連続してカウントする。出力イベントＵ，ＶおよびＷは以下の機能を有する。Ｎ回をカウントするカウンタに対して、Ｎ−１個の0-eventおよび１個の1-eventが出力側Ｕに生成される。出力側ＶにはＮ個の0-eventが生成され、出力側ＷにはＮ個の0-eventおよび１個の1-eventが形成される。Ｗにおける1-eventは、このカウンタが終了した後にだけ形成される。すなわち、最後のデータパケットが出力された後、１ＮＥＸＴイベントパケットが受信される。
【０７２４】
・ＲＡＭ[サイズ]：ＲＡＭ機能は固定個数（「サイズ」）のデータワードを記憶する。これはデータ入力側ＲＤと、アドレスＲＤにおける読み出しのためにデータ出力側ＯＵＴとを有する。イベント出力側ＥＲＤは、リードアクセスの完了を通知する。ライトアクセスに対してデータ入力側ＷＲおよびＩＮ（アドレスおよび値）と、データ出力側ＯＵＴとが使用される。イベント出力側ＥＷＲは、ライトアクセスの完了を通知する。ＥＲＤおよびＥＷＲはつねに0-eventを生成する。外部ＲＡＭは、ＲＡＭ機能として内部ＲＡＭと全く同じように処理することができることに注意されたい。
【０７２５】
・ＧＡＴＥ：ＧＡＴＥは入力側Ａにおけるデータパケットと、入力側Ｅにおけるイベントパケットとを同期化する。２つの入力が到着すると、これらは共に消費される。このデータパケットは出力側Ｘにコピーされ、イベントパケットは出力側Ｕにコピーされる。
【０７２６】
・ＭＵＸ：ＭＵＸ機能は２つのデータ入力側ＡおよびＢと、イベント入力側ＳＥＬと、データ出力側Ｘとを有する。ＳＥＬが0-eventを受信する場合、入力Ａは出力側Ｘにコピーされて入力Ｂは廃棄される。1-eventに対してはＢがコピーされてＡが廃棄される。
【０７２７】
・MERGE：MERGE機能は、２つのデータ入力側ＡおよびＢと、イベント入力側ＳＥＬと、データ出力側Ｘとを有する。ＳＥＬが0-eventを受信する場合、入力Ａは出力側Ｘにコピーされるが、入力Ｂは廃棄されない。その代わりにパケットは入力側Ｂに残される。1-eventに対してはＢがコピーされ、Ａは入力側に残される。
【０７２８】
・DEMUX：DEMUX機能は、１つのデータ入力側Ａと、イベント入力側ＳＥＬと、２つのデータ出力側ＸおよびＹとを有する。ＳＥＬが0-eventを受信する場合、入力Ａは出力側Ｘにコピーされ、出力側Ｙにおいてパケットは形成されない。1-eventに対してＡはＹにコピーされ、出力側Ｘにおいてパケットは形成されない。
【０７２９】
・MDATA：MDATA機能は、データパケットを乗算（multiplicate）する。これはデータ入力側Ａと、イベント入力側ＳＥＬと、データ出力側Ｘとを有する。ＳＥＬが1-eventを受信する場合、Ａにおけるデータパケットは消費され、出力側Ｘにコピーされる。ＳＥＬにおける後続のすべての0-eventに対して、Ａにおいて新しいパケットを消費することなく、入力データパケットのコピーが出力側に形成される。別の1-eventがＳＥＬに到着した場合に限り、Ａにおけるつぎのデータパケットが消費されコピーされる（ＸＰＰＴＭにおいてこれは特別な性質を有するMERGEによって実現できることに注意されたい）。
【０７３０】
・INPORT[名前]：これは、入力ポート「名前」を介してＲＤＦＰの外部からデータパケットを受信してこれらをデータ出力側Ｘにコピーする。また１パケットを受信すると、イベント出力側Ｕに0-eventが形成される。（この機能は、外部パスに接続された専用のオブジェクトにおいてのみコンフィギュレーションできることに注意されたい。）
・OUTPORT[名前]：これは、データ入力側Ａにおいて受信したパケットを、出力ポート「名前」を介してＲＤＦＰの外部に送信する。また１パケットを送信すると、イベント出力側Ｕに0-eventが形成される。（この機能は、外部パスに接続された専用のオブジェクトにおいてのみコンフィギュレーションできることに注意されたい。）
付加的に以下の機能により、イベントパケットの操作だけが行われる：
・0-FILTER，1-FILTER：FILTERは入力側Ｅおよび出力側Ｕを有している。0-FILTERは、0-eventをＥからＵにコピーするが、Ｅにおける1-EVENTを廃棄する。1-FILTERは、1-eventをコピーし、0-eventを廃棄する。
【０７３１】
・INVERTER：これは、入力側Ｅからすべてのイベントを出力側Ｕにコピーするが、その値を反転する。
【０７３２】
・0-CONSTANT，1-CONSTANT：0-CONSTANTは入力側Ｅのすべてのイベントを出力側Ｕにコピーするが、これをすべて値０に変える。1-CONSTANTはすべての値１に変える。
【０７３３】
・ECOMB：これは２つ以上の入力側Ｅ１，Ｅ２，Ｅ３〜を結合して、出力側Ｕに１パケットを形成する。これらの入力パケットの１つ以上が1-eventの場合かつその場合に限り、1-eventを出力する（論理的な「ｏｒ」）。出力パケットが形成される前にすべての入力側においてパケットが利用可能でなければならない。（この機能はＸＰＰＴＭにおいてＥＡＮＤ演算子により、実現されることに注意されたい。）
・ＥＳＥＱ[ｓｅｑ]：ＥＳＥＱはイベントのシーケンス「ｓｅｑ」、例えば「０００１」を、その出力側Ｕに形成する。これが入力側STARTを有する場合、Ｕに到来するイベントパケット毎に１シーケンス全体が生成される。このシーケンスが繰り返されるのは、つぎのイベントがＵに到着する場合だけである。しかしながらSTARTが接続されていない場合、ＥＳＥＱは上記のシーケンスを一定に繰り返す。
【０７３４】
ＡＬＵ，ＭＵＸ，DEMUX，ＧＡＴＥおよびECOMB機能は、古典的なデータフローマシン[３，４]における等価機能と同様に動作することに注意されたい。
【０７３５】
３．２  パケットベースの通信ネットワーク
ＲＤＦＰの通信ネットワークは、１オブジェクトの１出力側（すなわちその各機能）を１つ以上の別のオブジェクトの入力側に接続することができる。これは通常、バスおよびスイッチによって行われる。機能をオブジェクトに適切に配置することによって、デバイスサイズによって課される制限まで、多くの機能を任意に接続することができる。上述のようにすべての値はパケットとして通信される。データおよびイベントパケットに対して別々の通信ネットワークが存在する。これらのパケットにより、肯定応答を有するデータフローマシン[３]と同様に機能が同期化される。すなわち上記の機能は、すべての入力パケットが利用可能になった場合にのみ実行されるのである（上記の厳格でない例外を除いて）。また機能は、最後の出力パケットが消費された場合にも停止する。したがってＲＤＦＰにマッピングされるデータフローグラフは、外部のコントロールを必要とせずにその実行をそれ自体で同期化するのである。２つ以上の機能出力側（データまたはイベント）が同じ機能入力側（「Ｎ対１接続」）に接続されている場合のみ、この自己同期化が禁止される（ＸＰＰＴＭコアにおいて「Ｎ対１接続」は、イベントについてはＥＯＲ機能によって実現され、データについてはいくつかの出力側を入力側に割り当てることだけで実現されることに注意されたい）。ユーザは、１時点に正しいＣＤＦＧに１つのパケットだけが到着することを保証しなければならない。そうでないと、パケットは失われることがあり、２つ以上のパケットを結合することによって得られる値は不定になってしまう。しかしながら、機能出力側は、問題なしに多数の機能入力に接続することができる（「１対Ｎ接続」）。
【０７３６】
特殊なケースがいくつかある：
・機能入力側には、コンフィギュレーション中に別の値を「プリロード」することができる。このパケットは、別のオブジェクトから到来する通常のパケットと同様に消費される。
【０７３７】
・機能入力側は、「一定」として定義することができる。この場合、この入力側におけるパケットは、機能の実行の毎に繰り返して再形成される。
【０７３８】
ＲＤＦＰにはデータフローにおいてレジスタ遅延が必要である。そうでないと、極めて長い組み合わさった遅延および非同期フィードバックが発生し得る。遅延は、いくつかの機能（例えばほとんどのＡＬＵに対して）の入力側および通信ネットワークのいくつかルーティングセグメントに挿入されると仮定する。レジスタはタイミングを変えるが、正しいＣＤＦＧの機能を変更しないことに注意されたい。
【０７３９】
４  コンフィギュレーションの生成
４．１  言語の定義
以下のＨＬＬ機能は、ここに説明する手法によってサポートされていない：
・ポインタ演算
・ライブラリコール、オペレーティングシステムコール（標準Ｉ／Ｏ関数を含む）
・再帰的な関数コール（非再帰的な関数コールは、機能のインライン化によって取り除くことができ、したがってここでは考慮しないことに注意されたい）
・すべてのスカラデータは整数型に変換される。整数値はＲＤＦＰにおける「データ」パケットと等価である。アレイ（多次元のこともある）がここで唯一考察される複合型データタイプである。
【０７４０】
以下の付加的な機能がサポートされている：
INPORTSおよびOUTPORTSは、ＨＬＬ関数getstream(name, value)およびputstream(name, value)によってそれぞれアクセスすることができる。
【０７４１】
４．２  高級レベル言語構成体のマッピング
この手法により、ＨＬＬプログラムは、３．１節に定義したＲＤＦＰ機能からなるＣＤＦＧに変換される。処理を開始する前にすべてのＨＬＬプログラムアレイは、ＲＤＦＰ ＲＡＭ機能にマッピングされる。アレイｘはＲＡＭ ＲＡＭ(ｘ)にマッピングされる。いくつかのアレイが同じＲＡＭにマッピングされる場合、オフセットも割り当てられる。ＲＡＭは、初期状態では空のＣＤＦＧに付け加えられる。すべてのプログラムアレイに対して、十分なサイズのＲＡＭが必要なだけなければならない。
【０７４２】
ＣＤＦＧはＨＬＬプログラムのＡＳＴを縦断することによって生成される。これは、プログラムを１命令ずつ処理して適宜、ループおよび条件文内に降りていく。縦断中には各プログラムポイントで以下の２つの情報部分が更新される（プログラムにおいて「プログラムポイント」とは、２つの命令文の間、またはループまたは条件文などのプログラムコンポーネントの開始の前または終了の後のことである）：
・STARTは、ＲＤＦＰ機能のイベント出力側をポイントする。この出力側は、プログラム実行がこのプログラムポイントに到達すると必ず0-eventを供給する。はじめにイベント入力側がプリロードされた0-CONSTANTがＣＤＦＧに付け加えられる。（これはコンフィギュレーションの直後、0-eventを供給する。）STARTは初期状態ではその出力側をポイントする。このイベントは、プログラム全体の実行をスタートするために使用される。プログラム部分の実行が終了した後に生成されるSTARTｎｅｗ信号が、後続のプログラム部分に対する新しいSTART信号として使用されるか、またはこれは全体プログラムの終了を通知する。STARTイベントによって保証されるのは、データの依存関係だけでは不十分な場合にも必ずオリジナルのプログラムの実行順序が維持されることである。このスケジュール方式は、ディジタルハードウェアの「ワンホットコントローラ（one-hot controller）」に類似している。
【０７４３】
・VARLISTは、{変数、機能出力}ペアのリストである。これらのペアは、整数の変数またはアレイ要素をＣＤＦＧ機能の出力にマッピングする。VARLISTの１変数に対する最初のペアは、目下のプログラムポイントにおいて有効なこの変数の値を形成する機能の出力を含む。新しいペアはつねにVARLISTの先頭に加えられる。表現VARDEF(ｖａｒ)は、VARLISTにおける「変数」ｖａｒを有する最初のペアの「機能出力」を示す。（VARLISTを使用するこの手法はTransmogrifierＣコンパイラ[５]から採用した。）
以下の項は、すべてのＨＬＬプログラムコンポーネントを系統的にリストアップし、またこれらがどのように処理されるかを説明する。ここではＣＤＦＧ，STARTおよびVARLISTが変更される。
【０７４４】
４．２．１  整数表現および割り当て
アレイアクセスのない直線的な（straight-line）コードは、データフローグラフに直接マッピングすることができる。プログラムの演算子毎に１ＡＬＵが割り当てられる。ＡＬＵは自己同期であるため、明示的なコントロールまたはスケジューリングは不要である。したがってこの割り当ての処理ではSTARTにアクセスしないか、またはSTARTは変更されない。データの依存関係（これはプログラムのＤＡＧ表現において明らかになる[１]）は、VARLISTの処理を介して解析される。これらの割り当ては、データフローを介してそれ自体で同期化される。データドリブンの実行により、利用可能な命令レベルの並列性が自動的に引き出される。
【０７４５】
すべての割り当てにより、右辺（ＲＨＳ right-hand side）またはソース表現が評価される。この評価によって、ＣＤＦＧオブジェクト（または以下に定義する擬似オブジェクト（pseudo-object））の出力へのポインタが得られる。整数割り当てに対して、左辺（ＬＨＳ left-hand side）変数ないしはターゲットが、ＲＨＳ結果オブジェクトと結合され、新たなペア{ＬＨＳ，result(ＲＨＳ)}が形成され、これがVARLISTの先頭に加えられる。
【０７４６】
最も簡単な命令文は、整数への定数の割り当てである。（以下の例に対してＣ言語の構文を使用することに注意されたい。）
ａ ＝ ５；
これはＣＤＦＧを変更しないが、{ａ，５}をVARLISTの先頭に追加する。定数５は「擬似オブジェクト」であり、値を保持するが、ＣＤＦＧオブジェクトを参照しない。いまや後続のプログラムポイントにおいて、ａが再定義されるまでVARDEF(ａ)は５に等しい。
【０７４７】
整数割り当ては、すでに定義された変数および定数を結合することもできる。
ｂ ＝ ａ ＊ ２ ＋ ３；
ＡＳＴでは、ＲＨＳはすでに表現ツリーに変換されている。このツリーは、以下のように旧いＣＤＦＧオブジェクトおよび新しいＣＤＦＧオブジェクト（これらはＣＤＦＧに加えられる）の結合に変換される。すなわち、このツリーの各演算子（内部ノード）は、このツリーの演算子に相応するオペコードを有するＡＬＵによって置き換えられる。リーフノードが定数の場合、ＡＬＵの入力側はこの定数に直接接続される。リーフノードが整数の変数ｖａｒの場合、これはVARLISTにおいて参照される。すなわちVARDEF(ｖａｒ)が取り出される。つぎにVARDEF(ｖａｒ)（ＣＤＦＧに既に存在するオブジェクトの出力または定数）がこのＡＬＵの入力側に接続される。この表現ツリーにおけるルートの演算子に相応するＡＬＵの出力がＲＨＳの「結果」として定義される。最終的に新しいペア{ＬＨＳ，result(ＲＨＳ)}がVARLISTに加えられる。上記の２つの割り当てが処理されると、図２の２つのＡＬＵを有するＣＤＦＧが形成される。（入力および出力側の名前は、図１を参照して、その位置からわかることに注意されたい。またコンパイラフロントエンドにより、ふつう第２の割り当てがｂ＝１３（定数伝播）によって置き換えられていることにも注意されたい。この説明を簡単にするため、この例および以下の例ではフロントエンド最適化を考慮していない）。VARLISTに発生する出力は、ローマ数字でラベル付けされている。これらの２つの割り当ての後、VARLIST ＝ [{ｂ，Ｉ}，{ａ，５}]である。（リストの先頭は左側である。）定数に接続されるすべての入力は（表現ツリーから直接取り出されるか、またはVARLISTから取り出されるかにかかわらず）定数として定義しなければならないことに注意されたい。定数として定義される入力は、図２において入力の矢印の隣に小文字のｃを有している。
【０７４８】
４．２．２  条件付き整数割り当て
整数の割り当てだけを含む条件付きのif-then-else命令文に対して、条件評価のためのオブジェクトが最初に形成される。条件の結果を示すオブジェクトイベント出力は、後に正しい分岐結果を選択するために保存される。つぎにVARLISTの別個のコピーVARLIST1およびVARLIST2を使用して２つの分岐が並列に処理される。（VARLISTそれ自体は変更されない。）最終的に、VARLIST1またはVARLIST2に加えられるすべての変数に対して、VARLISTに対する新たなエントリが形成される（結合フェーズ）。VARLIST1およびVARLIST2からの有効な定義はＭＵＸ機能と結合され、正しい入力が条件結果によって選択される。２つの分岐のうちの１つにおいてのみ定義された変数に対して、マルチプレクサは、別の分岐に対するオリジナルのVARLISTから取り出した結果を使用する。このオリジナルのVARLISTがこの変数に対してエントリを有しない場合、特殊な「未定義」の定数値が使用される。しかしながら機能的に正しいプログラムではこの値は決して使用されることはない。最適化として、if-then-else構造の後、「ライブ（live）」の変数 [１]だけを結合フェーズにおいてVARLISTに加えるだけでよい。（定義：プログラムポイントにおいて変数が「ライブ（live）」であるとは、中間の再定義なしにそこから到達可能な命令文においてその値が読み出される場合である。）
つぎの例を考察する。
【０７４９】
ｉ ＝ ７；
ａ ＝ ３；
ｉｆ （ｉ ＜ １０） ｛              ａ ＝ ５；
ｃ ＝ ７；
｝
ｅｌｓｅ ｛
ｃ ＝ ａ − １；
ｄ ＝ ０；
｝
図３は結果的に得られるＣＤＦＧを示している。if-then-else構成体の前ではVARLIST ＝ [{ａ，３}，{ｉ，７}]である。分岐を処理した後、ｔｈｅｎ分岐に対してVARLIST1 ＝ [{ｃ，７}，{ａ，５}，{ａ，３}，{ｉ，７}]であり、ｅｌｓｅ分岐に対してVARLIST2 ＝ [{ｄ，０}，{ｃ，Ｉ}，{ａ，３}，{ｉ，７}]である。結合の後、VARLIST ＝ [{ｄ，II}，{ｃ，III}，{ａ，lV}，{ａ，３}，{ｉ，７}]である。
【０７５０】
ｃａｓｅまたはswitch命令文も処理できることに注意されたい。それはこれらが（一般性を失うことなく）ネスティングされたif-then-else命令に変換できるからである。
【０７５１】
条件文のこのような処理には明示的な制御は不要であり、またSTARTは変更されない。２つの分岐は並列に実行され、データフローによって同期化される。データフローをパイプライン化してスループットを最適化することが可能である。
【０７５２】
４．２．３  一般的な条件文
アレイアクセス（以下の４．２．７節を参照されたい）または内側ループを含む条件文は、４．２．２節で説明したように処理することはできない。データパケットは、アクティブな分岐にだけ送信しなければならない。これは、[４]に示された方法と類似して図８に示した実現によって達成される。
【０７５３】
２つの分岐の「使用されたセット（used set）」ｕｓｅおよび「定義されたセット（defined set）」ｄｅｆ[１]を計算するためにデータフロー解析を行う（変数が命令文（またしたがってこの命令文を含むプログラム領域（region））に「使用されている（used）」とは、その値が読み出される場合である。変数が命令文（または領域で）「定義されている（defined）」とは、新たな値がこれに割り当てられる場合である）。ＩＮ ＝ ｕｓｅ(ｔｈｅｎ本体)∪ｄｅｆ(ｔｈｅｎ本体)∪ｕｓｅ(ｅｌｓｅ本体)∪ｄｅｆ(ｅｌｓｅ本体)∪ｕｓｅ(ヘッダ)におけるすべての変数の目下のVARLISTエントリに対して、ＩＦ条件によって制御されるDEMUX機能が挿入される。図８において二重線を有する矢印は、ＩＮにおけるすべての変数に対する接続を示しており、また影付きDEMUX機能は、ＩＮにおける変数に対して１つずつの複数のDEMUX機能を表すことに注意されたい。DEMUX機能は、選択された分岐にだけデータパケットを転送する。新しいVARLIST1およびVARLIST2は、DEMUX機能の相応の出力と共にコンパイルされる。ｔｈｅｎ分岐は、VARLIST1と共に、またｅｌｓｅ分岐はVARLIST2と共に処理される。最後に出力値が結合される。ＯＵＴは、ＩＮと同じ変数に対して新しい値を含む。ただ１つの分岐だけがアクティブにされるため、２つのパケットが同時に到着したことに起因するコンフリクトは発生しない。上記の結合は条件命令文の後、VARLISTに加えられる。ＩＦ実行をパイプライン処理したい場合、出力に対するMERGEオペコードも挿入しなければならない。これらはDEMUX機能のような条件によって制御される。
【０７５４】
[４]に対して以下の拡張（図８の点線）を加えたのは、上でSTARTイベントに関連して述べたように、実行を制御するためである。START入力は、条件出力とECOMBにより結合されており、DEMUX機能のＳＥＬ入力側に接続されている。ｔｈｅｎ本体およびｅｌｓｅ本体のSTART入力側は、ECOMB出力から生成されており、ここでこのECOMB出力は、1-FILTERまたは0-CONSTANT（0-CONSTANTが必要であるのは、STARTイベントがつねに0-eventでなければならないからである。）を介して、または0-FILTERを介して送信される。全体的なSTARTｎｅｗ出力は、ｔｈｅｎ本体およびｅｌｓｅ本体のSTARTｎｅｗ出力の単純な「２対１接続」によって生成される。この拡張により、任意にネストされた条件文またはループをｔｈｅｎ本体およびｅｌｓｅ本体内で処理することができる。
【０７５５】
４．２．４  WHILEループ
WHILEループは、[４]に示されているのと類似の方式で処理される。図９を参照されたい。４．２．３節と同じように、２重線の接続線と影付きのMERGEおよびDEMUX機能は、ＩＮにおけるすべての変数毎に多重になっていることを示している。ここでＩＮ ＝ ｕｓｅ(while本体)∪ｄｅｆ(while本体) ∪ｕｓｅ(ヘッダ）である。WHLEループはつぎのように実行される。第１のループの繰り返しでは、MERGE機能は、ループ入口（ＳＥＬ ＝ ０）におけるVARLISTからすべての入力値を選択する。MERGE出力は、ヘッダおよびDEMUX機能に接続される。while条件が真の場合（ＳＥＬ ＝ １）、入力値はwhile本体に転送され、その他の場合、ＯＵＴに転送される。while本体の出力値は、条件が真である場合、MERGEおよびDEMUX演算子を介してwhile本体の入力側に供給し直される。最終的には最後の繰り返しの後、これらはＯＵＴに転送される。これらの出力は新しいVARLISTに加えられる。（ループの開始およびwhile本体の開始においてライブでない変数に対するMERGE機能はその出力が使用されていないため、除去できることに注意されたい。これらの変数に対して最終値を出力するDEMUX機能だけが必要である。またコンフィギュレーション処理により、フィードバック値が到着する前にＩＮ１からパケットが到着することが保証される場合、このMERGE機能を単純な「２対１接続」で置き換えられることにも注意されたい。）
[４]に対する２つの拡張が加えられている（図９の点線）：
・[４]では、MERGE機能のＳＥＬ入力に０がプリロードされる。それゆえにループの実行は直ちに開始され、１度だけ実行できるのである。その代わりにSTART入力側と、MERGEのＳＥＬ入力側とを接続する（ヘッダ出力側との「２対１接続」）。これによってループ実行のスタート時間を制御し、またこれを再スタートさせることができる。
・while本体のSTART入力側は、ヘッダ出力側と接続され、これは上記のように1-FILTER／0-CONSTANTの結合を介して送信される（ループの繰り返し毎に0-eventを生成する）。MERGE機能のＳＥＬ入力側に対して、while本体のSTARTｎｅｗ出力と、ヘッダ出力とをECOMBで結合することによって、ループのつぎの繰り返しは、前の繰り返しが終了した後でなければ開始されない。whileループのSTARTｎｅｗ出力は、0-eventに対するヘッダ出力をフィルタリングすることによって生成される。
【０７５６】
このような拡張によって、任意にネストされた条件文またはループをwhile本体内で処理することができる。
【０７５７】
４．２．５  ＦＯＲループ
ＦＯＲループは、特殊であるが正規のWHILEループである。したがってこれらは上に説明したように処理することができる。しかしながら、ここのＲＤＦＰは、専用のカウンタ機能ＣＮＴおよびデータパケット乗算機能MDATAを備えており、これらを使用してＦＯＲループを一層効率的に実現することができる。この新しいＦＯＲループ方式は図１０に示されている。
【０７５８】
ＦＯＲループは、カウンタＣＮＴによって制御される。下限（ＬＢ Lower Bound）、上限（ＵＢ Upper Bound）およびインクリメント（ＩＮＣ）表現は、他の任意の表現と同じように評価され（４．２．１および４．２．７節を参照されたい）、相応の入力側に接続される。
【０７５９】
WHILEループとは異なり、MERGE／DEMUXの結合は、ＩＮ１ ＝ ｄｅｆ(ｆｏｒ本体)における変数だけに必要である。すなわち、これはｆｏｒ本体において「定義」される変数だけに必要である。（コンフィギュレーション処理により、フィードバック値が到着する前につねにＩＮ１からのパケットがDEMUX入力側に到着することが保証される場合、MERGE機能は単純な「２対１接続」に置換できることに注意されたい。）ＩＮ１は、ｆｏｒ本体にだけ「使用される」変数、ＬＢ，ＵＢまたはＩＮＣを含まず、またループのインデックス変数も含まない。ＩＮ１の変数は、WHILEループと同じように処理されるが、MERGEおよびDEMUX機能のＳＥＬ入力側はＣＮＴのＷ出力側に接続される。（このＷ出力側は、WHILEループのヘッダ出力側の逆を行う。カウンタが終了した後、これは1-eventを出力する。したがってMERGE機能の入力およびDEMUX機能の出力はここではスワップされ、MERGE機能のＳＥＬ入力側には1-eventがプリロードされる。）
ＣＮＴのＸ出力側は、ループインデックス変数の現在値を供給する。ＦＯＲループの後、最終的なインデックス値が必要な場合（ライブ）、これはＣＮＴのＵイベント出力（これはループの繰り返し毎に１イベントを形成する）によって制御されるDEMUX機能によって選択される。
【０７６０】
ＩＮ２ ＝ ｕｓｅ(ｆｏｒ本体)＼ｄｅｆ(ｆｏｒ本体)における変数、すなわちループの外側で定義され、またループ内だけで使用される（しかし再定義されない）変数は上記とは異なって処理される。これが一定値でない場合、この変数の（VARLISTからの）入力値は、ループの繰り返し毎に再形成しなければならない。それはこれが各繰り返しの際に消費されるからである。そうでなければ、このループは第２の繰り返し以降、停止することになる。ＳＥＬ入力側がＣＮＴのＵ出力側に接続されて、パケットがMDATA機能によって再形成される。このＳＥＬ入力側には1-eventをプリロードして第１入力側を選択しなければならない。最後の繰り返しによって供給される1-eventにより、このループ全体のつぎの実行に対して新しい値が選択される。
【０７６１】
以下の制御イベント（図１０の点線）は、上記のWHILEループの拡張と同様であるが一層単純である。ＣＮＴのSTART入力側は、ループの全体的なSTART信号に接続されている。STARTｎｅｗは、ＣＮＴのＷ出力側から生成され、これは1-FILTERおよび0-CONSTANTを介して送信される。ＣＮＴのＶ出力側は、ループの繰り返し毎に0-eventを形成し、したがってｆｏｒ本体のSTARTとして使用される。最終的にＣＮＴのＮＥＸＴ入力側は、ｆｏｒ本体のSTARTｎｅｗ出力側に接続される。
【０７６２】
（以下の４．２．６節に定義するような）パイプライン化されるループに対して、ループの繰り返しは重なり合うことができる。したがってＣＮＴのＮＥＸＴ入力側を接続する必要はない。ここではカウンタは、インデックス変数値および制御イベントを、これが消費され得る速さで形成する。しかしながらこの場合にＣＮＴのＷ出力は全体的なSTARTｎｅｗ出力として十分ではない。それは最後の繰り返しのｆｏｒ本体が終了する前にカウンタが終了するからである。その代わりにｆｏｒ本体のSTARTｎｅｗ出力とECOMBで結合されたＣＮＴのＵ出力からSTARTｎｅｗが生成され、ここでこれは1-FILTER／0-COUNTERの結合を介して送信される。ECOMBは、各ループの繰り返しが終了した後、イベントを形成するが、「最後の」イベントだけが1-eventである。それはＣＮＴのＵ出力側の最後の出力だけが1-eventだからである。それゆえにこのイベントは、最後の繰り返しが終了したことを示すのである。パイプラインを有するおよびこれを有しないＦＯＲループの例示的なコンパイルについては４．３節を参照されたい。
【０７６３】
WHILEループについては、この手法により、任意にネストされたループおよび条件文を処理することできる。WHILEループによる実現に対して以下の利点が得られる。
・各クロックサイクルにおいて１インデックス変数値がＣＮＴ機能によって生成される。これは、MERGE／DEMUX／ADDループと、カウンタ機能に対して比較器とを割り当てるWHILEループによる実現よりも高速でありかつサイズが小さい。
・（ｆｏｒ本体にのみ使用される）ＩＮ２における変数は、専用のMDATA機能において再形成され、MERGE／DEMUXループを通過する必要はない。これもまたWHILEループによる実現よりも高速でありかつサイズが小さい。
【０７６４】
４．２．６  ベクトル化およびパイプライン化
ここまで説明した手法により、ＲＤＦＰにおいてＨＬＬプログラムの機能を実行するＣＤＦＧが生成される。しかしながらこのプログラムの実行は、START信号によって過度に順次化（sequentialize）されている。場合によっては最も内側のループを「ベクトル化」することができる。すなわち、ループの繰り返しはオーバラップすることができ、ループ本体の演算子を介してパイプライン化されたデータフローが得られる。パイプラインベクトル化技法[６]は、ここに示すコンパイル手法に簡単に適用可能である。上記のようにＦＯＲループに対してＣＮＴのＮＥＸＴ入力側は除去されて、ＣＮＴは連続してカウントし、これによってループの繰り返しがオーバラップするのである。
【０７６５】
アレイアクセスのないすべてのループはパイプライン化することができる。それはデータフローによって「ループキャリードの依存関係」が自動的に同期化される、すなわち１つの繰り返しにおける命令文と、後続の繰り返しにおける別の命令文との間の依存関係が自動的に同期化されるからである。アレイアクセスを有するループは、このアレイ（すなわちＲＡＭ）アクセスがループキャリードの依存関係を発生させないか、またはこのような形態に変換できる場合にパイプライン化することできる。この場合、１つの繰り返しにおいて書き込まれ、また後続の繰り返しにおいて読み出されるＲＡＭアドレスはない。したがって同じＲＡＭに対する読み出しおよび書き込みアクセスが、オーバラップできるのである。この程度の自由度が、以下で説明するＲＡＭアクセス技法において活用されている。これにより、殊にデュアルポートＲＡＭに対して性能が格段に改善される。
【０７６６】
４．２．７  アレイアクセス
スカラ変数とは異なり、プログラムの正しい実行順序を維持するためにアレイアクセスは明示的に制御しなければならない。通常のデータフローマシンモデル[３]とは異なり、ＲＤＦＰは単一のアドレス空間を有しない。むしろアレイはいくつかのＲＡＭに割り当てられるのである。このことがＲＡＭアクセスを処理するために別のアプローチに結びつき、また最適化に対する新しいチャンスが開かれるのである。
【０７６７】
コンパイル処理の複雑さを低減するため、アレイアクセスは２つのフェーズで処理される。フェーズ１は、ＲＡＭ読み出しおよび書き込みアクセスに対して「擬似機能（pseudo-function）」を使用する。ＲＡＭ読み出し機能は、データ入力側（読み出しアドレス）ＲＤおよびデータ出力側（読み出し値）ＯＵＴを有し、またＲＡＭ書き込み機能は、ＷＲおよびデータ入力側ＩＮ（書き込みアドレスおよび書き込み値）を有する。これらの２つの機能は、アクセスが参照するアレイによってラベル付けされ、また両者ともイベント入力側STARTおよびイベント出力側Ｕを有する。これらのイベントにより、アクセス順序が制御される。フェーズ２では同じＲＡＭへのすべてのアクセスが結合されて、図１に示したように単一のＲＡＭ機能によって置き換えられる。これには、データおよびイベントの入力および出力の操作が含まれ、これによって正しい実行順序が維持され、また出力がＣＤＦＧの正しい部分に転送される。
【０７６８】
フェーズ１  アレイはいくつかのＲＡＭに割り当てられるため、同じＲＡＭへのアクセスだけを同期化しなければならない。別個のＲＡＭに対するアクセスは並行に行うことができ、またはアウトオブオーダ（out-of-order）に行うことさえ可能である。データが相互に依存する場合、アクセスは自動的に自己同期化される。パイプライン化されるループ内では、同じＲＡＭへの読み出しおよび書き込みアクセスさえも同期化する必要はない。これは、ＲＡＭ毎に別個のSTART信号を維持することによって、またはパイプライン化されるループにおけるＲＡＭ読み出しおよびＲＡＭ書き込みアクセスに対して別個のSTART信号を維持することによって行われる。基本ブロック[１]（基本ブロックは、単一の入口と単一の出口ポイントを有するプログラム部分であり、すなわち直線的コーディングの一部である）の終わりにはすべてのSTARTｎｅｗ出力は、ECOMBによって結合され、つぎの基本ブロックに対するSTART信号が供給されるようにしなければならない。これによって前の基本ブロックにおけるすべてのアレイアクセスが終了することが保証される。パイプライン化されるループに対してはこの条件を緩めることさえも可能である。ループ出口の後、すべてのアクセスが終了しているいればよい。個々のループの繰り返しは、同期化する必要がない。
【０７６９】
まずＲＡＭアドレスが計算される。アレイアクセスに対するコンパイラフロントエンドの標準の変換を使用することができ、ＣＤＦＧ機能の出力が生成され、これによってアドレスが得られる。適用可能であれば、ＲＤＦＰ ＲＡＭに関するオフセット（初期のマッピングフェーズにおいて決定される）を加算しなければならない。この出力は、（読み出しアクセスに対して）擬似ＲＡＭ読み出しの入力側ＲＤに接続されるか、または（書き込みアクセスに対して）擬似ＲＡＭ書き込みの出力側ＷＲに接続される。付加的に出力ＯＵＴ（読み出し）または入力ＩＮ（書き込み）が接続される。START入力は変数の信号STARTに接続され、また出力Ｕはつぎのアクセスに対するSTARTｎｅｗとして使用される。
【０７７０】
冗長な読み出しアクセスを避けるため、ＲＡＭ読み出しもVARLISTに登録される。整数の変数の代わりにアレイ要素がペアの最初の要素として使用される。しかしながら、アレイインデックスにおいて発生すく変数の変更により、VARLISTにおける情報が無効になる。この場合にはこれをそこから除去しなければならない。
【０７７１】
２つの読み出しアクセスを有する以下の例は、図１２に示した中間のＣＤＦＧにコンパイルされる。START信号は変数ａだけを参照する。STOP1はこれらのアクセスを同期化するイベント接続線である。入力START（old），ｉおよびｊは、このアレイの読み出しの前にプログラムから得られる実際の出力によって置き換えられるべきである。
【０７７２】
ｘ ＝ ａ[ｉ]；
ｙ ＝ ａ[ｊ]；
ｚ ＝ ｘ ＋ ｙ；
図１３は、以下の書き込みアクセス、すなわち
ａ[ｉ] ＝ ｘ；
の翻訳を示している。
【０７７３】
フェーズ２
さてここで同じＲＡＭに対するすべてのアクセスの擬似機能をマージして、これらを単一のＲＡＭ機能で置き換える。すべてのデータ入力側（読み出しアクセスに対するＲＤおよび書き込みアクセスに対するＷＲおよびＩＮ）に対して、これらの入力側とＲＡＭ機能との間にＧＡＴＥを挿入する。これらの入力側Ｅは、元々の擬似機能の相応の入力側STARTに接続される。ＲＡＭがただ１つのプログラムポイントにおいて読み出されまた書き込まれる場合、読み出しおよび書き込みアクセスの出力側Ｕはそれぞれ出力側ＥＲＤまたはＥＷＲに移動される。例えば、図１３の単一のアクセスａ[ｉ] ＝ ｘ；は、図５に示した最終的なＣＤＦＧに変換される。
【０７７４】
しかしながら、同じＲＡＭに対して複数の読み出しまたは複数の書き込みアクセス（すなわち相異なるプログラムポイントからの擬似機能）が行われる場合、ＥＲＤまたはＥＷＲもはや固定ではない。しかしながら元々の擬似機能のSTARTｎｅｗイベントは、相応のプログラムポイントに対して、すなわち「現在のアクセス」に対してだけ生成されるべきである。これは同じタイプ（読み出しまたは書き込み）の別のすべてのアクセス（擬似機能）のSTART信号と、現在のアクセスの「反転された」START信号とを接続することによって達成される。結果的に得られる信号は、アクセス毎にイベントを生成するが、現在にアクセスだけに対して1-eventを生成する。このイベントは、ECOMBによってＲＡＭの出力側ＥＲＤまたはＥＷＲと結合される。ECOMBの出力は、このアクセスが終了した後にだけ行われる。ECOMBはそのイベントパケットをＯＲ結合するため、現在のアクセスだけが1-eventを形成する。つぎにこのイベントが1-FILTERによってフィルタリングされ、0-CONSTANTによって変更されて、STARTｎｅｗ信号が得られる。これは、要求されるように現在のアクセスが完了した後だけに0-eventを形成する。
【０７７５】
複数のアクセスに対して、複数のソースがＲＡＭの入力側ＲＤ，ＷＲおよびＩＮに接続される。これによって自己同期化はできなくなる。しかしながら１時点に１アクセスしか発生しないため、ＧＡＴＥはこれらの入力側に１つのデータパケットだけしか到着させないのである。
【０７７６】
読み出しアクセスに対して出力側ＯＵＴにおけるパケットにＲＤイベントパケットと同じ問題が発生する。すなわち、これらは読み出しアクセス毎に発生するが、現在のアクセスに対してだけ使用され、（また後続の演算子に転送され）なければならないのである。これはDEMUX機能を介して出力側ＯＵＴを接続することによって達成可能である。このDEMUXの出力Ｙが使用され、出力Ｘは未接続のままである。この場合にこれは選択的なゲートとして機能し、これは入力側ＳＥＬが1-eventを受信する場合にだけパケットを転送し、またＳＥＬが0-eventを受信する場合にそのデータ入力を廃棄する。STARTｎｅｗ信号に対して上で述べたECOMBによって形成される信号は、現在のアクセスに対して1-eventを形成し、その他の場合に0-eventを形成する。これをＳＥＬ入力として使用することによってまさに所望の機能が達成されるのである。
【０７７７】
図４は、フェーズ２の変換を図１２に適用した後に、上記の第１の実施例（２つの読み出しアクセス）に対して結果的に得られるＣＤＦＧを示している。STOP1はここではつぎのように生成される。すなわち、START(old)が反転され、STOP1に対して「２対１接続」され（なぜならばこれは第２の読み出し擬似機能のSTART入力だからである）、ＲＡＭの出力ＥＲＤとECOMB結合され、1-FILTER／0-CONSTANTの結合を介して送信される。START(new)も同様に生成されるが、ここではSTART(old)は直接使用されて、STOP1が反転される。入力側ＩＮ（ｉおよびｊ）に対するＧＡＴＥはSTART(old)およびSTOP1にそれぞれ接続され、出力ｘおよびｙに対するDEMUX機能は、STOP1およびSTART(new)に関連してECOMB出力に接続される。
【０７７８】
多重書き込みアクセスは同じ制御イベントを使用するが、入力側ＲＤに対するアクセス毎に１ＧＡＴＥを使用する代わりに、ＷＲに対して１ＧＡＴＥと、（同じ入力Ｅの）ＩＮに対して１ゲートとを使用している。出力ＥＷＲは、読み出しアクセスに対する出力ＥＲＤと同じように処理される。
【０７７９】
この変換によって保証されるのは、すべてのＲＡＭアクセスが正しく実行されることであるが、これはあまり高速ではない。それは同じＲＡＭへの読み出しまたは書き込みアクセスはパイプライン化されないからである。使用されるＲＡＭが複数のパイプラインステージを有する場合であっても、つぎのアクセスがスタートするのは、前のアクセスが終了した後だけである。このような効率の悪さはつぎのようにして取り除くことができる。
【０７８０】
基本ブロック内の（混ざっていない）読み出しアクセスまたは書き込みアクセスのいずれかの第１の連続的な「シーケンス」はつぎのようにして検出される。すなわち、出力Ｕが同じＲＡＭの別の擬似機能の入力側STARTに直接接続接続され、また同じタイプ（読み出しまたは書き込み）である擬似機能をチェックすることによって検出されるのである。これらのシーケンスに対して、前のアクセスが完了するのを待つ代わりに、このＲＡＭにデータを流すことができる。このためにMERGE機能の結合によって、上記のシーケンスによって与えられる順序で入力側ＲＤまたはＷＲおよびＩＮが選択される。これらのMERGEは、入力を所望の順序でのみ転送することを保証する繰り返しＥＳＥＱによって制御しなければらない。この場合にこのシーケンスにおける最初のアクセスだけを１つまたは複数のＧＡＴＥによって制御すればよい。同様に読み出しアクセスの出力ＯＵＴは、シーケンスに対して、より効率的に分配することができる。DEMUX機能と、同じＥＳＥＱ制御との結合を使用可能である。最も効率的であるのは、MERGEおよびDEMUX機能をバランスされたバイナリツリーとして配置構成することである。
【０７８１】
STARTｎｅｗ信号はつぎのように生成される。長さｎのシーケンスに対し、シーケンス全体のSTART信号がESEQ[00..1]機能によってｎ回複製され、ここで入力側STARTはこのシーケンスのSTARTに接続される。その出力側は、別のアクセスの（単一のアクセスに対する）START信号か、（シーケンスアクセスに対する）0-CONSTANTを介して送信される出力ＥＳＥＱか、ＥＷＲまたはＥＲＤに接続されたECOMBかのいずれかにそれぞれ直接「Ｎ対１接続され」、また上記の基本的な手法と同様に1-FILTER／0-CONSTANT結合を介して送信される。最後の出力ＥＳＥＱだけが1-eventであるため、要求されるようにこの「最後の」ＲＡＭアクセスだけがSTARTｎｅｗを生成する。択一的には読み出しアクセスに対して、最後の出力の生成は、（入力側Ｅを接続することなしに）ＧＡＴＥを介して送信することができ、これによってイベントSTARTｎｅｗが生成される。
【０７８２】
図１４は、STARTｎｅｗを生成するためにＥＳＥＱ手法を使用した第１の例（図１２および４）の最適化バージョンを示しており、また図６は、３つのアレイの読み出しを有する比較的大きな以下に示す例、すなわち
ｘ ＝ ａ[ｉ]；
ｙ ＝ ａ[ｊ]；
ｚ ＝ ａ[ｋ]；
の最終的なＣＤＦＧを示している。
【０７８３】
複数の読み出しシーケンスまたは読み出しシーケンスおよび単一の読み出しアクセスが同じＲＡＭに対して発生する場合、「現在のアクセス」を検出するための複数の1-eventを読み出しアクセスのシーケンスに対して生成しなければならない。これらは、別個のシーケンスに関連するＯＵＴ値を分離するために必要である。1-CONSTANTを介して送信される上で定義したＥＳＥＱ出力によってこれが達成される。ここでもこれは、（単一アクセスに対する）別のアクセスのSTART信号または（シーケンスアクセスに対する）0-CONSTANTを介して送信される出力ＥＳＥＱに「Ｎ対１接続される」。結果的に得られるイベントは、第１ステージのDEMUXを制御するために使用され、これは、基本的な手法に対して上で述べたのと同じようにシーケンスの関連するOUT出力データパケットを選択するために挿入される。完全な例については４．３節における第２の例（図１５および１６）を参照されたい。
【０７８４】
４．２．８  入力および出力ポート
入力および出力ポートはベクトルアクセスと同様に処理される。入力ポートからの読み出しは、アドレスのないアレイ読み出しのようなものである。入力データパケットは、DEMUX機能に送信され、このDEMUX機能は、後続の正しい演算子にこれを送信する。INPORTの出力Ｕと、現在のSTART信号または他のSTART信号とを結合することにより、ＲＡＭアクセスに対して上で説明したのと同じようにしてＳＴＯＰ信号が生成される。
【０７８５】
出力ポートは、ＧＡＴＥライクなアレイ書き込みアクセスによってデータパケットを制御する。ＳＴＯＰ信号もＲＡＭアクセスと対するのと同様に形成される。
【０７８６】
４．３  別の例
図７は、以下のｆｏｒループに対して生成されるＣＤＦＧを示している。
【０７８７】
ａ ＝ ｂ ＋ ｃ；
ｆｏｒ （ｉ＝０；ｉ＜＝１０；ｉ＋＋）｛
ａ ＝ ａ ＋ ｉ；
ｘ[ｉ] ＝ ｋ；
｝
この例において、ＩＮ１ ＝ {ａ}およびＩＮ２ ＝ {ｋ}（図１０を参照されたい）である。変数ａに対するMERGE機能は４．２．５節の注記で述べたように２：１データ接続によって置き換えられる。変数ｂ，ｃおよびｋに対して１つのデータバケットが到着し、最終的に１つのパケットが（ｏｕｔ）に対して形成されることに注意されたい。ｆｏｒ本体はSTARTイベントを使用していない。それは２つの演算子（加算器およびＲＡＭ書き込み）はいずれにせよカウンタによってデータフロー制御されるからである。しかしながらＲＡＭの出力ＥＷＲは、ｆｏｒ本体のSTARTｎｅｗであり、ＣＮＴの入力側ＮＥＸＴに接続されている。パイプライン化の最適化（４．２．６節）はここでは適用されていないことに注意されたい。これが適用される場合（このループに対しては可能である）、ＣＮＴの入力側ＮＥＸＴは接続されない。図１１を参照されたい。ここではループの繰り返しはオーバラップする。４．２．５節の終わりに定義したようにSTARTｎｅｗは、ＣＮＴの出力側Ｕおよびｆｏｒ本体のSTARTｎｅｗ（すなわちＲＡＭの出力側ＥＷＲ）から生成される。
【０７８８】
以下のプログラムは、アレイ（ＲＡＭ）ｘへの書き込みアクセスと、アレイ（ＲＡＭ）ｙへの２つの読み出しアクセスのシーケンスとを有するベクトル化可能な（パイプライン処理される）ループを含む。このループの後、ｙへの別の単一の読み出しアクセスが行われる。すなわち、
ｚ ＝ ０；
ｆｏｒ （ｉ＝０； ｉ＜＝１０； ｉ＋＋）｛      ｘ[ｉ] ＝ Ｉ；
ｚ ＝ ｚ ＋ ｙ[ｉ]＋ｙ[２＊ｉ]；      ｝
ａ ＝ ｙ[ｋ]；
である。
【０７８９】
図１５は、アレイアクセスのフェーズ２の変換が適用される前に生成される中間のＣＤＦＧを示している。このパイプライン化されるループは、つぎのように制御される。すなわち、ループ内ではｘへの書き込みアクセスおよびｙへの読み出しアクセスに対して別個のSTART信号が使用される。ｆｏｒ本体部へのリエントリは２つの独立した信号（「cycle1」および「cycle2」）によって制御される。読み出しアクセスに対して、「cycle2」は、読み出しアクセスｙが正しい順序で行われることを保証する。しかしながら読み出しアクセスｙと、書き込みアクセスｘと対する繰り返しのはじめは同期化されていない。ループ出口においてのみすべてのアクセスが終了していなければならず、これは信号「ループ完了」によって保証される。上記の単一の読み出しアクセスは、ループとは完全に独立している。
【０７９０】
図１６は、フェーズ２の後の最終的なＣＦＤＧを示している。単一の書き込みアクセスには付加的な制御は不要であるため、「cycle1」が取り除かれ、また挿入されるMERGEおよびDEMUX機能によって正しい実行順序が自動的に保証されるため、「cycle2」が取り除かれていることに注意されたい。読み出しアクセスｙはもはや独立していない。それはこれらすべて同じＲＡＭを参照しており、また機能がマージされているからである。ＥＳＥＱは、読み出しシーケンスのMERGEおよびDEMUX機能を制御するために割り当てられており、また読み出しＯＵＴ値を読み出しシーケンスに対しておよび最終の単一読み出しアクセスに対して分離する第１ステージのDEMUXの機能に対して割り当てられている。ECOMB，1-FILTER，0-CONSTANTおよび1-CONSTANTは４．２．７節においてフェーズ２で説明したように割り当てられており、これによってＧＡＴＥおよびDEMUX機能に対して正しい制御イベントが生成される。
【０７９１】
参考文献
[1] A.V.Aho, R.Sethi, and J.D.Ullman. Compilers - Principles, Techniques, and Tools. Addison-Wesley, 1986,
[2] The Stanford SUIF Compiler Group.  Homepage http://suif.standford.edu
[3] A.H.Veen.  Datafolw architecture. ACM Computing Surveys, 18(4), December 1986.
[4] S.J.Allan and A.E.Oldehoeft.  A flow analysis procedure for the translation of high-level languages to a data flow language.  IEEE Transactions on Computers, C-29(9):829-831, September 1980.
[5] D.Galloways. The transmogrifier C hardware description language and compiler for FPGAs.  In Proc. FPGAs for Custom Computing Machines, pages 136-144. IEEE Computer Society Press, 1995.
[6] M.Weinhardt and W.Luk.  Pipeline vectorization.  IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, 20(2), February 2001.
【図面の簡単な説明】
【０７９２】
【図１】ＲＤＦＰの機能一覧を示す図である。
【図２】整数の割り当てを示す図である。
【図３】条件付きの整数の割り当てを示す図である。
【図４】図１２にフェーズ２の変換を適用した後、２つの読み出しアクセスに対して得られるＣＤＦＧを示す図である。
【図５】図１３の単一のアクセスを変換して最終的に得られるＣＤＦＧを示す図である。
【図６】３つのアレイの読み出しを有する例の最終的なＣＤＦＧを示す図である。
【図７】ｆｏｒループに対して生成されるＣＤＦＧを示す図である。
【図８】一般的な条件文のテンプレートを示す図である。
【図９】whileループのテンプレートを示す図である。
【図１０】ｆｏｒループのテンプレートを示す図である。
【図１１】パイプライン化の最適化が適用されたｆｏｒループのテンプレートを示す図である。
【図１２】２つの読み出しアクセスを有する例をコンパイルして得られた中間のＣＤＦＧを示す図である。
【図１３】書き込みアクセスの翻訳を示す図である。
【図１４】STARTｎｅｗを生成するためにＥＳＥＱ手法を使用した第１例（図１２および４）の最適化バージョンを示す図である。
【図１５】アレイアクセスのフェーズ２の変換が適用される前に生成される中間のＣＤＦＧを示す図である。
【図１６】フェーズ２の後の最終的なＣＦＤＧを示す図である。
【図１】
2005535055.tif 000217
【図２】
2005535055.tif 000218
【図３】
2005535055.tif 000219
2005535055.tif 000220
【図５】
2005535055.tif 000221
【図６】
2005535055.tif 000222
【図７】
2005535055.tif 000223
【図８】
2005535055.tif 000224
【図９】
2005535055.tif 000225
【図１０】
2005535055.tif 000226
【図１１】
2005535055.tif 000227
【図１２】
2005535055.tif 000228
【図１３】
2005535055.tif 000229
【図１４】
2005535055.tif 000230
【図１５】
2005535055.tif 000231
【図１６】
2005535055.tif 000232
【国際調査報告】
2005535055.tif 000233
2005535055.tif 000234
2005535055.tif 000235