ReLM = Register-Less Multiprocessor
ReLMは独自のメモリアーキテクチャによるソフトコアマルチプロセッサで、比較的小型なFPGA上に高性能なマイクロコントローラを構築することが可能です。
FPGA上の開発で最も負荷が大きいのが論理合成ですが、ソフトウェアの変更に関しては論理合成が不要なので、FPGAにおける回路設計のサポートツールとして利用することも可能です。
開発中はFPGAの回路を固定した上でソフトウェアをホストPCから読み込む形でデバッグ作業を行い、最終的にはソフトウェアを固定して自立したマイクロコントローラとして動作させることも可能になります。
さらに、回路の最適化と組み合わせれば、ASIC開発への応用も可能です。
現状、PCやモバイル機器で使用されるプロセッサは相応の性能が要求されるため、マルチコア構成が通常となっています。
これらの機器ではOSやアプリが大容量のSDRAM等で構成される共有メモリに置かれるため、各プロセッサコアでは必要となるデータを一部キャッシュメモリにコピーして使うことでフォン・ノイマン・ボトルネックを回避しています。
アプリケーションソフトウェア側では特にキャッシュメモリの存在を意識する必要は無く、あたかも巨大な共有メモリ上でプログラムが動いているかのような感覚でプログラミングが出来て便利です。
反面、ハードウェア側での代償は小さくなく、キャッシュメモリはユーザー側からは直接利用できない実質的に無駄なメモリ領域であるにも関わらずプロセッサ回路の大部分を占め、消費電力も相応に増大します。
特に別々のキャッシュメモリが共有メモリの重複する領域のコピーを保持するような場合、メモリ一貫性を維持するための処理はかなり複雑になりがちです。
基本的には外部に巨大な共有メモリが存在することを前提としており、比較的大規模なシステムに特化した方式といえます。
- Pros
- 共有メモリのアクセスが容易。
- Cons
- アクセス調停機構が複雑。
- 比較的大規模なシステムに限られる。
より効率や性能を必要とする特殊な用途のマルチプロセッサでは、ローカルストアまたはスクラッチパッドメモリと呼ばれるプロセッサコア個別に分割された、比較的小規模で高速なメモリ領域を利用する方法もあります。
ソフトウェア側では他のコアやスレッドからは直接見えないメモリ領域を扱う必要があり、並列処理のアルゴリズム構築には特別なテクニックが必要となります。
ハードウェア面では共有メモリやキャッシュメモリと比較して複雑なアクセス調停機構が不要となり単純化が可能となりますが、実用的には何らかのプロセッサ間通信の手段を用意する必要があります。
Cell/B.E.のSPEはその典型的な例で、メモリアクセスをローカルストアに限定し、外部との通信はメインメモリとのDMA転送に頼る必要があったため、これが利用の上で大きな問題となりました。
- Pros
- 複雑なアクセス調停機構が不要。
- 比較的小規模なシステムでも対応可能。
- Cons
- 比較的小規模なローカルメモリをやりくりする必要があり、ソフトウェアが複雑化。
- 共有メモリのアクセスが不能または間接的で複雑。
それでは、以下の条件を満たす理想的なマルチプロセッサのメモリアーキテクチャは実現可能でしょうか?
- 複雑なアクセス調停機構を必要としない。
- 共有メモリの利用が容易。
- 比較的小規模なシステムにも対応可能。
実は、特殊なアーキテクチャのマルチプロセッサを仮定すると、これらを実現する方法があります。
- 共有メモリをアドレスの下位ビットでバンク分割し、各メモリバンクをプロセッサコアに直結する。
- 各コアは接続されたメモリバンクから命令とオペランドをフェッチし、命令実行結果の内部状態全てを隣接するプロセッサに移動する。
- 全てのコアで同時に命令フェッチと実行が行われ、全体が回転する形で一斉に内部状態の移動が実施される。
- これにより、全てのスレッドは環状に接続されたプロセッサを巡回する形で実行を続ける。
特に命令実行毎に内部状態をプロセッサ間で移動するという点がこの構成の最も顕著な特徴で、従来のプロセッサアーキテクチャでは実現困難な制約条件となります。
この不可能とも思われる課題に挑戦し、実用的なレベルで実現した成果がReLMアーキテクチャになります。
- 従来のプロセッサによく見られる命令パイプラインでは内部状態が複雑すぎて移動が困難。
- ReLMアーキテクチャでは全ての命令は1サイクルで実行される。
- 命令フェッチの同時アクセスは可能だが、別にメモリデータの読み書きが発生する場合、結局は調停が必要?
- ReLMアーキテクチャでは命令フェッチとデータアクセスを区別しない。
- コードメモリの任意の番地のオペランドを読み書き可能。
- 内部状態にレジスタファイル全体も含まれるため、レジスタ数が多いと移動の負荷も増大する。
- ReLMアーキテクチャでは基本的にレジスタはアキュムレータとその他必要最低限に限定。
- 実際にはコードメモリのオペランドがレジスタ代りとなるため、大量のレジスタは不要。
ReLMアーキテクチャのハードウェアでは、命令実行毎にスレッドの実行主体となるCPUが切り替わりますが、これをソフトウェア側から見ると、あたかもメモリイメージがバンク切り替えのように変化して見えることになります。
実行アドレスと下位ビットが一致するバンクのみが常にCPUから見えることになるので、命令実行とともにプログラムカウンタがインクリメントされる場合、実行主体CPUの切り替えにより次の命令のフェッチと実行が可能になります。
ここで問題となるのが、命令実行の結果を共有メモリに書き込む場合です。
例えばCPU#0で実行した結果を、離れていて直接見えないメモリバンク#3に書き込む場合を考えます。
これを直接書き込み可能にしようとすると、CPUとメモリの組合せから膨大な信号配線の追加と、非常に複雑な調停機構の追加が必要になり、シンプルなメモリアーキテクチャのメリットが全て失われてしまいます。
そこで実際、この書き込み結果を同じスレッドで参照することを考えた場合、参照が可能となるのはスレッドの実行主体がCPU#3に移動した時点になりますので、それまでは書き込みを遅延しても問題ないことになります。
他のスレッドからはメモリの更新が遅れて見えることになりますが、高々CPUリング一周分の遅延ということがわかっていますので、これをスレッド間通信のオーバーヘッドとして考慮すれば許容範囲であるといえます。
ハードウェア実装ではプロセッサ内部状態に遅延書き込みの情報を追加することで、この機構を容易に実現することが可能です。
プロセッサ内部状態は、以下の要素で構成されます。
- レジスタファイル(Reg)
- プログラムカウンタ(PC)
- 遅延書き込み情報(WriteBack)
4コア構成を例に、このスレッド実行の環状パイプラインを以下に図示します。
遅延書き込み情報は対象となるメモリバンク毎に分割され、オペランド読み出しの際に書き込みも同時に実行されます。
命令コード(OpCode)の読み出しも同時に行われ、その他の情報はタイミングを合わせるためにフリップフロップ(FF)で1クロック遅延されます。
後に命令セットで触れますが、オペランドは即値形式のみなので、この時点でCPUの演算に必要な情報は全て揃っています。
そのため、CPUの実行ユニットをクロック遅延を受けない組み合わせ回路とすることで、全ての命令は1クロックのみで完了することになります。