技術

インスタンストレンダリング(インスタンストアトリビュート)と頂点データをひとつにまとめたレンダリングの比較

インスタンストレンダリングはOpenGL ES 3.0からの標準機能ですが、iOS7では、全てのiOS7対応デバイスにおいてOpenGL ES 2.0でも拡張機能としてインスタンストレンダリングができるらしいです。
ということで手持ちのiOS7対応デバイスで(といってもiPhone 4sと5sだけですが)軽く性能を計測してみました。
(GLKViewControllerだと60FPSが上限みたいなので、その辺りを割り込む辺りしか計測してません。)

インスタントレンダリングは、頂点属性にインスタンスの変数を格納するインスタンストアトリビュート方式を使用しています。
以下、インスタンストレンダリング(インスタンストアトリビュート)を用いた方法をA、昔ながらの頂点データをひとつにまとめるレンダリング方法をB、とします。

処理内容

基本的には、大量の微小な三角形を半径1の球の表面に一様分布させそれを表示するプログラムです。
視点は球の中心にあり、背景が黒なのでちょうど星空を見てるような感じになります。
AのプログラムとBのプログラムで異なる部分は以下のとおりです。

頂点データのレイアウト

A. 三角形1つ分の頂点(vec3 * 3)、色(vec4 * インスタンス数)、変換行列(mat4 * インスタンス数)
B. 全頂点データ((座標(vec3) + 色(vec4)) * インスタンス数)

頂点シェーダー

A. アトリビュート変数で受け取った頂点を、アトリビュート変数で受け取った変換行列で変換する。
B. アトリビュート変数で受け取った頂点をそのまま出力する。(座標変換は頂点データ生成時に済んでいる。)
もちろんどちらもさらにビュープロジェクション変換行列で座標変換をします。

フラグメントシェーダー

どちらもフラグメントシェーダーでは何の計算もせず、色のデータをそのまま入力から出力に流すだけのごく簡単なものを使用。

計測結果

iPhone 4s

A.

インスタンス数 CPU使用率 メモリ使用量 FPS
4096 / 2 11-12% 3.2MB 60
4096 * 1 99% 7.8MB 25

B.

インスタンス数 CPU使用率 メモリ使用量 FPS
4096 * 64 9% 24MB 55-60
4096 * 128 7% 45MB 28-30

4sの場合はAよりBのほうが100倍ぐらい速いようです。
Aが遅い原因ですが、4096 * 1(約4千ポリゴン)の段階でCPU的に頭打ちになっているので、インスタンシングをドライバ(ソフトウェア)で一部エミュレーションしてるのかなと思います。
で、4096 * 1でなんらかのデータがなんらかのキャッシュに乗らなくなって4096 / 2(約2千ポリゴン)の場合に比べて急激に性能劣化してるのではないかと。
インスタンス数分のドローコールを内部で実行しなおしてるだけだったりしてw
Bの4096 * 64(約26万ポリゴン)の結果から、リアルタイムレンダリングにおける実際のGPUの限界はこのあたりにありそうです。
ちなみにAの場合のCPU使用率はデバッグビルドでもリリースビルドでも変化なしでした。

iPhone 5s

A.

インスタンス数 CPU使用率 メモリ使用量 FPS
4096 * 32 6% 14MB 60
4096 * 64 4% 24MB 37
4096 * 128 4% 44MB 19

B.

インスタンス数 CPU使用率 メモリ使用量 FPS
4096 * 64 6% 24.9MB 60
4096 * 128 7% 45.9MB 55-58
4096 * 256 6% 86.5MB 34-37
4096 * 512 5% 170MB 19-20

こちらは4sとはだいぶ違った様子です。
CPU負荷はどれも抑えられてるのでAの場合もBの場合もGPUがボトルネックになってて、インスタンシングがGPUのハードウェアでちゃんと行われているように見えます。
AよりBの方が4倍速いですが、Aの方が頂点シェーダでインスタンスごとの変換行列をかけてる分重いので、インスタンシングそのものにどのくらいオーバーヘッドがあるかは分かりません。
ただ、4分の1の性能でも個別に変換行列をかけれるのはものすごいメリットだと思いますので、適材適所で使い分けるのがいいのではないでしょうか。

不思議な点

インスタンストレンダリングとは関係ないのですが、4sと5sでBのパターンの性能を比べたときに5sの性能が低すぎる気がします。
4sのGPUであるSGX543は、カタログスペックで3千5百万ポリゴン/秒となっており、Bの4096 * 64の場合だと実際に1千5百万ポリゴン/秒出てる計算になり、こちらは納得感があります。
しかし、5sのGPUであるG6430は、カタログスペックで3億5千万ポリゴン/秒であり、SGX543の10倍となっています。
しかし、5sのBの4096 * 128の場合にすでに4sのBの4096 * 64の場合と同じレベルのFPSに落ち込んでおり、5sは4sと比べて単純に2倍程度のポリゴン処理能力しか無いように見えます。
カタログとはクロックが違うのか、性能を引き出す方法が何かあるのか…謎です。

とにかくまとめ

Apple A7 GPUより古いGPUでもインスタンストレンダリングは使えるけど、古い機種だと速度的にやばいゾ!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください