Voltaでは命令エンコーディングを一新
命令のエンコーディングであるが、次の図は、Kepler、Maxwell/PascalとVoltaの命令エンコーディングの例を示している。Keplerでは7個の64bit命令に対して、1語の制御ワードが置かれていた。これがMaxwell/Pascalになると、3つの64bit命令に対して1語の制御ワードが置かれるようになった。
そして、Voltaでは1命令が2語(128bit長)となり、2語目の先頭に制御命令が書かれるという構造になり、従来とはまったく違うエンコーディングになっている。CPUで一般的なバイナリ互換など知ったことではないというCPU設計者から見ると大胆不敵な設計である。
ただし、IBMメインフレームのように、ソースコードが行方不明でバイナリしか残っていない、50年前にCOBOLで書いたプログラムが今でも動くというような世界はGPUでは望むべくもない。
そして、赤丸で囲ったVolta命令の制御部分の内訳が次の図の一番下に書かれている。4bitが各オペランドのレジスタ値をReuse Cacheに格納するかどうかを示すReuse Flag、6bitが可変レーテンシの命令(他方の使用状態で実行時間が変わる共有リソースのアクセスなど)を待ち合わせる場合、使用するバリア番号をWrite Barrier Indexに書き込み、さらに使用されているバリアのビットマップであるWait Barrier Maskにもセットする。
Read Barrier Indexは、メモリへの書き出しが行われるまでレジスタの値を書き変えてはいけないというバリアを指定する3bitのRead Barrier Indexである。
Yield Flagは1ビットで、負荷の調整に使われる。このFlagがセットされていると、スケジューラは現在のワープから次の命令を選ぶ方向で命令実行を行う。一方、Flagがクリアされている場合は、次の命令は異なるワープから選ばれる傾向となる。
Stall Cyclesは、次の命令の発行まで待つサイクル数を指定する。この欄は4bitであるので、0~15サイクルの待ちを挿入することができる。
Voltaのメモリ階層
Volta V100のメモリ階層は次の図のようになっている。この図の一番外側の緑のボックスはGPU全体、二番目の赤のボックスはStreaming Multiprocessor(SM)、一番内側の青いボックスはプロセサブロックである。V100 GPUの場合、GPUには80個のSMがあり、SMの中には4個のプロセサブロックが含まれる。
そして、プロセサブロックは16Kエントリの32bitレジスタファイルを持ち、実行ユニットとして8個のFP64演算器、16個のFP32演算器、16個のINT演算器、8個のLD/STユニット、4個のSFUと2個のTensorコアを持っている。 メモリ階層は、プロセサブロックは64KiBのレジスタファイルと12KiBのL0命令キャッシュを持ち、SMレベルでは128KiBのL1データキャッシュ/シェアードメモリを持つ。このメモリアレイは、L1データキャッシュとシェアードメモリに分割して使用でき、シェアードメモリは最大96KiBまでを使用できる。
SMレベルは128KiBのL1命令キャッシュと64KiB以上のL1.5定数キャッシュ/128KiB L1命令キャッシュを持つ。そして、GPUレベルには6144KiBのL2キャッシュとTLBがあり、L2キャッシュは16GiBのHBM2 DRAMのメモリサイドキャッシュとなっている。
VoltaのTLBは3階層で、TLBのページサイズは、L1は2MiB、L2は128MiB、L3は2GiBとなっている。なお、x86 CPUとのUnified Memoryを実現するためにCPUと同じ4KiBページのTLBを持っているはずであるが、この論文では記述がない。
次の図は、Pascal P100のメモリ階層とVolta V100のメモリ階層を比較した図である。大きな違いは赤で囲んだ部分で、PascalではL1データキャッシュとシェアードメモリが分離されていたが、Voltaでは可変の分割ができる一体型のアレイとして作られている点である。
また、Pascalの8KiBのL1命令キャッシュはSM単位であるが、Voltaではこれが各プロセサブロック単位に変更されて12KiBのL0命令キャッシュとなっている。SM単位で見るとPascalは8KiBであるが、Voltaは48KiBと4倍に増加している。命令エンコーディングのところ述べたように、命令サイズが長くなっているので格納命令数では、4倍にはなっていないが、命令供給系が強化されていることが分かる。
(次回は5月30日に掲載します)