画像提供:マイナビニュース

写真拡大

●アーキテクチャの変更が行われた「Bifrost」

今年の「Hot Chips 28」の冒頭を飾ったのは、ARMの「Bifrost GPU」の発表である。学会での論文発表のプログラムは、最初に興味深い発表を持ってきて、朝から参加者が多くなるようにするというのが一般的である。ARMのBifrostの発表がトップバッターに選ばれたというのは偶然ではなく、多くの参加者が聞きたがる良い論文と評価されたからであろう。

なお、Bifrostというのは北欧神話に出てくる燃える虹の橋で、人間の世界であるMidgardと神の世界であるAsgardの間に架かっている。現在、スマートフォンなどに使われているMali T600〜T800 GPUはMidgardアーキテクチャで、BifrostアーキテクチャのMali G71 GPUは、今年の終わり頃にはハイエンドスマートフォンに搭載が始まると考えられる。

Mali G71については、今年5月に発表されているが、学会での発表は、今回のHot Chips 28が最初であり、同社のフェローで、テクノロジ関係のVPであるJem Davies氏が発表を行った。

まず、Davies氏は、同社のMali GPUは2015年には7億5000万コア出荷され、世界で出荷量ナンバーワンということをアピールした。

そして、初代のUtgardアーキテクチャは、頂点シェーダとピクセルシェーダが分離されたアーキテクチャであったが、2代目のMidgardアーキテクチャでは、両方が共通のユニファイドシェーダとなり、今回のBifrostアーキテクチャでは、スカラISA、Clause実行に代わったと説明した。

技術的に見て一番大きな変更は、Bifrostではシェーダコアの設計を従来のSIMDから、スカラのクローズ(Clause)ベースの命令を処理するようにしたことである。また、シェーダコアの最大搭載数を32個と倍増し、ジオメトリデータの流れを変更して、必要メモリバンド幅やメモリ使用量を減らしたことも性能向上に寄与している。

結果として、同一の半導体プロセスで作ったMali-T880と比較して、エネルギー効率は20%改善し、メモリバンド幅は20%改善、面積当たりの性能は40%改善したとのことである。

Bifrost GPUでは、シェーダコアが最大32個並ぶ構成が取れるようになった。そして、メモリはL2キャッシュとメモリコントローラが1対1になるメモリサイドキャッシュ構成を取り、4チャネルのメモリをサポートしている。

そして、次の図に見られるように、ジョブマネージャが32個のシェーダコアでの実行を制御し、MMU(Memory Management Unit)と画面をタイルに分割して描画処理を行うタイラーがあるという構成になっている。

シェーダコアは3つの実行エンジンを持っている。各実行エンジンは、Quadと呼ばれる4つの演算を並列に実行することができる。大まかに言うと、1個のシェーダコアはNVIDIAのCUDAコア12個分の演算ができる。

そして、コンピュートフロントエンドと対のQuad Creatorが計算用のQuadを作り、フラグメントフロントエンドと対のQuad Creatorがピクセル処理用のQuadを作って、Quadマネージャに実行命令を供給する。

シェーダコアは、その他にLoad/Storeユニット、Attributeユニット、Varyingユニット、Textureユニット、Blender&Tileユニット、Depth&Stencilユニットなどを持っている。Depth&StencilユニットはDepthやStencilを処理するためのZSメモリに繋がっている。

次の図は、現在のMidgardアーキテクチャのGPUの実行状況を示す図で、各サイクルには1つのスレッドの命令を実行する。そして、1つのスレッドから、命令の順序を入れ替えたりして、4つの並列に実行できる命令を見つけて、まとめて実行できるようにするのは、コンパイラの役目である。しかし、必ずしも4つの並列に実行できる命令が見つかるとは限らず、次の図のようにLane 3では実行すべき命令がなく、演算器が遊んでしまうということが起こる。

●低消費電力と省メモリ化を図りながら性能を向上

これに対して、Bifrostアーキテクチャでは、前の図と次の図を見比べると、実行の順番が90度回転している。1サイクルには、1つのスレッドの命令を実行するのではなく、サイクル1には4つのスレッドのxを処理する命令、サイクル2には4つのスレッドのyを処理する命令のように実行する。各演算器(Lane)は1つのスレッドの命令だけを実行する。これは、スカラ処理の場合と同じ実行である。

