GPUのメモリのエラーの検出と訂正

グラフィックス処理の場合は、1ピクセルの色や明るさが変わって表示されても気が付かないことが多いし、気が付いたとしても、その1ピクセルが化けたことで表示画面がまったく役に立たなくなるということはほとんど無い。座標変換マトリクスの係数が化けてしまうと影響は大きいが、このようなデータはピクセルデータに比べると量が少なく、そこでエラーが発生する頻度は低いので、グラフィック処理を行うGPUでは、エラー検出や訂正は行われていなかった。

しかし、GPUを科学計算に使用するようになると、1カ所のエラーが計算結果全体を大きく誤らせてしまうということも起こる。また、一目瞭然でエラーがあったと分かるのは良い方で、分からない程度のエラーの方がたちが悪い。サーバ用のメインメモリでは、このようなエラーを検出し、軽微な(1bitとか2bit)のエラーの場合は訂正するという機能が使われている。

これにならい、科学技術用のGPUでも、NVIDIAのTesla GPUや、AMDのハイエンドのFirePro GPUではGDDR5メモリにECCを付けてエラーの検出、訂正を行う機能を組み込んでいる。しかし、ECCを付けると、チェック用のビットが必要となるので、使用できるメモリ量が減る、チェックビットの読み書きとエラーの検出、訂正を行うため、有効に利用できるメモリバンド幅が減るという影響があるので、グラフィック処理に使う場合にはフルのメモリ容量とメモリバンド幅を生かせるように、エラー検出、訂正機能をオフできるようになっている。

ECCを行うためには、エラーの検出、訂正のためのビットが必要になる。良く使われる2bitエラー検出、1bitエラー訂正を行うSECDED符号の場合は64bitのデータに対して8bitのチェックビットを追加する必要があり、12.5%のオーバヘッドとなる。

AMDのFirePro GPUの場合は、約6%のオーバヘッドと書かれており、128ビット単位に8ビットのチェックビットでECCを付けているようである。この符号では2ビット誤りを検出できないと思われるが、1ビットエラーにしか対処しないという割り切りは有り得る。

64bitに8bitのチェックビットを付ける場合、8bit幅のDDR3/4 DRAMの場合は、9個のDRAMチップを使えば64bitのデータ+8bitのチェックビットを得ることができるが、32bit幅のGDDR5 DRAMでは、同じことを使用とすると、3チップを使って96bitとすることになり、24bitがムダになってしまう。

GDDR5 DRAMは、32bit幅でバースト長8でアクセスを行うので、1回のアクセスで256bitを読み出すことができる。この中には72bitが3つ入り、40bitあまることになる。図3.10に示すように、これを次の256bitも読み出して、そこから32bit補えば72bitが作れる。このように、必要に応じて、次のアドレスを読み出して継ぎ足していく。256bitのアクセスを9回繰り返せば2304bitが読まれ、これは72bit×32になる。DRAMを読むアドレスが9/8倍になるので、多少アドレスの計算が面倒であるが、アドレスを3bit左シフトし、1倍を足しこんで、アドレスの9倍を計算し、その後3ビット右シフトを行って1/8にすればよい。

図3.10 GDDR5 DRAMでは256bitの読み出しから72bitを切り出す

このようにチェックビットのアクセスが必要になるので、NVIDIAのGPUをECCオンで動かすと、実効的なメモリ容量が8/9に減少し、メモリのアクセス時間も若干長くなり、ある程度の性能的な影響があるが、これはやむを得ない。どうしても性能を落としたくなければ、ECCをオフにして、エラーを見逃してしまって答えが誤っているのに気づかないというリスクを選ぶしかない。

なお、HBMは、 128bitのデータに対してチェックビット用に16bitのDM_CBというビットが用意されており、このような苦労は必要ない。