後藤弘茂のWeekly海外ニュース

AMD GPUとモバイルGPUで同じプログラムを走らせるHSA構想



●AMDが立ち上げたHSA Foundationが目指すもの

 AMDはヘテロジニアス(Heterogeneous:異種混合)コンピューティング時代のためのプログラミングモデルHSA(Heterogeneous System Architecture)を構築しようとしている。AMDの戦略の特徴は、NVIDIAのように、ほぼ自社だけで推進するのではなく、他のチップベンダーを巻き込んだHSAのアライアンス「HSA Foundation」を組み立てることにある。そのために、HSAフレームワークの鍵となる要素をオープン化して他社を引き込もうとしている。

 AMDのこうした呼びかけに応えたのは、主にモバイル系のチップのARMやImagination Technologies(PowerVRを開発)、Texas Instrumentsといったベンダー群だった。スマートフォンやタブレットにGPUやCPUコアのIPやSoC(System on a Chip)を提供するベンダーがAMDに乗った。急成長するモバイル市場のプレイヤーをHSAのサポーターとして迎えたことで、HSA構想は勢いに乗った。

HSA FoundationはARM、ImaginationのIPベンダー、TI、MediaTekらのSoCベンダーがファウンダーに HSA Foundationの活動内容

 HSA構想の最終的なゴールは、同じ並列プログラムが、異なるベンダーのGPUコアや並列プロセッサの上で、“手を加えなくても”効率的に走るようにすること。そうすれば、GPUコアを使ったアプリケーションが花開き、エコシステムが成立するというのがAMDの構想だ。そして、HSAアライアンスの数の力によって、他のハードベンダーとのアライアンスに積極的ではないNVIDIAとIntelに対して、ヘテロジニアスコンピューティングの競争で優位に立つことも可能になる。

 ベンダー横断でのGPUプログラミングの共通化なら「OpenCL」や「DirectCompute」で、すでに始まっているのでは、と思うかも知れない。ここでポイントは、AMDが目指しているのが、単純にOpenCLや「C++AMP」といった上位のプログラミング言語レベルの共通化ではない点だ。その下層にある、中間言語(下位コンパイラのインターフェイス)である「HSAIL」と、CPUとGPU間での共有メモリモデル、オーバーヘッドの小さなディスパッチ&実行モデル、アーキテクチャフィーチャにいたるまで、ベンダー横断での標準化を、ある程度図ろうとしている。これまでになかった試みだ。

 この構想を単純化したのが下のスライドだ。現状では、各社がバラバラの実行モデルや中間言語で、異なるアーキテクチャフィーチャをカバーしている。例えば、NVIDIAのCUDAがあり、IntelのMICアーキテクチャがある。それに対して、HSAではベンダーを横断して、共通化したランタイムや中間言語、アーキテクチャフィーチャをもたらす。

 HSAの導入は、ソフトウェアデベロッパー側から見ると、アプリケーションの実行効率が高くなり、パフォーマンスの予測がし易くなり、揃ったフィーチャを期待できるようになり、共通化した最適化ライブラリの構築が容易になるという利点がある。HSAによって、GPUコアなどを活かした並列プログラミングを容易にして、ヘテロジニアスコンピューティング全体を活性化させようとしている。

 最終的には、同じGPUプログラムを変更することなく、AMD GPU、ARM Mali、PowerVRといったGPUコアでも効率良く走る。また、同じ枠組みのプログラミングモデルでTexas InstrumentsのDSPコアなど、他のアクセラレータにもアクセスできるようになる。これがAMDのビジョンだ。

