サブコアは1つのワープスケジューラを持ち、ワープスケジューラは、毎サイクル、1命令をTensor Core、演算ユニット、あるいはMIO(Memory IO)のどれかに発行する。

ワープスケジューラは毎サイクル1ワープ命令の発行であるが、サブコアあたり2個のTensor Coreがあり、毎サイクル2つの4×4×4のテンソルの演算を行うことができる。また、FP64ユニットは8/clk、INTとFP32演算ユニットは16/clkとなっているので、FP64ユニットは4クロック同じ命令を実行し、INTとFP32演算ユニットは2クロック同じ命令を実行することで32スレッド分の演算を行っている。

このように、 1命令の処理に少なくとも2サイクルを必要とするので、Math Dispatch Unitは少なくとも2つの演算パイプラインをビジーにすることができる。

そして、従来SFUと呼ばれていたMUFUは4/clkであり、8クロック同じ命令を実行するようである。

サブコアは1つのワープスケジューラを持ち、毎サイクル、Tensor Core、数値演算、MIOのどれかに1命令を発行する

L1キャッシュとシェアードメモリは一体の128KBのメモリとして作られており、分割して使う。32KBの粒度で分割を変えることができ、シェアードメモリの最大容量は96KBとなっている。

L1キャッシュの容量は、P100 GPUと比べるとバンド幅、容量ともに4倍になっており、さらにレーテンシも短縮されているとのことである。

L1とシェアードメモリは一体の128KBのメモリで、分割して使う。シェアードメモリの最大値は96KBである。L1キャッシュのバンド幅、容量はP100 GPUと比べて4倍になっているという

Voltaではワープの実行の自由度が大きく広がった。Volta以前のGPUでは、ワープ全体で1つのプログラムカウンタ(PC)とスタックしか持っていなかったのに対して、Voltaでは下の図のように、ワープの中の各スレッドがPCとスタックの状態を持つようになった。

Voltaではワープ内の各スレッドがプログラムカウンタ(PC)とスタックの状態を持つ (この図の出典はNVIDIAのInside Volta: The World’s Most Advanced Data Center GPUである)

Volta以前のGPUでは、次のようなif() then{A;B;} else{X; Y;}という構文の場合、条件の成立したスレッドではAとBを実行してから、条件が成立しなかったスレッドでXとYが実行される。しかし、この実行法では、条件の成立しなかったスレッドのXの実行の結果を条件が成立したスレッドのBが待つというような処理になっている場合は、デッドロックになってしまう。

A; B;の実行の後にX; Y;を実行するやり方では、Xの実行の結果をBが待つという処理になっている場合は、デッドロックになってしまう (この図の出典はNVIDIAのInside Volta: The World’s Most Advanced Data Center GPUである)

これに対して、A; B;が終わらなければ、X;の実行が始まらないというのではなく、どのような状況でもX;のフォワードプログレスが保証される実行ができれば、デッドロックに陥ってしまうことがない。

Voltaでは、ワープ内の各スレッドが異なるアドレスの命令を実行できるので、次の図のようにA; X; B; Y;の順に実行させることができる。このため、X;の処理結果をB;が待つという処理でも正しく実行することができる。

ただし、CPUのマルチスレッドのようにハードウェアレベルでフォワードプログレスを保証しているわけではないので、適切にスレッドをグループ化して、実行の順序を決める必要があり、その辺りはコンパイラが依存関係を解析して決めていると思われる。

これにより、A、B、X、Yの順の実行だけでなく、A、X、B、Yの順の実行が可能になる (この図の出典はNVIDIAのInside Volta: The World’s Most Advanced Data Center GPUである)

V100 GPUはTensor Coreと呼ぶ新しい演算ユニットを搭載することで、ディープラーニングの演算性能を大幅に引き上げた。Tensor Coreは次の図のように4行4列の行列AとBを掛け、それに行列Cを足すという計算を行う。

FP16のA、Bの積をフル精度で計算し、それにFP32のCを加える。FP16で加算を行うモードは推論用と書かれている

行列の積には64回の積和演算が必要であり、さらに、行列Cの加算には16回の和が必要である。しかし、Cを最初にアキュムレータに入れておけば、行列の積とCの加算は128演算×640Tensor Core×1.455GHzで119.2TFlopsで実行できる。

Tensor Coreは4行4列の行列Aと行列Bを掛け、それに行列Cを加算するという計算を行う。A,BはFP16で、Cと結果DはFP16あるいはFP32とすることができる

より大きな16行16列の行列の積を計算する場合は、次の図のようにワープの同期を行ってから、4×4の行列を4×4に並べて積を計算すればよい。この計算は4×4の行列の積を64回計算する必要があるが、順番にやっていけば良い。これらの計算が終わったところで結果をすべてのワープに分配し、次の処理を始めればよい。

16×16の行列の積を計算する場合は、ワープを同期して16×16の行列の積を、4×4の行列を4×4に並べたとして順に計算を行い、計算結果をほかのワープに分配する

次の図はTensorコアを使って混合精度のcuBLASで行列積を計算した場合と、P100 GPUで行列積を計算した場合の性能を比較した棒グラフで、Tensorコアを使うことにより、性能は9.3倍に向上している。

この行列積は、ディープラーニングの人工ニューロンの入力に対する出力の計算に使われる処理であり、ディープラーニングの性能がおおむね9.3倍に向上するといっても良い。

NVIDIAのcuBLASライブラリを使ったマトリクス乗算性能の比較。P100に比べて、Tensor Coreを使った混合精度の計算では9.3倍高速になっている

まとめとして、V100は、Voltaアーキテクチャを使う最も生産性の高いGPUであり、NVLinkとHBM2の採用で効率の高いバンド幅を実現している。また、新しいSMで性能の改善とプログラマビリティの改善を実現している。特に、スレッドごとのスケジュールを可能とし、ワープ内のスレッド間で依存性のあるアルゴリズムも実行可能になっている。また、Tensorコアの導入でディープラーニングに対しては120TFlopsという画期的な性能向上を実現している。

そして、V100 GPUは、最速で、ディープラーニングとHPCの両方に対して最も生産性の高いGPUであると述べて発表を締めくくった。

Tesla V100は最速で、ディープラーニングとHPCの両方に対して最も生産性の高いGPUである