(NVIDIAの)GPUは32スレッドのワープ単位で命令を実行する。次の図のLD.E R2,[R6]という命令はR6に格納されているアドレスのメモリを読み出し、その値をR2に格納するという命令である。R6レジスタに格納されている値であるが、スレッドごとに独立のR6レジスタがあるので、各スレッドのR6レジスタにどのような値が入っているかはケースバイケースである。
このメモリアクセスをスレッドからみると、それぞれのスレッドは4あるいは8バイトのデータをメモリから読むという要求を出しているのであるが、SMとしてみると、32のスレッドがメモリの読み出しを要求しており、アドレスが1つのキャッシュライン(128バイト)に入っている場合は一括して処理できるが、別のキャッシュラインにまたがっている場合は、そのキャッシュラインを読み出して処理を行う必要が出る。この別のキャッシュラインの読み出しをNVIDIAは「replay」と呼んでいる。
また、L2キャッシュやDRAMからみると、読み出すアドレスのキャッシュラインがL2キャッシュに入っている場合は、それを読み出してSMに送ればよいが、L2キャッシュに入ってない場合は、DRAMから読み出してL2キャッシュに入れるという操作が必要になる。
スレッドから見ると、4バイトあるいは8バイトのメモリの読み出しであるが、SMから見ると、32のLoad要求が来る。1つのキャッシュラインに入るアドレスのLoadは一括して処理できるが、別のキャッシュラインにまたがる場合は、そのキャッシュラインを読み出すreplayが必要となる |
個々のスレッドから見ると、メモリバンド幅は単位時間にどれだけのデータを受け取れるかということになる。従って、バンド幅はスレッドごとのレーテンシの逆数に比例する。
一方、SMから見ると、バンド幅は、単位時間にすべてのスレッドに合計でどれだけのデータを届けられるかということになる。この場合のバンド幅の計算の分母は、他の仕事をしていない純粋なレーテンシの逆数に比例する。
そして、L2キャッシュやメモリから見ると、毎秒、どれだけのデータを移動させたかということになる。
次の図は、これを書き直したものであるが、個々のスレッドからみれば1つのリクエストであるが、SMは32個の異なるアドレスへのリクエストを処理することが必要になる。このアドレスが1つのキャッシュラインに収まらない場合はreplayが必要になる。
SMは32個のアドレスを受け取るのであるが、同じキャッシュラインへの複数のアクセスを合体して処理する機能を持っている。このため、全てのアクセスが同じ128バイトのキャッシュラインに入っている場合は1回のアクセスですべてのアクセスを処理することができる。この場合、SMは1つのキャッシュラインの読み込みを行うだけで済み、L2キャッシュやDRAMは4回の読み込み(L2やDRMは32バイト単位であるので)を行えば済む。
しかし、32スレッドのアクセスするアドレスがバラバラで、それぞれが異なるキャッシュラインとなる場合は、最悪、32の異なるキャッシュラインを読み込むことが必要となる。
なお、ここでは、Readのケースで書いたが、メモリアクセスという点では、Writeでも同じ事になる。