●バーチャルISAモデルがマルチベンダーを可能にする

 AMDのHSAフレームワークが、他社の支持を得ることができた背景には、GPUのプログラム実行モデルがバーチャルISA(Instruction Set Architecture)ベースであるという事情もある。GPUの場合、ネイティブ命令であるGPU固有のISAはプログラマに対して露出されない。中間言語をJIT(Just In Time)コンパイラで動的に変換することでプログラムを実行する。そのため、コンパイラのインターフェイスとなる中間言語が実質的なISAとなる。

 AMDのHSA構想では、プログラム実行モデルの中間言語(IL:Intermediate Language)としてHSAILを導入する。そして、HSAのモデルでは、バーチャルISAであるHSAILを拡張して、AMDだけでなく、他社のプロセッサもカバーすることが示されている。HSAILは最終的に、AMD GPUコアだけでなく、他社のGPUコアや並列プロセッサもカバーするバーチャルISAになる見込みだ。HSAILは、NVIDIAのPTXに当たる中間言語レイヤーだが、他社デバイスまで積極的にカバーしようとする姿勢が異なる。

 HSAがやろうとしていることは、CPUならば、ネイティブのISAをAMDに合わせることを提案するようなものだ。CPUなら、AMDと共通のx86 ISAのCPUを作ることで、同じプログラムを走らせることができるようになる。しかし、そのためにはCPUのアーキテクチャをかなり変更しなければならない。

 それに対して、GPUの場合は、バーチャルISAで抽象化されているため、GPUコアのネイティブISA自体を合わせる必要はない。バーチャルISAがサポートする機能は備える必要はあるが、ネイティブISAを変更してGPUコアアーキテクチャを大きく変えることは要求されていない。AMDがバーチャルISAを共通化させようとするなら、他社がそのアライアンスに乗ることは可能だ。バーチャルISAであるHSAILやHSAディスパッチモデルを共通化させることは、CPUで言えばフロントエンド部分(命令デコーダやスケジューラ)の共通化に近い意味を持っている。

 まとめると、HSAでは、CPUのISAの変更に当たるようなことを行なう。CPUをx86以外のISAに切り替えて、他社にも同じISAを使うように働きかけるのと同じようなことを、GPUについて行なおうとしている。GPUがバーチャルISAモデルであるため、これが可能になる。

●ハードウェア設計上も利点があるバーチャルISA

 AMDは先月開催した技術カンファレンス「AMD Fusion Developer Summit(AFDS)」で、HSAILについての技術的な概要を説明した。AMDはこの時、そもそもバーチャルISAモデルをGPUで取るのはなぜなのか、という根源の部分から説明を行なっている。こうした説明は、これまでインタビューなどで口頭で行なうことはあっても、プレゼンテーションを行なうことは少なかった。

GPUが仮想ISAモデルをとるのはなぜか

 AMD FellowのNorm Rubin氏は、CPUのようなISAのハードウェア実装とGPUのようなバーチャルISAにはそれぞれ利点と難点があるが、GPUにはバーチャルISAが向いていると説明。その理由の1つは、パフォーマンス上の利点だと語った。ISAをハードウェア実装した方が当然命令デコードのパフォーマンスは高くなるため、矛盾しているようだが、AMDの説明にも理由がある。ISAをソフトウェア実装にすればハードウェアをシンプルにして、より早い時期に市場に投入できる。その分、より進んだプロセス技術を使えるためにパフォーマンスの向上があると言う。

 また、ネイティブISAはバーチャルISAで隠蔽されるため、ネイティブISAを変更してハードウェアを進化させることも容易となる。ハードウェアの革新は、バーチャルISAからネイティブISAへのコンパイラの変更だけで済む。後方互換を取るためにISAを複雑にして、ハードウェアを複雑にしてしまう心配もない。

 さらにRubin氏は、ISAを露出させるのは1社の1プロセッサファミリに適したスタイルだと説明。バーチャルISAなら、より広く多種のデバイスに対応できると利点を強調した。バーチャルISAだからこそ、HSAで他のベンダーを巻き込むことができるという説明だ。バーチャルISAモデルが、HSAアライアンスの鍵となっている。

●2層に分かれたコンパイラ

 HSAの実行モデルで、AMDはリアルタイムコンパイラを2層に分けた。スプリットコンパイレーションで、上位と下位の2レイヤーにコンパイラが分かれている。「High Level Compiler (HLC)」がOpenCLやC++AMP、将来的にはJavaなどのソースからHSAILコードを生成する。HSAILコードはターゲットマシンにディスパッチされるが、その前に2層目のコンパイラ「Finalizer(ファイナライザ)」で、GPUのネイティブISAに変換される。もちろん、HSAILのハンドコーディングも可能だ。