前の図ではLane 3は遊んでいたが、このように実行すると、次の図に示すように、すべてのLaneが使われ、3サイクルですべての処理が終わっている。

この実行方式は、SIMT(Single Instruction Multiple Thread)方式であり、NVIDIAが最初に採用したのであるが、現在では、AMDのGCNアーキテクチャのGPU、IntelのHD Graphics Gen 9、そして、今回のARMのBifrost GPUと、主要GPUのほとんどがSIMT実行に切り替わっている。

Bifrostの実行ユニットは4つの32ビット乗算を並列に実行するFMAと4つの32ビット加算を並列に実行するADD/SFで構成されている。加算器は、逆数や平方根などを計算するSF(Special Function Unit)と一体化して作られている。そして、メインレジスタから入力オペランドを読み、演算結果をメインレジスタに書き込む。

実行エンジンは32ビットのfloat32データだけでなく、半分の長さのfloat16の2つの演算を並列に実行することができる。また、整数の演算の場合は、1つのint32演算、2つのint16演算、4つのint8演算を行うことができる。

スマートフォンなどでは、消費電力を低く抑えるため、シェーダの演算は必要な精度が得られる最低のビット数で行うのが一般的で、16ビットや8ビットの演算も多用されるので、このような構成が採られている。

Bifrostアーキテクチャでは、必ず連続して実行される命令の列をクローズと呼び、クローズの終了時にはメインレジスタなどにアーキテクチャ状態が格納されているように動作させる。一方、クローズの中では演算結果をメインレジスタには書き込まず、テンポラリレジスタでデータを受け渡すことができるアーキテクチャとなっている。テンポラリレジスタを使うことにより、メインレジスタよりも使用エネルギーが少なくて済み、消費電力を減らすことができる。

次の図の左が通常のソースコードで、最初にr0にロードを行い、依存関係があるFADD.32命令が6個続いている。そして、最後にr0の値をメモリにストアしている。

中央のコードはクローズコンパイルを行った例で、ロード命令を1つのクローズとし、その他の命令をまとめて2番目のクローズにしている。そして、2番目のクローズは、ロードが終わるのを待つwait指定が付けられている。

右側のコードは最初のロードを1番目のクローズ、6個の連続したFADD命令を2番目のクローズ、最後のストア命令を3番目のクローズとしている。2番目のクローズの中ではメインレジスタに正しいアーキテクチャ状態が書き込まれることを保証しなくても良いので、テンポラリレジスタ(tの付いたレジスタ)を使っている。

そして、ストアは最後のFADDの結果を入力オペランドとして使っているので、中央のコードでは待ち時間が長くなる可能性がある。このため、右側のコードでは、ストアは別クローズとして、スケジューリングの自由度を上げている。

1つのタイルに入ってしまうトライアングル、4つのタイルにまたがるトライアングルのように階層的に分類して処理するのはMidgardアーキテクチャと同じであるが、Bifrostアーキテクチャでは、タイルのバッファの割り当ての単位を小さくし、左端の図の2行目の右端のタイルに見られるようなマイクロトライアングルは除去してしまうように変更した。細かいトライアングルが大量に存在する場合では、これはメモリ削減効果が大きい。結果として、メモリ使用量が最大95%小さくなったという。

また、インデックスを使ったポジションシェーディングを行うことにより、Positions処理のメモリアクセスが平均3.5回から2回、Attribute処理のメモリアクセスが平均2.5回から1.5回と大幅に減ったという図が示されたが、詳しい説明はなく、なぜ、メモリアクセスが減るのかは分からなかった。

最高性能を狙うディスクリートGPUの場合は、CPUのメモリとGPUメモリは別々に設けられるが、Cortex-A73 CPUとMali G71 GPUの場合は、同じメモリを使い、次の図のように、キャッシュコヒーレンシをサポートするCoreLink CCI-550で接続される。このため、CPUとGPUのメモリのコヒーレンシが保たれ、使い勝手が良くなる。

まとめとして、Bifrost GPUは最大32シェーダコアまで拡張が可能で、シェーダコアを再設計している。新コアでは、命令がスカラ型のクローズベースとなり、クワッドベースの演算ユニットとなっている。

また、ジオメトリ処理の改良で、必要メモリバンド幅と必要メモリ量を減らしている。そして、CPUとGPUのキャッシュコヒーレンシから、細粒度のバッファの共用が可能になっていると述べた。