L1データキャッシュ

AMDのGCNアーキテクチャのGPUは読み書き可能な16KBの容量の1次データキャッシュを持っている。NVIDIAのGPUは1次データキャッシュの位置づけが世代ごとに変り、最適化がやり難いが、GCNアーキテクチャの1次データキャッシュは読み書き可能なキャッシュという位置づけが一貫しているのは立派である。

GCNアーキテクチャのGPUの1次データキャッシュの構造を図8.8に示す。1次データキャッシュは、容量が16KBで、ラインサイズは64B、4wayのセットアソシアティブで、LRU入れ替えを行う。

図8.8 GCNアーキテクチャのGPUの1次データキャッシュのブロックダイヤ

1次データキャッシュへの書き込みを行う場合、CPUでは、キャッシュコヒーレンシプロトコルを使って、各コアの1次データキャッシュ間の内容に矛盾が生じないようにするのであるが、GPUの場合はWavefrontごとに64個の異なるアドレスに書き込みが行われる可能性がある。このため、書き込みを行う場合のコヒーレンシを維持するためには、膨大な数のスヌープを必要とするので、CPUのようなキャッシュコヒーレンシプロトコルの実装が難しいという問題がある。

このため、GCNアーキテクチャのGPUの1次データキャッシュは、データの書き込みに対して、他のCUの1次キャッシュとのデータの整合性はとらず、64Bのキャッシュラインの内の書き込みが行われた部分をバイト単位にダーティ(dirty)ビットを設けて記憶しておくという方法を使っている。

そして、Wavefrontの64個のすべての1次データキャッシュへの書き込みが終了した時点で、部分的にダーティなキャッシュラインを2次データキャッシュに書き戻す。この2次キャッシュへの書き込みで、コヒーレンシが取られるという造りになっている。

コンパイラは、レジスタの数が不足した場合は、レジスタの内容を1次データキャッシュに書き出してレジスタを空け、処理が終わったら、1次データキャッシュからレジスタを復元するというコードを出すのが一般的であるが、このような1次データキャッシュへのアクセスは、他の1次データキャッシュとのコヒーレンシ維持の必要はないので、細かくコヒーレンシを取る必要は無いので、この実装はムダがない。

また、グローバルメモリへデータを書き出して別のCUがその値を読む場合は、コヒーレンシを保つ特別なロード命令を使えば、最新の値を読むことができるので、特別なロード命令を使うという点で手間は掛かるが、大きな問題はない。

1次データキャッシュのアドレス計算ユニットには、Wavefrontの64個のアクセスのアドレスが送られてくる。また、他のSIMDもロードストア命令を実行していると、それらのWavefrontからのアクセスも押し寄せる。アドレス計算ユニットは一度にアクセスできる64Bのキャッシュラインに入る全てのアクセスを一まとめにするコアレス(Coalesce)処理を行って1次データキャッシュをアクセスする。

コアレスの結果、64B全部が使える場合は、16個のアクセスが処理できるので、4回の1次データキャッシュアクセスで1つのWavefrontの64個のアクセスが処理できることになる。しかし、アクセスするアドレスが連続していない場合は、もっと多くの1次データキャッシュアクセスが必要になり、時間もかかる。

なお、図8.8にはFormat ConversionやDecompressionというブロックが描かれているが、具体的に何を行っているのか説明がなく、グラフィックスの場合はともかく、数値計算でも使われているのかどうかも分からない。