リアルタイムコンパイラを2層に分割 上位のHLCが時間のかかる最適化、下位のFinalizerがハードに合わせた最適化 HSAソリューションのスタック

 HSAモデルでは、HLCとFinalizerの2レイヤーのコンパイラで、最適化も分担する。上位のHLCが時間のかかるアグレッシブな最適化作業を担当する。とはいえ、HLCではターゲットのハードウェアの情報が限られるため、汎用的な最適化を行なう。

 そして、Finalizerが、実際のハードウェアに合わせたシンプルな最適化を極短時間で行なう。例えば、GPUでは通常は立ち上げるスレッド数によって1スレッド当たりのレジスタ数が変化するため、Finalizerの段階でしか正確なレジスタ数の情報を得られない。HSAIL上では固定数のレジスタを割り付けておき、HLCの段階で生じたレジスタあふれを、Finalizerが、使えるレジスタに割り振るといった処置を行なう。また、HSAILは、ハードウェアのベクター長なども隠蔽する。この分担の目的は、最適化コンパイルをできる限り共通したフレームワークで行ないながら、異なるハードウェアに対応することにある。

HSAモデルの利点

 AMDは、HSAモデルの大きな利点が、並列プロセッサに対するプログラミングツールの共通化にあると説明する。GPUプログラミングでは、パフォーマンスの最適化が非常に難しい。そして、現状では、各コアそれぞれに合わせた最適化のツールが必要で、それがGPUプログラミングの障壁の1つとなっている。HSAプログラミングモデルでは、そうした壁を取り払い、ダイレクティブだらけのコードをシンプルにすることで、コードの可読性と生産性を高めるとAMDは説明する。また、GPUコアだけでなく、DSPや固定ハードウェアアクセラレータも共通のツールでカバーできるようにしようとしている。

 まとめると、コンパイラにより多くを任せて、コードをシンプルにしながら、異なるプロセッサ間でポータブルになるようにしようというのがAMDのビジョンだ。実際には、コンパイラの進化には時間がかかるので、HSAはそのための土台を構築することになる。同じコードが、アーキテクチャの異なるプロセッサコアの上で、高速に走ることが最終目標だ。

 ちなみに、HSAILは、従来のAMDのグラフィックス向けの中間言語である「AMDIL」と併存する。HSAILからはグラフィックスの機能の多くはアクセスできない。AMDILがグラフィックス向けで、HSAIL自体はGPUコンピューティング向けと、それぞれ用途を絞っている。HSAを採用するGPUベンダーは、グラフィックスは従来のモデルを継続して使って互換性を保ちながら、コンピューティングはHSAILを使うといった切り分けも可能となる。グラフィックスはHSAILへの移行させない、現実的な移行パスだ。グラフィックスに特化したAMDILは、レジスタも4-wayベクターで32bit×4構成で、「Array of Structures (AOS)」に特化した仕様となっている。

HSAILとAMDILの違い HSAのゴール
Array of Structuresと、Structures of Arrayの違い(PDF版はこちら)

●HSAはSIMT(Single Instruction, Multiple Thread)モデルを採用

 HSAILのオペコードは120と絞り込まれている。HSAIL上でのレジスタは4種類。Cレジスタはコントロールレジスタで、典型的なものは分岐の制御を行なう。Sレジスタは32bitレジスタで、HSAILでは浮動小数点と整数のデータタイプの区別を行なわない。Dレジスタは64bitレジスタで倍精度浮動小数点と64bit整数に対応する。

 Qレジスタは128bitで、これはSSEなどと似たようなパックドレジスタだ。64bit×2や8bit×16といったフォーマットとなっている。SSEのようなパックドフォーマットもサポートされる。このQレジスタの構成は、ARMのMali-600系などに向いている。

