ECCの問題
グラフィックスの処理では1ピクセルのデータ誤りがあっても出力画像が大きく変わることはない。また、動画のような場合は、エラーが表示されるのは一瞬であり、見逃されてしまうことが多い。
しかし、GPUを使って科学技術計算を行なう場合は1bitのエラーも許されない場合が多い。このため、NVIDIAはFermi世代のGPUからECC(Error Correcting Code)をサポートしている。ECCにはいろいろなやり方があるが、NVIDIAが採用したコードは64bitの本来のデータに8bitのチェックビットを付け、72bitの中で1ビットの誤りを訂正できるというものであると考えられる。このため、ECCを付ける場合には、使用できるデバイスメモリ量が8/9に減少し、実質的なメモリバンド幅も8/9に減少してしまう。
グラフィックスに使う人は容量やメモリバンド幅を重視し、ECCでこれらが減るのは好まないし、大規模科学技術計算を行なう人にはエラーは大きな問題であるのでECCが欲しい。このため、Fermi以降のNVIDIAのハイエンドGPUは、ECCあり、無しの両モードを切り替えられるようになっている。
DDR3/4 DRAMを使うDIMMの場合は、64ビットのDIMMは×8のDRAMを8個使用し、ECC用には9個のDRAMを使う72ビットのDIMMが使われるのであるが、GDDR5 DRAMにはこのようなチェックビットが無い。このため、チェックビットを付けるためには工夫が必要になる。
NVIDIAが、前述の÷6の問題と、ECCのための9ビット目のメモリをどのように捻出しているかについては公開された情報は無く(実はNVIDIAに質問したのであるが、開示できないとして、教えてくれなかった)、以下の記述は筆者の推測である。
考えられるのは、 32bit×8のアクセス単位のブロックが1つのGDDR5 DRAM中では順に並んでいると考え、通常のECC無しの場合は8個のブロックを連続してアクセスして256バイトのデータブロックとして扱う。ECCを付ける場合は9個のブロックを連続してアクセスして288バイトのブロックを作り、256バイトはデータブロックとし、最後のブロックをチェックビットとして扱うという方法である。
これ以外の方法もあり得るが、ECCの追加の8bitを読むために、別のチャネルのGDDR5 DRAMを読むのは面倒であるし、メモリバンド幅的にも好ましくなく、1個のメモリチップに64bitデータと8bitのチェックビットが収まる図3-52のアドレス付けが一番理に適っていると思われる。
この場合、図3-52に示すように、8個の32バイトブロック(256バイト)、ECC付きの場合は9個の32バイトブロック(288バイト)を単位として、12個のGDDR5 DRAMを順に回るというアドレスを振る。あるいはペアで16個の32バイトブロック、ECC付きの場合は18ブロックを単位として6つのペアを順に回るというアドレス付けを行う。
1つのGDDR5ペアから512バイトのデータを連続して読み出すので、小容量の読み出しではメモリチップの分散は起こらないが、GPUでは32スレッドのワープで連続した128バイトをアクセスするというようなケースが多いので、まあ、妥当なところであろうと思われる。
GPUの2次キャッシュ
GPUコアからこれらのデバイスメモリへのアクセス時間を短縮し、メモリバンド幅を向上させるために2次データキャッシュが設けられているが、CPUの2次キャッシュとは作り方が違う。
図3-53の左側の図のように、2次キャッシュは複数の2次キャッシュのスライスから構成されるが、CPUコアがアクセスするスライスはコアとペアになっているものとは限らず、アクセスするアドレスでどのスライスをアクセスするかが決まる。また、データのアドレスがどこであるかとは無関係にメモリをアクセスしたスライスがそのデータをキャッシュする。従って、図の赤線の矢印で示すデータの転送は、どのようなペアでも起こり得る。
一方、図3-53の右側の図のように、GPUの2次キャッシュは、メモリコントローラと1対1に設けられ、メモリコントローラも直接、2個のGDDR5メモリチップと対応する。そして、それぞれの2次キャッシュは、それが接続されるGDDR5メモリのデータだけをキャッシュする。2次キャッシュスライスとコア(SM)の間にはクロスバがあり、コアはどの2次キャッシュスライスにもアクセスすることはできるが、CPUのように2次キャッシュスライスとメモリコントローラの対応は可変にはならない構造となっている。
対応するGDDR5 DRAMのデータしかキャッシュしないというGPUの方式では、GDDR5メモリのアドレスは一意に付けられているので、1つのアドレスのデータが2つ、あるいはそれ以上の2次キャッシュスライスに格納されるということは絶対に起こらず、複数の2次データキャッシュ間で同じアドレスのデータがあるという問題が起こらない。従って、キャッシュコヒーレンシの問題は発生せず、キャッシュコヒーレンシプロトコルも不要で、簡単に実装ができる。
この方式の2次キャッシュは、GDDR5 DRAMのアクセス時間の短縮やメモリバンド幅を向上させるために設けられていると見ることができ、メモリキャッシュと呼ばれることもある。