イベント
[GDC 2014]Compute Shader導入で注目が集まるOpenGL ES 3.1セッションレポート。OpenGLのドライバオーバーヘッドは「Mantle」と戦えるレベルに
その概要は3月18日の記事で掲載済みだが,ここでは説明会で披露されたOpenGL ES 3.1の要点と,AMDの「Mantle」登場で注目されるようになったドライバオーバーヘッドが,OpenGLではどうなっているのかといった話題をレポートしたい。
OpenGL ES 3.1の説明を担当したのは,ARMでグラフィックス研究部門のディレクターを務めるTom Olson(トム・オルソン)氏である。
OpenGL ES 3.1は既存のOpenGL ES 3.0対応ハード上で動作
OpenGL ES 3.1でKhronosは,OpenGL 4.x系の機能から,開発者からの要望が最も多かった機能をピックアップして採用したという。その中でもとくにホットなトピックは,「Compute Shader」と「Draw-Indirect」(Indirect draw commands)の導入だ。
まずはCompute Shader導入の意義を説明しよう。
これまでのOpenGL ESには,GPGPUを扱うソリューションがなく,OpenCLを活用するしかなかった。本家OpenGLも,「OpenGL 4.2」までは同じような状況だったのだが,開発者からのリクエストを受けて「OpenGL 4.3」でCompute Shaderを導入することになった。このあたりの経緯はSIGGRAPH 2012のレポート記事で紹介しているが,OpenGL ES 3.1におけるCompute Shaderの採用も同じ流れの上にあるものという理解でいいだろう。
「GPGPU用APIにはOpenCLがあるのに,なぜ開発者はCompute Shaderを求めるのか」といえば,グラフィックスレンダリング向けにGPGPUを活用するなら,OpenCLよりも,OpenGLの枠内でCompute Shaderを使うほうが都合がいいからだ。
独立した画像処理やフィルタリング処理をするというなら,OpenCLでもいいだろう。しかし,不要な光源を排除する「ライトカリング」(Light Culling)のようなレンダリング支援処理や,レンダリング結果にモーションブラーのようなポストエフェクトをかけるという場合は,同じグラフィックスパイプラインの中で処理できるCompute Shaderのほうが,面倒がなくて都合がいい。
もう1つのホットトピックであるDraw-Indirectは,メモリ上に置いたジオメトリデータなどを,CPUを介すことなくGPU側で取得してレンダリングに回せるという仕組みである。もともとOpenGL ARB(Architecture Review Board)が策定したARB拡張仕様にあり,OpenGL 3.1で導入されていたものが,OpenGL ESにやってきたことになる。
Compute Shaderは,グラフィックスメモリに任意のデータ,たとえばプリミティブ(=ポリゴン)を初めとしたジオメトリデータを書き出せる。つまり,Compute ShaderとDraw-Indirectを組み合わせると,描画すべき3Dグラフィックスデータの準備から描画までをGPU側で実行できるようになるわけだ。
「生成したパーティクルやシミュレーションした結果をグラフィックスデータに変換して,それを基に描画を行う」といったことが,GPU内で完結できるようになる。CPUの手助けは不要となので,アプリケーションのCPU負荷を減らせるうえ,CPUと非同期かつ並列なグラフィックス描画を行うことも可能になる。
これは処理性能の向上だけでなく,モバイル機器にとって最重要課題である消費電力の削減――効率化というべきか――にも有効となるだろう。
なお,OpenGL ES 3.1は基本的に,OpenGL ES 3.0世代のハードウェアでそのまま動作する。新機能はどれも,ドライバレベルで実現できるというわけだ。また,「OpenGL 4.4」でOpenGL ES 3.1ベースのアプリケーションを動かすための手段も,近い将来提供されるとのことだ。
「最新のOpenGLはMantle並にオーバーヘッドが少ない」
ここでいうドライバのオーバーヘッドとは,GPUを駆動するまでの前段階で,主にCPU側で実行されるプログラム部分で発生する時間的なロスのことを指す。
GPUを駆動するためには,コマンドやパラメータを準備してドライバに受け渡す処理が必要となるが,これは基本的にはシーケンシャルな動作なので,必然的にシングルスレッドで実行されることになる。マルチコアCPU環境でも,GPUを駆動するために動作するCPUは通常1コアだけなので,これでは効率を上げられずにオーバーヘッドが生じてしまう。
一方のGPU側も,コマンドやパラメータが揃わないと処理を始められないので,これらがドライバから与えられるのを待たなくてはならない。これもオーバーヘッドを生じる原因になる。
その点,OpenGLはどうなっているのか。Trevett氏は「『OpenGLは基礎設計が古くて遅い』と言われるが,OpenGL 3.x以降は,DirectXよりもモダンなアーキテクチャになっているので,大きな改変を必要としていない」と主張する。
プログラマブルシェーダに初めて対応したOpenGL 2.x時代は,固定パイプライン基軸の設計により,オーバーヘッドが生じやすい構造になっていた。
しかし,Trevett氏は「OpenGL 2.x以前のAPIで制作されたアプリケーションはオーバーヘッドが大きかったものだが,OpenGL 3.x以降をうまく活用すると,CPUとGPUが並列に動作できるようになる」と述べる。オーバーヘッドを減らしてハードウェア性能が引き出しやすくなるよう,改良を重ねてあるというわけだ。
OpenGL 3.x以降は,クラシックなアーキテクチャを改めて,コマンドやパラメータを記述したバッファそのものを,APIを介さずにGPUに直接転送できる仕組みが実装された。これにより,CPU側がマルチスレッドでコマンドやパラメータをまとめたバッファを形成すれば,バッファをどんどんGPUに転送できるようになる。GPU側はCPUの都合を気にせず,転送されたバッファを使って,非同期に描画を実行できるようになったのだ。
互換性維持のために固定パイプライン機能は残ってはいるものの,OpenGL 3.x以降を使っている限り,オーバーヘッドはすでに十分なほど小さくなっている。これがKhronosの立場である。
また,Trevett氏は,「Draw-Indirectを活用すれば,『GPU自体がGPUを駆動する』動作を効果的にプログラムできる」と述べ,アプリケーションがハードウェアの性能をさらに引き出せるよう,OpenGL ES側でも進化が続いていることをアピールしていた。
もっとも,モバイルデバイス向けに進化してきたOpenGL ESはともかく,PC上で動作するOpenGLの場合,過去のソフトウェア資産を簡単には切り捨てられないという事情もある。もしかするとKhronosは,「小型軽量でスマートなOpenGL」を実現するのは,OpenGLではなくOpenGL ESのほうだと考えて,そちらを今後は育てていこうと考えているのかもしれない。Trevett氏の講演を聞いた筆者は,そう感じた次第である。
Khronos Group公式Webサイト(英語)
GDC 2014公式Webサイト(英語)
- 関連タイトル:
OpenGL
- この記事のURL: