HN 日本語サマリー

← 一覧へ戻る
プログラミング

Linux 7.3、VRAM不足時のパフォーマンスを改善

Linux 7.3 improves performance when running out of vRAM (pixelcluster.dev)

490 pointsby flaburgan253 コメント

要約

この記事は、LinuxカーネルのVRAM管理に関する最近の改善について解説しています。VRAMが不足すると、GPUはCPU RAMにアクセスする必要が生じ、PCIバスの帯域幅制限によりパフォーマンスが大幅に低下します。しかし、キャッシュヒット率やアクセスパターンによっては、この影響を軽減できる可能性が示唆されています。Linux 7.3にマージされたカーネルパッチは、このような状況下での安定性とパフォーマンスを向上させることを目指しています。

全文翻訳

今年初めに、ゲームのVRAM管理を改善するための作業についてブログを書きました。そして今、数ヶ月にわたるメーリングリストでのやり取りを経て、カーネルパッチがついにアップストリームにマージされ、Linux 7.3向けにキューイングされました!やったー!これを祝して、前回の投稿で書いた一文をもう少し深く掘り下げてみましょう:[ゲーム]は、ゲーム自体が実際に持っている以上のVRAMを使用しない限り、はるかに安定して動作するはずです。では、もし実際に持っている以上のVRAMを使用したらどうなるでしょうか?これに対する一般的な期待は、一度そうなると pretty much 終わりだということです。ゲームは次々とクラッシュし始め、パフォーマンスはプレイ不可能なレベルまで急落し、良いゲーミング体験は不可能になります。しかし、それは本当に避けられない人生の事実なのでしょうか?何がVRAM不足をこれほどまでにひどくさせているのでしょうか?そして、最も重要なこと:それをできるだけひどくないようにするにはどうすればよいでしょうか?期待値の設定理論上、VRAM不足は安定性の問題ではなく、パフォーマンスの問題に限定されるはずです。VRAMのオーバーコミットメントのサポートは、GPUドライバーが存在する限りずっとありました:ドライバーがVRAMをオーバーコミットする場合、一般的に好きなだけVRAMを要求することができ、カーネルドライバーがGPU上の物理メモリに収容できると判断した量だけが得られます。パフォーマンスの面では、VRAM不足時のパフォーマンス低下の大きな理由は非常に単純です。ゲームが物理的に存在する量以上のVRAMを要求するとすぐに、ゲームのメモリの一部はCPU RAMに移動/追い出される必要があります。GPUにとって、CPU RAMへのアクセスは専用GPUのVRAMへのアクセスよりもはるかに遅いです:一般的にCPU RAMは専用GPUのVRAMよりも遅いだけでなく、すべてのメモリアクセスはPCIバスを経由しなければなりません。PCIバスはレイテンシを追加し、CPUメモリからフェッチする際の帯域幅のボトルネックとなることも一般的です。PCI速度の制限により、VRAMのオーバーコミットメント時に本当に避けられないパフォーマンス上の制約があります。GPUがPCIe 4.0x16接続で接続されていると仮定すると、32GiB/s弱の帯域幅が得られます。毎ミリ秒、そのPCIeバスは約32.2MiBのデータを転送できます。最低30フレーム/秒(フレームあたり33.3ms)のフレームレートでは、GPUがアクセスできるデータの絶対最大量は約1,075.5MiB、つまり1GiB強です。言い換えれば、メモリがそれほど多く追い出され、GPUが1フレームあたり1GiBを超える追い出されたメモリからデータをフェッチする必要がある場合、30FPSを達成することは単純に不可能です。すべてのメモリが同じではない同時に、GPUがCPUメモリを少しだけ読み取ることは、パフォーマンスにとって即座に死刑宣告ではありません。実際、GPUドライバーは、VRAMが十分に利用可能な場合でも、コマンドバッファデータや関連する割り当てなどをCPU RAMに配置することがあります!GPUがこれらのコマンドを実行するたびに、CPUメモリにアクセスする必要がありますが、これらのケースではすべて完全に正常に動作します。では、これらのアクセスは何が違うのでしょうか?なぜこれらは正常で、VRAM不足は壊滅的に見えるのでしょうか?計算に大きく影響する一つのことはキャッシングです。キャッシュヒットの場合のアクセスレイテンシは、キャッシュされたメモリがCPUにあるかGPUにあるかに関わらず同じなので、PCIバスを介したフェッチの高い初期コストは、キャッシュヒットによって(ある程度)償却できます。CPU RAMとVRAMへのアクセスレイテンシの違いは、異なるバッファサイズ(キャッシュヒット率を可能な限り最小限に抑えるための敵対的なアクセスパターンを使用)を測定するマイクロベンチマークを記述することで推定できます。得られる結果は(RDNA3でキャプチャしたものですが)このようになるかもしれません。予想通り、バッファがL2(またはそれ以上のレベルのキャッシュ)に収まる場合、CPU RAMによってバックアップされたメモリとVRAMによってバックアップされたメモリのアクセスレイテンシはまったく同じです。なぜなら、どちらの場合もデータはキャッシュから直接フェッチされるからです。6MB(RDNA3のL2キャッシュサイズ)のサイズでは、CPUメモリのレイテンシは約2400サイクル/アクセスまで上昇しますが、デバイスメモリのレイテンシは同じような範囲にとどまります。VRAMアクセスもInfinity Cacheを通過しますが、CPUメモリアクセスはそうしません(L2ミスでPCIeに直接ヒットします)。これは、Infinity CacheがVRAMのすぐ上にあるため、VRAMにヒットしないアクセスはInfinity Cacheにも到達しないためだと推測します。明らかに、メモリはどこにもキャッシュされていない状態から始まるわけではないので、最初のアクセスは依然としてかなりの高いレイテンシを持つことになります。また、Infinity Cacheを失うことは間違いなく痛手です:PCIeフェッチは、Infinity Cacheヒットよりも約7.3倍、VRAMからのフェッチよりも約4.6倍のレイテンシを持つようです。この増加したレイテンシは、PCI経由でのコストを完全に償却するために、本当に高いキャッシュヒット率を必要とします。これは、CPUメモリを使用することによるわずかな速度低下が、選択肢がある場合にVRAMよりも積極的に使用することを決定するほど小さいユースケースは、ごくわずかしかないことを意味します。VRAMからメモリを追い出す場合、全体的なパフォーマンスへの影響が少ないメモリと、影響が大きいメモリがあるでしょう。キャッシュフレンドリーな方法でアクセスされるメモリは、CPU RAMの速度低下の影響をそれほど受けません。アクセスパターンがキャッシュフレンドリーではなく、メモリがあまり頻繁にアクセスされない場合でも、GPUはCPU RAMからデータをフェッチする必要がめったにないため、問題ないかもしれません。GPUが割り当てられた総サイズの一部しかアクセスせず、残りは決して読み取らないメモリ割り当てが多く存在する可能性があります。これらの割り当てが追い出された場合、数GiBのデータを追い出すかもしれませんが、フレームあたり実際にアクセスされるデータの1GiBのハードリミットをはるかに下回るままかもしれません。これらの変数のすべてが、メモリが追い出されたときにパフォーマンスが実際にどうなるかを予測することを驚くほど難しくしています。しかし、要するに:追い出されたメモリがどれだけアクセスされ、これらのアクセスがどれだけキャッシュされるかによって、パフォーマンスを(完全に)台無しにすることなくVRAM不足で実行できるかもしれません!現実に立ち向かう理論上は、パフォーマンスの良いVRAMオーバーコミットメントができるようになりました。素晴らしい!SteamOSを起動して、ゲームを開始し、設定を最大にしましょう- radv/amdgpu: コマンド送信のためのメモリが不足しています。おお。実際には、VRAM不足は多くの安定性の問題をもたらすことが判明しました。このエラーは、通常の「割り当てできません、メモリ不足」エラーとは少し異なります。メッセージは特にコマンド送信について不平を言っていることに注意してください:RADVは、カーネルがコマンドを送信しようとしたときに-ENOMEMを返した場合にこのメッセージを表示しますが、コマンドを送信するだけでは新しいリソースは割り当てられません!すべてのコマンドバッファは事前に割り当てられており、明らかにその割り当ては成功しました。すべてのメモリは正常に割り当てられていたにもかかわらず、GPU送信で使用すると突然「メモリ不足」エラーが発生します。カーネルの冒険の時間です!カーネルが送信を受け入れるようにすることは、それほど難しくないはずです。結局のところ、カーネルはすでにすべての割り当てを受け入れています!カーネルロックの恐怖amdgpuドライバーが、GPUにコマンドの実行を開始するように指示する前に、すべての送信ごとに行う必要があるのは、GPUコマンドによって参照される可能性のあるすべてのメモリにアクセス可能であることを確認することです。よりモダンなバインドレスグラフィックスAPIでは、割り当てられたすべてのメモリがいつかは参照される可能性があると仮定する必要があります。したがって、amdgpuは、割り当てられたすべてのメモリにアクセス可能であることを確認しようとします。各メモリ割り当てには、どのタイプのメモリ(ここではシステムRAMまたはGPU VRAM)から適切にアクセスできるかに関する情報が含まれています。ほとんどの割り当ては、CPU RAMまたはVRAMのいずれかからアクセスできます。そして、amdgpuはメモリ割り当てがこれらのメモリタイプのいずれかに存在することに満足します。しかし、一部の割り当てはVRAMに配置する必要があり、VRAMのみです。