イベント
[GDC 2015]NVIDIAが伝授するマルチGPU構成時のカク付き対策。これまで語られなかった「AFR」の秘密も明らかに
「スタッター」(Stutter)は,端的にいえば画面のカク付きのこと。Vsyncを有効にした状態で,ディスプレイの垂直リフレッシュレートに満たないフレームレートで映像表示を行うと,「GPUがVsyncタイミングまでに画面を描画仕切れず,結果として,次のVsyncタイミングがやってくるまでの間,画面には以前の映像が表示されたままになる」という事態が生じる。これが映像の停滞感として視覚されるものがスタッターだ(関連記事)。
セッションを担当したのはNVIDIAでデベロッパテクノロジーエンジニアを務めるIain Cantlay氏とLars Nordskog氏だ。
スタッターを測る簡単な方法とは?
セッションは前後半の2部構成。前半ではCantlay氏がスタッターの調査方法を指南し,後半では,Nordskog氏がSLI環境におけるスタッターの原因とその解決方法を説明した。
というわけで前半からだが,スタッターの発生要因となるのは,フレームのレンダリングにかかる時間が一定ではないということだ。何らかの原因により,あるフレームの描画がVsyncタイミングまでに終わらない状況が発生すると,GPUからディスプレイへの映像送出が遅れるため,それがスタッターとなる。
なので,解決するためには,「フレームのレンダリングにかかる時間を調べ,異常に時間がかかっているフレームが含まれる割合を把握し,ゲームプログラム側で原因を追及する」必要が出てくる。Cantlay氏が語ったのは,「それをどうやって行うか」という話である。
ここで,「FCAT」を思い出した人は,相当なNVIDIA通だろう。FCATというのは,
Cantlay氏が紹介したのは,もっと簡単な方法だ。
氏はまず,「スタッターを調べるには,フレームの描画時間を調べ,パーセンタイルのグラフを作成するのが分かりやすく,また効率的だ」と述べている。
下のスライドにあるグラフがその例だ。このグラフは,横軸に100分率を,縦軸にフレームの描画時間をとり,96%以上でプロットしたものだが,赤いほうのグラフ線では,99%のフレームが29ms未満で描画されていたものの,残る1%ではそれ以上の時間がかかっているのが分かる。
NVIDIAは現在,FCATに変わる社内ツールとして,Frapsのテストデータからパーセンタイルのグラフを生成するための「fraps2percentile tool」を使っていると紹介したCantlay氏は,右に示したスライドのとおり,ソースコードを開発者向けにも配布中だと明らかにしている。Excelが使える状態のPCであれば,FCATを使うよりもはるかに簡単にグラフを作れるとのことなので,興味のある人は試してみるといいだろう。
NVIDIAのfraps2percentile toolソースコード配布ページ
ここでCantlay氏は,パーセンタイルのグラフを作成することで問題解決に成功した事例を2つ挙げた。1つは「Battlefield 4」で,「オープンβテスト時のバージョンではスタッターが頻繁に見られたが,製品版では改善された」という。これはパーセンタイルのグラフから,デベロッパ側で対処した結果だそうだ。
もう1つは「Call of Duty: Ghost」で,こちらではNVIDIAがドライバ側で対処したとのこと。ドライバ側でシェーダのコンパイルを最適化した結果,下に示したスライドのとおり,スタッターは改善したという。
このようにパーセンタイルグラフ化し,スタッターの低減を実現できた例がある一方,Cantlay氏は,パーセンタイルグラフに頼った分析には落とし穴があることも明らかにしている。
その例として示されたのが下のスライドで,フレーム描画の所要時間が途中から急に跳ね上がってしまうようなゲームだと,「跳ね上がった後のデータ」が「跳ね上がる前のデータ」をマスクしてしまうため,パーセンタイルのグラフには現れなくなってしまうのだ。したがって,パーセンタイルグラフを頼る場合は,フレーム描画時間の計測結果などとパーセンタイルのグラフを突き合わせる必要がある。要は,パーセンタイルグラフだけを過信するなということだ。
GeForce Driverに用意されるSLI設定の謎(?)が明らかに
セッションの後半では,マルチGPU環境とスタッターの関係を,Nordskog氏が解説した。AFRの秘密が明らかになったのは氏によるセッションのほうだが,順に追っていこう。
これはAMDのCrossFireでも同じなのだが,冒頭でも紹介したとおり,SLIにおけるメインの動作モードとしては,AFRが採用されている。「Alternate Frame」(フレームをかわるがわる)という名のとおり,複数のGPUで,フレームを順番に描画していくモードだ。以下,本稿では,SLIを構成するGPUの数が2基という前提で話を進めるが,この場合には,片方のGPUが偶数番フレーム,もう片方が奇数番フレーム,といった具合に描画を担当することになる。
「単純で,GPU数に応じてスケーラブルにフレームレートが向上する」と,
しかし,弱点もある。
1つは,「表示すべきフレームを切り替える間隔が一定とは限らない」点だ。フレームの切り替え間隔が乱れると,「マイクロスタッター」(Micro Stutter)という,別の現象が生じてしまう。
もう1つは,「フレーム同士の依存が問題になり得る」点である。フレームを生成するために1つ前のフレーム情報が必要になる場合,GPUとGPUとの間でデータのやり取りが発生することとなり,これがスタッターの原因になることがあるという。
そして最後にもう1つ,「フレームレートは向上しても,入力遅延は改善されない」点が挙げられる。あくまで向上するのはフレームレートだけなのだ。
Nordskog氏はこのうち,本セッションのテーマから外れる3番めの弱点を除く,2つの問題についての対策法を語っていった。
……と,その前に,マイクロスタッターとは何かを押さえておこう。下のスライドを見てもらうと理解しやすいと思うが,SLIでは,「GPUによるフレームのレンダリングは正常に行われたにも関わらず,何らかの原因で表示すべきフレームの切り替えタイミングがおかしくなってしまい,片方のフレームが,短い時間しか表示されなくなる」ことがある。この結果生じるのがマイクロスタッターだ。
というわけでマイクロスタッター対策だが,Nordskog氏によると,NVIDIAでは,ドライバに「Flip Metering」(フリップメータリング)という機能を実装することで解決したという。Flip Meteringとは,ドライバ側で表示フレームの切り替えを正常化してしまう機能だそうで,「いまや,ゲーム開発者がマイクロスタッターの発生を気にする必要はない」と,Nordskog氏は述べていた。
ちなみに,同様の機能は,AMDも「Frame Pacing」としてグラフィックスドライバ上で実装している。Nordskog氏がそうだと言ったわけではないが,Flip Meteringは,Frame Pacingと同様の機能ではなかろうか。
そのため,SLIにおけるレンダリングの問題としては,2つめに挙げた「フレームの生成に前のフレームのデータが必要になるようなケースでGPU間のデータ転送が発生し,それがフレームの表示を送らせてしまうことでスタッターが発生する」ことのほうが,はるかに重大,ということになる。しかも,これはレンダリングの“内部事情”となるため,ドライバ側の対応には限界がある。
とはいえ,「ドライバでは対応できないので,ゲーム開発者さん,頑張ってください」と放り出すわけにもいかない。そこでNVIDIAは,この問題に対してもドライバ側に対策を導入した。それが,NVIDIAコントロールパネルに用意された「SLI rendering mode」という設定項目だ。
SLI rendering modeに「Force alternate frame rendering 1」(以下,AFR1)と「Force alternate frame rendering 2」(以下,AFR2)という2つの選択項目があることは,以前から知られていた。ただ,筆者が記憶する限り,この2項目にどういう違いがあるのか,NVIDIAから公式に説明されたことはなかったと思う。明らかになったAFRの秘密とはこの部分で,今回,Nordskog氏は,両者の違いを明快に説明してくれたのである。
いわく,AFR1は,直前のフレームを参照するリクエストがあったときに,変更があったデータのすべてをGPU間で転送するという設定だ。それに対してAFR2では,リクエストされたデータ転送の多くを省略するという。
「AFR2は(データ転送でスタッターが発生するようなゲームの)フレームレートをスケーラブルに高められるが,ときとして問題が生じることもある」と氏は述べていたが,データ転送を端折るのだから当然だろう。
NVIDIAは,自社のラボで検証を行い,AFR2を適用しても問題がないと確認されたタイトルに限り,SLI構成時に「GeForce Experience」の最適化設定を行うと,自動的にAFR2が選択されるよう設定しているのだそうだ。
ただ,これら2つのAFRモードで,どんなゲームにも対応できるわけではない。そのためNordskog氏は,「SLIのスケーラビリティを高めるには,ゲーム内部でGPU間のデータ転送が発生しないような設計にすることが効果的だ」とアドバイスしていた。
その具体的な方法は多分にプログラマ向けの話になるため詳細は割愛するが,簡単にまとめておくと,NVIDIAのドライバで提供されているAPIを使うと,「システムがSLIで動作しているかどうか」「SLI構成における何番めのGPUで動作しているか」といったことを,コードの内部で確認できるそうだ。この情報を使って,SLIを前提にしたデータのやり取りを行うようにすればいいという。
また,「片方のGPUで当該フレームだけでなく,1つ前のフレームも描画して,データのやり取りを行わない」という手法も,SLIのスケーラビリティを高めることに役立つと,Nordskog氏は話していた。GPUが連続する2つのフレームをレンダリングしなければならないため,性能的に不利な印象もあるのだが,「GPUがそれぞれ前のフレームを参照し,GPU間でデータのやり取りを行うのに比べたら全然マシ」(同氏)とのこと。
Nordskog氏は別の解決策も紹介している。参照する1つ前のフレームと本来のフレームをまとめて1基のGPUでレンダリングしてしまえば,GPU間のデータ転送が発生しなくなるのでSLIのスケーラビリティを高めることに役立つ,というのだ。1基のGPUで2フレーム分をレンダリングしなければならないので,性能面では不利になるように思えるが,GPU間でデータのやり取りが発生するよりは,ずっと効果的なのだとNordskog氏は主張していた。
ちなみに,Nordskog氏は面白いデバッグの裏技も披露してくれた。3Dアプリケーションの実行ファイル名を「AFR-FriendryD3D.exe」に変更して実行すると,
個人的には,このセッションに参加したおかげで,マルチGPU環境におけるスタッターの問題について,かなり理解が深まったように思う。また,ドライバ側で対処できるタイトルとそうでないタイトルが存在する理由や,SLI rendering mode設定の意味が分かったのも収穫だった。
SLI rendering modeの設定は,GeForce Experienceに任せておいたほうが安全ではあるだろうが,GeForce Experienceにプレイしたいゲームの設定がない場合に備え,SLIを日常的に使っている人は,覚えておくと役立つかもしれない。
NVIDIA GameWorks 公式Webサイト(英語)
GDC公式Webサイト
4GamerのGDC 2015関連記事一覧
- 関連タイトル:
GeForce Driver
- この記事のURL:
キーワード
Copyright(C)2011 NVIDIA Corporation