ユニファイドメモリアーキテクチャ(英: Unified Memory Architecture、UMA)は、メインメモリをCPUだけでなく、他のデバイスにも共有して使用するメモリアーキテクチャの一つである。まれにUniversal Memory Architectureと表記されることもある[1][2]。
概要
| この節は 世界的観点から説明されていない可能性があります。 ノートでの議論と記事の加筆への協力をお願いします。 (2023年10月) |
この方式は、古くはNECのPC-8001で実装された。メインメモリの一部をVRAM(ビデオメモリ)の一部として扱い、CRTC(CRTコントローラー)にDMA転送することで、画面を表示していた。DMAが動作中CPUはメモリバスの使用権を失い、画面表示中はCPU本来の能力を発することができなかった。そこで計算などの用途においてDMAを停止し、CPUがメインメモリをフルにアクセスできるようにすることが一般的だった。この手法は後に、PC-8800シリーズでも使用された。
現代のこの方式の応用もまた、VRAMをメインメモリにマッピングする場合に用いられていることが多い。このアーキテクチャがパーソナルコンピュータ (PC) に適用されたときは、CPU本来の性能を発揮できないことから嫌われた。そこでCPU動作速度の低下を避けるため、メモリバスの周波数をCPU本来のバス周波数より高く設定し、CPUからのメモリアクセスをさまたげないよう工夫されるようになった。CPUがメモリにアクセスする際にグラフィックスコントローラー(のちのGPU)は目的の演算を遅延することから、表示にジッターが現れることが多かった。後にこれはメモリアクセス方式を工夫したり、あるいは最終的に画面表示に使うメモリのみを、グラフィックスボード(ビデオカード)に搭載したりすることで解決した。しかし、さらに時代が下って再び採用され始める。PCに限らずワークステーションでも一般的であった。3Dアクセラレーターにおいて、VRAMだけでなくテクスチャメモリ(テクスチャマッピング用の画像データを保持するメモリ)、イメージキャプチャ結果を保持するメモリとしても使われた。[要出典]
メモリがモジュールとして増設が簡単になり、単価も下がるにしたがい、32bitアドレスのメモリ空間の上限である4GBなども普通に実装できるようになったが、ハードウェアの予約されているメモリ番地はメモリがリニアに使えない。そのうえ、UMA方式に割く場合はさらにビデオ回路用として実メモリを用いるので、32bitモードで動かす場合にはその部分がさらに削られる。もっとも、32bitオペレーティングシステム (OS) では、独立したビデオカードを搭載する場合であってもビデオメモリは最初の4GBのアドレス空間内にマッピングされる必要があるため、ビデオメモリの量だけOS側(ソフトウェア側)で利用可能なシステムメモリの総容量が減少する[3]。つまり32bit OS環境では、大容量のビデオメモリを搭載するビデオカードはむしろシステム全体の性能を低下させることになる。
なお、かつてSGIが、高帯域幅のUMAを採用したSGI O2(英語版)と呼ばれるワークステーション製品を手掛けていたことがあった[4]。
UMAのメリットの一つは、グラフィックス専用のメモリが不要になるため、コストダウンが実現できることである[5]。エントリモデルのデスクトップPCやノートPCでは、独立したグラフィックスボードやGPU (dGPU) を搭載せず、マザーボード上に実装されたオンボードグラフィックスあるいはCPUに内蔵されたGPU (iGPU) を利用することが多い。スマートフォンやタブレット、ゲーム専用機などに搭載されているSoCは、CPU・GPU・メモリ・周辺回路などを1チップ(1パッケージ)に統合している。いずれもVRAMは搭載せず、メインメモリをCPUとGPUとで共有するUMAとなっている。
UMAのデメリットは、パフォーマンスがメモリに律速され、各々のプロセッサの能力を最大限に活かすことができない可能性があること、また拡張性に乏しいことである。例えばグラフィックスボードに実装されるVRAMには帯域幅の大きいGDDR系メモリやHBMが使われることが多いが、UMAでは通例DDR系メモリとなるため、GPUの性能を活かしきれない。また、CPUと比較すると、並列化しやすいGPUは半導体プロセスルールの微細化に伴う性能向上率が高く、旧製品の性能陳腐化が激しいが、UMA環境ではグラフィックスボードだけを交換・増設して性能を向上させるようなことができない。メモリも統合されたSoCの場合は、メモリだけを後から交換・増設することができない。
NUMA
複数のCPUが共有するメインメモリにアクセスする対称型マルチプロセッサにおいて、そのメモリアクセスのことを「Uniform Memory Access」と呼ぶ[6]。この言葉はNUMA(Non-Uniform Memory Access)ではないことを強調して指す言葉であり、あまり一般的ではない[要出典]。
従来型のPCアーキテクチャやSoC、Xbox 360などでUMAと呼ばれているアーキテクチャは、あくまでもメモリの部品としての共用であり、CPUとGPUのメモリマップ(メモリ空間)までは統合されていない。これはUMAの中でもNUMAとして分類される[7]。従来型のUMAでは、CPUとGPUはそれぞれのメモリ空間に存在するデータをお互いに直接共有・読み書きすることができず、都度データ転送(コピー)が必要になる。
hUMA
ヘテロジニアス・ユニフォームメモリアクセス (heterogeneous Uniform Memory Access) とは、UMAの中でもさらに統合が進み、CPUとGPUがメモリマップまで統合されているUMAのことを指す。AMDがHSA (Heterogeneous System Architecture) の鍵となる技術の一つとして発表した[7]。
CPUとGPUで同じメモリマップを共有しているということは、必然的にGPU側もページフォールトに対応し、MMUで仮想メモリ管理が可能となっていることになる。また、hUMAではCPUとGPUのメモリ一貫性(メモリコヒーレンス/メモリコヒーレンシ)がハードウェアレベルで確保されており、CPUとGPUが扱うデータの一貫性や同期をソフトウェア側で気にする必要がなくなる[8]。これはGPUを汎用目的に利用するGPGPUにおいて大きなメリットとなる。
つまり、hUMA環境において、あるメモリアドレスは、CPUやGPUにかかわらず同じアドレス空間内の同じメモリ番地を指すということである。一見当たり前の話に聞こえるが、hUMAではない従来型のUMAではメモリという部品を容量で用途別に分けあっているだけなので、CPUとGPUで異なるアドレス空間を持ち、それぞれ個別にアドレスが振られているうえにメモリ自身もあくまで別物扱いである。それゆえに例え同じアドレス値であっても、CPU用のアドレスとGPU用のアドレスでは全く別のメモリ番地を指している。CPUとGPU間(これは、PCにおいては同時にマザーボードとビデオカード間をも指す)に接続されたバスを通して転送するしか、両者間でデータのやりとりは不可能である。しかし、先述の通りhUMAの場合は単純に同じアドレスのメモリ領域でデータを読み書きするやりとりだけで済み、ソフトウェアによるデータ転送の手間が省ける。また、2023年現在においても、GPUではCPUのようにポインタあるいは参照を駆使した複雑で柔軟なデータ構造を直接扱うことができず、GPU向けにいったん分解や再構築が必要となるが、hUMA環境ではそのまま扱えるようになる。
なお、HSA規格を管理しているHSA Foundationの活動は、2020年を最後に止まっている[9][10]。
API側のUMA対応
前述のように、従来型のUMAでは、CPUとGPUのメモリ空間が異なるため、たとえ同一の物理メモリ上に存在するデータであっても、お互いに直接読み書きすることができず、データ転送が必要になってしまう。データ転送処理にはDirect3D(DirectX)あるいはOpenGLのようなグラフィックスAPIや、CUDAあるいはOpenCLのようなコンピューティングAPIを利用するが、このコピー処理および同期にかかるコストは、特にGPUの演算結果をCPU側で読み出して利用する場合にボトルネックとなる。しかし先進的なAPIの中には、UMAに対応した最適化機能を持つものも存在する。
OpenCL
OpenCLのclCreateBuffer()
のflags
引数にCL_MEM_USE_HOST_PTR
またはCL_MEM_ALLOC_HOST_PTR
を使用することで、ホスト(CPU)側に割り当てられたメモリをバッファとして使用できる[11]。UMA環境では、(GPUなどの)デバイス固有のルールに従ってこれらを利用することで、バッファ読み書きの際にコピーが不要となる「ゼロコピーバッファ」を実現することができる可能性がある。例えばIntel Graphicsでは、4096バイト境界でアライメントされ、64バイトの倍数のサイズを持つ既存のメモリ領域をバッファとして使うことで、ゼロコピーバッファを実現することができる[12]。ただし実装依存であり、UMA環境だからといって必ずしもゼロコピーバッファになるとは限らない。
OpenCL 2.0では、共有仮想メモリ(Shared Virtual Memory, SVM)の機能が追加され、ホストとデバイスで仮想メモリ空間を共有できるようになった[13]。SVMにより、UMA環境ではゼロコピーが実現できるようになるだけでなく、ポインタを使用した複雑なデータ構造をデバイス側で利用することもできるようになる[14]。
Direct3D
Microsoft Windows 10で追加されたDirect3D 11.3および12では、UMA環境の場合は冗長なコピーを減らすことのできる機能を持つ[15][2]。Direct3D 12では、通常のUMAとキャッシュコヒーレントなUMAを区別することもできる[16]。
AppleのMetal APIでは、単一の仮想メモリ領域内に存在する、アライメントされたメモリアドレスを使って、データをコピーすることなく既存のメモリ領域をラップするMTLBuffer
オブジェクトを直接生成することができる[17]。また、Metalではリソース生成時にMTLStorageMode.shared
を使用することで、CPUとGPUがシステムメモリ内に割り当てられたリソースへのアクセスを共有できるが、共有メモリを使用するリソースに対して、CPUまたはGPUのどちらかでスケジュールしたすべての変更処理が、もう片方のプロセッサ上でのリソースアクセスが発生する前に完了されなければならない[18]。つまり、MTLBuffer.contents()
を使って直接ポインタを取得して共有データを読み書きすることはできるものの、任意のタイミングでCPU/GPU間のメモリ一貫性が保証されるわけではなく、ソフトウェア側の配慮が必要となる。
Apple Silicon
2020年にAppleは、従来からiPhoneやiPadなどで採用されていたARMアーキテクチャベースのApple製SoCを、Macコンピュータにも採用するにあたって、Appleシリコンという総称で再定義した[19][20]。2020年末以降は、MacでもIntelのx86ベースプロセッサに代わって、Apple M1のようなApple SoCが搭載されるようになった。これらのApple SoCではUMAが採用されているが、Apple Silicon GPU環境におけるMetal APIでは、CPUとGPUとで共有可能なMTLBuffer
とMTLTexture
を生成することができる[18]。これによりゼロコピーを実現することができ、パフォーマンスと効率が向上する[21]。従来のIntelプロセッサを搭載したIntel Mac環境でも統合GPUに関してはUMAとなっており、MTLBuffer
に関しては共有モードを利用できるものの、MTLTexture
に関しては共有モードを利用できなかった。
なお、Apple GPU環境であっても、すべてのリソースに対して共有モードを設定するのではなく、リソースアクセスの傾向に応じて適切なストレージモードを選択する必要がある[22]。
脚注
関連項目
外部リンク