プロセサ間接続バス
複数のプロセサ間を接続するにはコモンバスが一番簡単な構造であるが、コモンバスは一時には1つのプロセサしかバスを使用できないので、接続するプロセサ数が多くなってくると、メインメモリアクセスの待ち行列ができてアクセス時間が長くなり、遂には、プロセサの数を増やしても、メモリバスの性能で全体の性能が決まってしまうことになる。
初期のコモンバスは、図9.9の上側の図のように、メモリアクセスの開始から、メモリが読まれてデータが戻ってくるまで1つのプロセサがバスを占有し、その次にサービスするアクセスの調停(Arbitration)を行い、次のアクセスを開始するという構造であった。しかし、これではメモリをアクセスしている間もバスを占有してしまい効率が悪い。
これを、バスに載せる要求やデータにどのプロセサのものかという識別情報を付加する構造として、図9.9の下側の図のように、アクセス要求Req1を送り終わるとバスを開放し、次の要求の調停を行い、アクセス要求Req2の転送を行い、そして、Req1に対するメモリデータが得られたらバスを要求し、バスが獲得できたらData1をバスに載せる。Req1の要求を出したプロセサは、データに付けられた識別番号で、自分宛であることを認識して読み出しデータをバスから取り込む。同様に、Req2に対するData2が読み出されたら、バスを獲得して識別番号をつけて送り出す。このような方式とすれば、DRAMの読み出し中などの実際にはバスを使用していないタイミングは、他のプロセサがバスを使用できるようになるので効率が良い。このようなバスをSplit Transactionバスと呼び、最近では、この形式の制御を行うバスが一般的である。
なお、 Split Transactionバスの場合は、要求を送るアドレスバスとデータを送るデータバスを分離し、両者を独立に調停して使用するとさらに性能を改善することができる。このため、高いバス性能を必要とする場合は、アドレスとデータのバスを分離する構造を採るのが一般的であり、IntelのFSBもこのような分離構造となっている。
Split Transactionバスは、バスを無駄なく使うことができるが、それでも1つのバスにぶら下げるプロセサの数を増やしていくと、バスが混雑して全体の処理性能が飽和してしまう。さらに性能を上げるためには、当然、複数のバスを使うという考え方が出てくる。
最近のプロセサでは、メモリの読み書きはキャッシュラインの単位で行われるのが普通であるので、マルチプロセサの最初で述べたメモリインタリーブの考えと同様にバスインタリーブを行う。例えば、4つのバスを持つ4wayインタリーブの場合は、それぞれのプロセサやメモリシステムは、これらの4つのバスに接続されており、データのアドレスがどこであるかによって使用するデータバスを選択する。
それぞれのWayごとにバスの使用要求を調停すると、先のストアが待たされ、同一プロセサからの別のWayへの後のストアが先にメモリに反映されるということが起こりうる。例えば、先のストアが処理結果の格納であり、後のストアが処理終了を示すフラグであり、終了フラグが先にメモリに書きこまれると、他のプロセサが終了フラグを確認してから処理結果を読んでも、処理結果は、まだ、メモリに書かれていないということが発生しうる。
したがって、ストアの実行順序が逆転を許容できるシステムでは、Wayごとの調停を行っても良いが、書き込み順序を保証するシステムでは、プロセサからの全部の要求を見て、次にどのプロセサからの要求を受け付けるかを決めなければならないので、単純にWayごとに調停を分割することはできない。しかし、1キャッシュラインのデータの転送には(64バイトを16バイトずつ転送し)4サイクルを必要とするような設計が一般的であり、4wayインタリーブを行った場合では、1サイクルに1つの調停を行えば間に合い、複数の調停を並列に実行しなくても済む。
図9.10に示すSun MicrosystemsのStarfireサーバは、1枚のボードに4個のCPUチップを搭載し、このボードを最大16枚搭載して64CPUのSMP(Symmetric Multi Processor)を構成できる大型サーバである。アドレスバスは4Wayのインタリーブ構成となっており、1バスサイクルに4つのアクセス要求を処理できる。そして、グローバルデータバスは16×16のクロスバであり、受信側ボードが重複しない限りは、任意のボードペア間でのデータ転送をすべて並列に実行することができる構成である。
ボード内の4個のプロセサからのアクセス要求の調停をローカルアドレスアービタが担当し、そして、各ボードで勝ち抜いた要求を16枚のボードからの要求の調停を行うグローバルアドレスアービタに送る。この時、アドレスによってWay-0~3のどのグローバルアドレスアービタに送るかを決めてアクセス要求を送るという構成になっている。
グローバルアドレスアービタからアドレスバスの使用権を得たボードのプロセサは、アドレスをバスに載せてブロードキャストする。各ボードは自ボード内のプロセサのキャッシュをスヌープし、応答をグローバルアービタに返す。
ただし、キャッシュのタグは、CPU内部からのアクセスを処理するのが主目的であり、ここに16枚の他のボードからのスヌープアクセスを入れるとオーバフローしてしまう。このような大規模なスヌープを行うため、CPU側のキャッシュタグと同じ内容を持つDuplicate Tag(Dtag)を設けて他のボードからのスヌープを処理するという構成がとられている。
そして、グローバルアービタは全部のスヌープ結果を纏めてバスに載せて、全ボードのキャッシュコントローラ(CC)に通知する。どのプロセサのキャッシュにもヒットしない場合は、アクセスするメモリアドレスを担当するボードはメモリのアクセスを継続し、1キャッシュライン分のデータをDRAMから読み出す。そして、そのボードのローカルデータアービタを経由してグローバルデータアービタにクロスバの使用要求を送り、許可が得られたら、クロスバ経由で要求元のボードにデータを送るという流れになる。
そして、要求元のCPUはクロスバからのデータを受け取り、自分のキャッシュに格納して、1回のメモリリードが完了する。