後藤弘茂のWeekly海外ニュース
CPUとGPUのメモリ空間を統一するAMDの「hUMA」アーキテクチャ
(2013/5/2 00:00)
HSAの完成に向けた大きな一歩となるhUMA
AMDはCPUとGPUのメモリ空間を統一する「hUMA(heterogeneous Uniform Memory Access:ヒューマ)」アーキテクチャの概要を発表した。CPUとGPUが、フルにメモリコヒーレンシを取った状態で、単一のメモリアドレス空間に自由にアクセスできるようにする技術だ。一言で表せば、GPUコアがCPUコアの1つのようにメモリアクセスできるようになる。
AMDの掲げるヘテロジニアス(Heterogeneous:異種混合)コンピューティングのフレームワーク「HSA(Heterogeneous System Architecture)」の核となる要素だ。hUMAの導入によって、GPUで走る汎用プログラムを、今よりもっと簡単に書けるようになり、パフォーマンスも引き出し易くなり、余計なメモリアクセスを減らすことで電力消費も抑えることができる。ヘテロジニアスコンピューティングを、より広いプログラマ層に広めるというAMDの究極の目的の、最大の武器となるのがhUMAだ。シリアルタスクを担当するCPUと、並列タスクを担当するGPUを、効率的に結びつけるのがhUMAの役目だからだ。
AMDはAPU(Accelerated Processing Unit)開発の流れの中で、段階的にHSAに必要な機能を実装しつつある。hUMAは、その中でも目玉と言うべき機能で、これによって、HSAのフレームワークは、プログラミングモデル的にはほぼ土台が整う。下はAMDが毎回示しているHSAのロードマップだ。左端の「物理統合:Physical Integration」がLlano(ラノ)の世代で、現在は「プラットフォームの最適化:Optimized Platforms」の段階で、次のステップが「アーキテクチャ上の統合:Architectural Integration」で、APUとしては「Kaveri(キャヴェリ)」の世代となる。
見て分かる通り、アーキテクチャ上の統合のステップは、完全にメモリアーキテクチャにフォーカスしている。スライドで謳っているのは下の3項目だ。メモリモデルはプログラミングに与える影響が大きいため、hUMAの導入によるアーキテクチャ統合は、HSAの大きな山場となる。
- CPUとGPUのユニファイドアドレス空間
- CPUのポインタを使ったGPUのページャブルシステムメモリへのアクセス
- CPUとGPU間でのフルコヒーレントメモリ
3段階で進展するAPUのメモリアーキテクチャ
メモリアーキテクチャだけを見ると、APUはホップステップで進化してきた。最初のLlanoでは、CPUコアとGPUコアを物理的に1つのシリコンダイ(半導体本体)に統合した。そして、CPUコアとGPUコアが、同じ物理メモリを共有できるようにした。しかし、Llanoでは、CPUコアとGPUコアのそれぞれが分離されたメモリ空間を持ち、その間のアクセスは非常に限られていた。そのため、CPUとGPUがデータを共有するためには、両メモリ間でデータをコピーしなければならなかった。また、CPUとGPUが互いのコアを経由してメモリにアクセスする場合は、メモリ帯域も非常に制限された。
2世代目のAPUのTrinity(トリニティ)では、IOMMU(I/O Memory Management Unit)を拡張したIOMMU v2に切り替えて、ページフォルト(Page Fault)のハンドリングをできるようにした。現在のPC向けOSは、仮想メモリをサポートしており、物理的に実装されているメモリよりも大きなメモリ空間を仮想的に提供している。仮想メモリアドレスの一部が、物理メモリからはみ出した場合は、SSDやHDDなどのストレージにマップして物理メモリから追い出す。利点は、実メモリのサイズを気にせずにプログラムを走らせることができること。
現在のOSはデマンドページング(Demand Paging)メカニズムの仮想メモリを使って固定長のページ単位でメモリ管理しており、CPU側もそれに対応している。この場合、アクセスしたアドレスの仮想メモリが物理メモリ上に存在しないと、MMU(Memory Management Unit)がページフォルトを発生させ、該当メモリアドレスを物理メモリ上へと移す。TrinityのIOMMU v2からは、このページフォルトにハードウェア的には対応した。とはいえ、Trinityのメモリアーキテクチャは、CPUとGPUのメモリ空間は分断されたままで、まだ制約が多く、真のメモリ統合までの中間解に過ぎなかった。
Kaveri世代から有効にされる見込みのhUMAは、AMDの目指すCPUとGPUのアーキテクチャ統合のメモリアーキテクチャでの最終形態だ。これまでのAPUと異なり、hUMAでは、CPUとGPUは、同じメモリアドレス空間を共有するようになる。CPUとGPUの間でのメモリコヒーレンシもハードウェアで取られるようになる。GPUコアが、CPUコアと同格の扱いになり、あたかも、もう1つのCPUコアのように、メモリにアクセスできるようになる。
CPUとGPUを単一の仮想メモリアドレス空間を共有に
hUMAでは、双方向のメモリコヒーレンシ、ページャブルメモリ、CPUとGPUの間での完全な統合メモリ空間を実現する。メモリコヒーレンシのポイントはハードウェアで制御すること。ページャブルメモリではページフォルトをGPUがサポートすることで、自由にメモリ全体にアクセスできるようになる。その結果、CPUとGPUが、フルに仮想メモリ空間を共有できるようになる。
現在のAPUは、物理的なメモリは単一だが、CPUとGPUで個別のメモリアドレス空間を持っている。UMA(Uniform Memory Access)システムでは、全てのプロセッシングコアがシングル単一のメモリアドレス空間を共有するべきだが、そうなっていないとAMDは指摘する。その原因は、GPUコンピュートが導入された時に、ディスクリートGPUによって「Non-Uniform Memory Access (NUMA)」が持ち込まれたからだと言う。個別のメモリ空間に分断されたNUMAによって、ヘテロジニアスコンピューティングでは複雑なプログラミングを強いられているというのがAMDの視点だ。異なるメモリ空間の間で、煩雑なデータコピーと同期、それにアドレス変換が必要になる。
hUMAの目的は、分断されたNUMA状態を、再びシンプルなUMAのモデルに戻すことにある。CPUとGPUが統合されたメモリ空間を共有するようになれば、プログラミングがシンプルになる。それぞれのコアが使うメモリは、共有するメモリスペース全体から、動的に割り当てされるようになる。つまり、CPUとGPUのそれぞれのMMU(Memory Management Unit)が連携して、連続したメモリ空間にシームレスにアクセスできるように協調したアドレス変換を行なう。
それも、物理メモリを共有するだけでなく、ページフォルトをサポートすることで、GPUもフルに仮想メモリにアクセスできるようにする。ページフォルトがサポートされていないと、GPUはページロックされたメモリにしかアクセスができない。物理メモリにマップされていないと、ページフォルトが発生した時点でエラーになってしまうからだ。
しかし、hUMAでは、ページフォルトがGPU側のMMUでもサポートされているために、シームレスに仮想メモリ空間全体にアクセスができる。つまり、ページフォルトになったら、MMUが割り込みをかけて、ストレージ上にあるメモリ内容を物理メモリに書き戻す。その結果、物理メモリ上になかった仮想メモリアドレスにもアクセスができるようになる。
hUMAのカギとなるハードウェアコヒーレンシ
また、hUMAでは、CPUとGPUの双方向のメモリコヒーレンシをハードウェアで保つ。双方にハードウェアがキャッシュをスヌープして、一貫性を自動的に確保する。あるプロセッサが、キャッシュ上のデータを書き換えた場合は、他のプロセッサが検知できるため、メモリの一貫性の間違いが生じない。GPUからCPUのキャッシュをスヌープするだけでなく、CPU側からもGPUのキャッシュをスヌープできる。
プログラミングモデル上は、ハードウェアコヒーレンシの利点は計り知れないとHSAの産みの親であるPhil Rogers氏(AMD Corporate Fellow)は、FSA(Fusion System Architecture)は説明する。上のスライドは、Rogers氏が説明したハードウェアコヒーレンシが重要である10の理由だ。
「(ハードウェア)コヒーレンシはチャレンジだが、我々はそれだけの価値があると考えた。なぜなら、プログラマにとって物事を非常に簡単にするからだ。プログラミングの際に、データの一貫性について気を配る必要がなくなる。また、マルチコアCPU用に作った並列プロセッシングのアルゴリズムをGPUに移したい場合、GPU側にコヒーレンシがないと、アルゴリズムをGPUに移す際に、再コーディングする必要が出てしまう。しかし、hUMAでは、再コーディングの必要がない。
さらに、コヒーレンシをソフトウェアで管理するとなると、オーバーヘッドがあるため、頻繁に同期させるわけには行かない。しかし、コヒーレンシにソフトウェアオペレーションが不要なら、オーバーヘッドがないため、細粒度でのデータ共有が可能になる。
それから、コヒーレンシをハードウェアで取るなら、実装は1回だけで済む。ところが、ソフトウェアで取ろうとすると、何回も異なるソフトウェアプラットフォームに対して実装しなければならない。Windows、Android、Linuxといった異なるOS、異なるプログラミングモデルランタイム、異なる言語……。しかし、ハードウェアで取るなら、どのソフトウェアからも同じに見えるので、簡単だ。
また、ソフトウェアで実装する場合は、それぞれの実装について、潜在的なバグを発見してつぶして行かなければならない。しかし、同期のバグは見つけることが難しい。ハードウェアで実装して検証が終われば、それは、どのソフトウェアでもうまく働く。特にOSベンダーは、安全なハードウェアベースの実装を望んでいる。ソフトウェア側でバグがあった場合は、アプリケーションベンダーから彼らが責められるからだ」。
こうした事情から、AMDはハードウェアコヒーレンシにこだわった。AMDは、GPUをプログラムするヘテロジニアスコンピューティングを幅広く普及させるためには、ハードウェアベースのコヒーレンシメカニズムが必須だと見ている。コヒーレンシは、HSAの究極の目的である、同じプログラムをCPUとGPUのどちらでも走らせるという構想に欠かせない。
「フルコヒーレンシが取れるなら、プログラマはシングルソースアプローチでプログラムすることができる。いったん並列アルゴリズムを書いたなら、それがCPUとGPUのどちらでも走るようにできる」(Rogers氏)。
ハードウェアコヒーレンシメカニズムには、技術的に難しい点もある。多くのコアを抱えるシステムでハードウェアコヒーレンシを取る場合の問題は、コヒーレンシのためのプローブのトラフィックが膨大になる。コヒーレンシのトラフィックでバスが埋まるだけでなく、消費電力も上がってしまう可能性がある。
この問題については、2011年のAMD Fusion Developer Summit(AFDS)の際に、当時AMDのCPU開発を担当していたChuck Moore氏(Corporate Fellow and CTO Technology Development)が「プローブフィルタとダイレクトリでトラフィックを制御することで、その問題は解決できる。どちらの技術も、すでにOpteronで実証済みだ」と説明していた。Moore氏は昨年(2012年)他界している。ヘテロジニアス(Heterogeneous:異種混合)のプロセッサ間でのコヒーレンシトラフィックをうまくフィルタすることで、効率の高いハードウェアコヒーレンシメカニズムを作ろうとしている。
CPU側のデータ構造そのままでGPUがアクセス可能に
hUMAの利点は、統合メモリアドレス空間とハードウェアコヒーレンシと、GPUのページャブルメモリのサポートによって、CPUとGPUの間での連携が容易になることだ。その結果、パラレルタスクとシリアルタスクが細粒度で入り組んだようなプログラムも、効率的に実行できるようにする。ヘテロジニアスコンピューティングでの、プログラマ側の負担をできる限り削る。
CPUとGPUが同じ仮想メモリアドレスを共有するhUMAでは、CPUのメモリ構造にそのままGPUがアクセスできる。現在のシステムでは、CPUとGPUは個別のメモリ空間に分かれている。そのため、ほとんどの場合、CPUメモリからGPUメモリへと明示的にデータをコピーして、GPUがそのデータをGPUメモリ上で処理し、その結果を再びCPUメモリへと書き戻すという手間が必要になる。
問題はデータのコピーの手間だけではないとAMDは指摘する。CPU側のプログラムは、データ構造を、リンクリストやツリー構造など複雑な構造にしている場合が多いが、そのデータ構造はそのままGPU側に持って行くことができない。GPU側は埋め込まれたデータ構造リンクを追うことができないからだ。そのため、CPU側は、パラレルタスクのデータ部分だけを抜き出してGPUに送る必要がある。
これと同じ指摘は、以前、IntelのJustin R. Rattner(ジャスティン・R・ラトナー)氏(Senior Fellow)も指摘していた。Rattner氏によると、話はもっと複雑で、CPUは、いったんデータ構造を分解してフラットにして転送しなければならないケースがよくあると言う。その場合、GPU側でもデータ構造の再構築が必要で、GPUがデータを更新したら、再び構造を分解して、CPUに送り返して、再構築しなければならない。そうしたデータ構造の転換で、データ転送のオーバーヘッドが大きくなってしまい、エラーが発生する可能性も増えるという。
ところがhUMAでは、GPUがCPUと同様にポインタを使うことができる。そのため、CPUとGPUの間の連携は極めてシンプルになる。hUMAではCPUがGPUに単純にポインタを渡すだけで、GPUがそのままCPUのデータ構造にアクセスできるようになる。GPUはそのままデータを更新する。CPUはその結果を、直接読むことができる。複雑なデータ構造の場合も、GPUが組み込まれた構造リンクを追うことができるので、データ構造の転換も一切必要がない。
ATI買収当初から計画していた細粒度のGPUコンピュート
このように、hUMAの目的は、CPUとGPUのメモリアドレススペースは統合してコヒーレンシを維持することで、GPUをCPUと同列のプロセッサとして扱えるようにすることにある。現在のGPUコンピューティングは、パラレルタスクの粒度が大きくなければ効果が現れにくい。それに対して、AMDは粒度が小さなパラレルタスクが、シリアルコードの間に入り組んでいるような場合でもパフォーマンスを出せるようにしようとしている。
AMDは、ATI Technologiesを買収してヘテロジニアスコンピューティングを目指し始めた当初から、この件について説明していた。AMDの元CTOだったPhil Hester(フィル・へスター)氏は、x86 CPUのコプロセッサとしてGPUを取りこみ、x86 CPUの中に命令セット拡張としてGPU型のワイドベクタを取り込むことも検討していると説明していた。その場合は、シングルのインストラクションストリームの中で、CPU命令とGPU命令が混在し、同じプロセッサコアで実行されることになる。この構想では、同じコアにCPUとGPUコプロセッサが統合されているため、当然同じメモリ空間となる。Hester氏は、どういうアーキテクチャが適しているかは、実際のアプリケーションのコードで、パラレルタスクとシリアルタスクがどの程度の粒度で入り組んでいるかにかかっていると説明していた。
最終的にAMDが選んだ道は、CPUとGPUは別コアのままで、メモリアドレス空間を統合してコヒーレンシを取るという解だったようだ。同じプロセッサコアにCPUとGPUを統合するほど細粒度にする必要はないが、両コアが密接に連携して解決できる程度の粒度に対応する必要があると判断したことになる。
hUMAが実装されると、HSAはいよいよ完成に近づく。最終的な姿は、密接に連携するCPUとGPUに対して、HSAタスクパラレルランタイムからタスクをディスパッチできるようにする。究極的には、プログラマ側は、自分のコードがCPUとGPUのどちらで実行されるかは意識しないで済むようになる。
また、次のフェイズになると、GPUは、コンピュテーションを細粒度で切り替えるコンテクストスイッチを実装する必要がある。hUMAでCPUとGPUが細粒度でタスクを切り替えできるようになると、GPU側のタスクの実行にも柔軟性が必要になる。HSAのロードマップの最後の「システム統合:System Integration」のフェイズに入る。
ちなみに、上のスライドは2011年6月のAMD Fusion Developer Summit(AFDS)でのスライドだ。これを、冒頭の昨年(2012年)秋のAMDのスライドと比較して欲しい。すると、冒頭のシステム統合(System Integration)の項目では、1つ要素が抜けていることに気がつく。上のスライドにあった「Extend to Discrete GPU」という文字が抜けている。
これが、過去2年でのAMDのHSA戦略の大きな変化だ。AMDは今回の発表で、APUとSoCが将来のヘテロジニアスコンピューティングの主役だと位置づけた。以前のように、ディスクリートGPUにも、APUと同じプログラミングモデルを拡張して、HSAの枠組みに同列に組み込もうという姿勢ではなくなっている。
hUMAを実装するAMDのAPU世代
hUMAを加えたHSAで、AMDはヘテロジニアスコンピューティングを変えようとしている。単純で簡素なプログラミングモデルへと持ち込み、より広い言語をサポートし、開発コストも下げる。HSAファウンデーションへと他企業も引き込み、HSAで大きなエコシステムを構築する。数百万単位のプログラマ人口のコミュニティを育てて、膨大なアプリケーションをヘテロジニアスコンピューティング上で繁栄させる。
AMDはロードマップ上では、HSAの機能が組み込まれる最初のAPUは「Kaveri」となっている。hUMAはこの段階で有効にされると見られる。Kaveriは、28nmプロセスで、CPUコアは「Steamroller(スチームローラ)」、GPUコアは「GCN(Graphics Core Next)」となる。製造はGLOBALFOUNDRIESの28nmハイパフォーマンスプロセスの見込みで、このプロセスはバルクではなくSOI(silicon-on-insulator)の可能性がある。現在のところKaveriは2013年中となっているが、年内にどれだけ出荷されるかは定かではない。
もっとも、実際にはAMDはAPUの内部アーキテクチャを、ラインナップで揃えて開発している。前世代では、メインストリームAPUのLlanoとローパワーAPUのBrazosは、実は内部アーキテクチャがほとんど同じで、そのため、プログラミングモデルは共通していた。逆を言えば、プログラミングモデルの一貫性を保つために、アーキテクチャを共通化していた。今回も、Kaveriと同世代のローパワーSoC「Kabini(カビーニ)」「Temash(テマーシュ)」でも、実際にはKaveriと共通した内部アーキテクチャになっている可能性がある。
Kabini/Temashは、TSMCで製造されるが基本的にシンセサイザブルなので、Fabを移すことは比較的容易だ。AMDのローパワーAPU系は、この世代から1ダイに統合したSoCになる。
また、今回、AMDはhUMAのソフトウェア面からの見たアーキテクチャを説明した。しかし、ハードウェアでどういった実装になっているかは一切説明していない。AMD APUは、GPUコアからDRAMコントローラの連結に、Onion(オニオン:Fusion Compute Link)とGarlic(ガーリック:Radeon Memory Bus)という2系統のバスを使っているが、hUMA世代でも、この構造が継続されるかどうかわからない。コヒーレンシモデルからすれば、単一バスの方が容易だ。
また、ここで出てくるもうひとつの疑問は、AMDアーキテクチャを使うゲーム機に関するものだ。ソニー・コンピュータエンタテインメント(SCE)のPlayStation 4(PS4)と、Microsoftの次世代Xboxが、hUMAを採用しているかどうか。つまり、hUMA型のMMUやコヒーレンシメカニズムを備えているのかが、まだわからない。ちなみに、PS4のAPUの内部バスについては、Onionを拡張したOnion+と、倍に強化されたGarlicを備えていることが分かっている。もう1つ加えると、PS4のOSがバーチャルメモリをサポートしていなければ、そもそもページフォルトのサポートによる、物理メモリ上にないバーチャルメモリアドレスへのアクセスは意味がないことになる。