GPUのメモリ階層とアクセス時間

GPUも1次データキャッシュ、2次キャッシュというメモリ階層を持っているが、CPUのメモリ階層とは、かなり、考え方が異なっている。CPUの場合は、1次キャッシュに対して2次キャッシュは、10倍程度の容量を持ち、1次キャッシュをミスしたアクセスの内のかなりの部分が2次キャッシュにヒットし、DRAMメモリにアクセスする頻度をさらに下げるという考え方になっている。特に、IntelのCoreプロセサのように、1次キャッシュに格納されているデータは、必ず2次キャッシュにも入っているというInclusion Cacheの場合は、2次キャッシュの容量は、1次キャッシュよりかなり大きくなければ意味がない。

しかし、Kepler GPUを使うK20x GPUの場合は、L1Dキャッシュの容量はSMあたり16~48KBで、15SMの合計では240~720KBである。これに(正確な容量は不明であるが)同程度の容量のL1Iキャッシュを加えると、1次キャッシュの総量は1MB程度となる。これに対して、2次キャッシュは1.5MBであり、2倍にも満たない容量である。

これは、1次命令キャッシュは複数のSMで同じプログラムを格納する場合が多いことと、1次データキャッシュはコアレスバッファ的に使われ、CPUのデータキャッシュとは位置づけが異なっていることが影響している。また、GPUはデータを連続にアクセスには強いがランダムにアクセスする場合の性能には重きを置いていないことから、容量が少なくても良いと割り切っている面がある。

GPUのGDDR5 DRAMはGPUと1対1に短い配線で結ばれている。CPUの場合は、DDR3/4を搭載したDIMMを使い、各メモリチャネルに複数枚のDIMMを芋蔓で接続するので、配線も長く、DIMMソケットなどという余計なものも付く。従って、物理的なDRAMのアクセス時間はGPUの方が、CPUよりもかなり速いはずである。

また、メモリアクセスの絶対時間ではなく、プロセサクロックのサイクル数で考えると、CPUは2~3GHzクロックであるのにGPUは1GHz程度であるので、絶対時間が同じでも、GPUのメモリアクセスに掛かるサイクル数は、さらに1/2~1/3倍になる。

従って、CPUのメインメモリのアクセスが、例えば400サイクル程度とすると、GPUのデバイスメモリのアクセスは100サイクルを切っても良いのであるが、実は、GPUのメモリアクセス時間はそれほど速くはない。

NVIDIAはGPUのメモリ階層の各構造のアクセス時間を発表しておらず、あまりデータが無いが、2013年のGPU Technology Conference(GTC)での性能最適化のチュートリアルには、図3-28に示したスライドがあり、単純な命令のレーテンシは10~20サイクルであるが、 DRAMのアクセスには400~800サイクル掛かると書かれている。

図3-28 2013年のGTCでの性能最適化の講義で示されたスライド

NVIDIAの公式な発表ではないが、メモリアクセス時間を実測してみようというユーザは当然居るわけで、NVIDIAのDeveloperのフォーラムにユーザが投稿した測定値は、

  • キャッシュを使わず、デバイスメモリを直接アクセスした場合は1060サイクル
  • L2キャッシュにヒットした場合は248サイクル
  • L1Dキャッシュにヒットした場合は18サイクル

となっている。これはGTX 580 Tiボードでの測定であるという。

しかし、GTX 480ボードでの測定で、デバイスメモリは1020サイクル、L2キャッシュは365サイクル、L1Dキャッシュは88サイクルという書き込みもあり、デバイスメモリが1000サイクル強というのは前の書き込みと一致しているが、L2キャッシュやL1Dキャッシュのアクセス時間は大きく食い違っている。

いずれにしても、GPUの場合は、1つのWarpやWavefrontの全スレッドのキャッシュアクセスをコアレスしてからメモリアクセスを開始する必要があるため、この処理に時間が掛かる。また、コアレス結果が1つのキャッシュラインに収まらないと複数回のアクセスが必要となるなどで、単純なメモリアクセスよりもずっと長い時間が掛かるようである。