HSAILのサポートするレジスタとタイプ Mali T658のシェーダコア(PDF版はこちら)

 HSAILは、OpenCLとC++AMPをソースとすることを念頭に置いて設計されている。しかし、実際にはより多くのフィーチャを備え、C++もフルにサポートできるという。HSAILが汎用的な高級言語と親和性が高い理由の1つは、「SIMT(Single Instruction, Multiple Thread)」モデルを取っている点にある。

 SIMTモデルでは、一定の数のワークアイテムに対して同じ命令を実行する。SIMTとSIMD(Single Instruction Stream, Multiple Data Stream)の大きな違いは、分岐がサポートされる点で、それぞれのワークアイテムに対してのスレッドを個別に分岐できる。概念上は、各ワークアイテムに対するスレッドそれぞれが個別のプログラムカウンタを備えて、個別に分岐する。

HSAの多くの新機能 SIMTモデルをとる理由

 実際のハードウェアでは、AMD GPUの場合は、64個のワークアイテムに対する64スレッドを束ねた「Wavefront」がSIMT実行の単位となっている。AMD GPUは基本はSIMD型のベクターマシンで、Wavefrontの64bitが実質的なベクター長だ。レジスタは物理的には32-bit単精度で64スレッド分、2,048bit幅のベクターレジスタとなっている。

 しかし、ベクターのそれぞれのレーンに対する分岐を、マスクレジスタによって制御している。個々のベクターレーンがマスクされることで、分岐によるコントロールフローが実現される。プログラムカウンタはWavefront単位となっている。ベクターレジスタに対しては、Wavefrontの各スレッドのレジスタがFinalizerによってマップされる。ちなみに、ベクター演算ユニット自体は16レーンで、4サイクルでWavefrontを実行する仕組みとなっている。

ベクターALUユニット ベクター条件分岐(PDF版はこちら)
GCN Compute Unitのアーキテクチャ(PDF版はこちら)
GCN Compute Unitのスケジューリング(PDF版はこちら)

●Finalizerが実行モデルやレジスタを抽象化する

 HSAIL上はSIMTでハードウェア自体はベクターでも、デベロッパー側ではそうしたことを意識する必要がない。1つのワークアイテムに対するプログラムが、自動的にSIMTマシンの中でスレッド並列で実行される。スレッドは実質的に個々に分岐できるため、実行上はシングルCPUコアに対するのと同じ感覚となる。

 プログラミング上ではWavefrontサイズについて意識する必要はないが、Wavefrontサイズを理解していて、うまく使えば、より効率的なプログラムを書くことができる。AMDはWavefrontを、キャッシュラインサイズのようなものと例えている。

Wavefrontはハードウェア専用のキャッシュサイズのようなもの 開発者はWavefrontサイズを意識しなくてもよい

 AMDはSIMTとベクター(この場合はSIMD)との違いもAFDSで説明している。単純なベクターモデルの方が、熟達したプログラマーにとって10%程度のパフォーマンスアップとなる。しかし、ベクターを意識しないで済むSIMTの方が開発者にとって馴染みやすいと言う。グラフィックスはSIMTモデルがフィットするため、ハードウェアの流れはSIMTへの最適化に向かっていると言う。

SIMTモデルの利点 ベクターモデルの利点

 HSAIL上からはWavefront単位でのSIMT実行は、Finalizerによってマップされる。ハードウェアの実行モデルやレジスタを隠蔽することは、AMD以外のハードウェアを含む多種多様なプロセッサをサポートするために必要なことだとAMDは説明する。「重要な点は、AMDが作ったハードウェアだけでなく、多くのマシンをサポートできることにある。その中にはベクターマシンでないものも含まれるだろう」と言う。ただし、HSAIL上からWavefrontを操作することもできる。各ワークアイテムについてどのWavefrontに含むか、あるいはワークグループ間でのデータ再利用などを明記することができる。

 まとめると、GPUではバーチャルISAであるために、異なるベンダーの異なるアーキテクチャも同じバーチャルISAの元に吸収し易い。そして、バーチャルISAをうまく設計すれば、アーキテクチャの差異が大きい場合も吸収しやすくなる。HSAILはそうした点を配慮して作られているとAMDは説明している。