single core CPU 世代の GPU 結果も追加しました。
(1) light 3 + shadow map (ambient + directional x2 + point) GPU OS fps display pix/sec framebuffer --------------------------------------------------------------------- Mali-400MP A2.3 38.96 480x800 15.0M 565 24 8 Exynos 4210 Mali-400MP A2.3 38.96 480x800 15.0M 8888 24 8 Exynos 4210 Adreno 220 A2.3 27.50 540x960 14.3M 565 16 0 MSM8660 Adreno 220 A2.3 25.00 540x960 13.0M 8888 24 8 MSM8660 SGX 543MP2 i4.3 11.83 768x1024 9.3M 8888 24 8 A5 ULP GeForce A2.2 8.00 600x1024 4.9M 565 16 0 Tegra 250 ULP GeForce A2.2 8.00 600x1024 4.9M 8888 16 8 Tegra 250 ULP GeForce A3.1 5.80 800x1232 5.7M 565 16 0 Tegra 250 ULP GeForce A3.1 5.65 800x1232 5.6M 8888 16 8 Tegra 250 SGX 535 i4.3 4.04 640x960 2.5M 8888 24 8 A4 SGX 535 i4.3 11.08 320x480 1.7M 8888 24 8 S5PC100 Adreno 200 A2.2 3.12 480x800 1.2M 565 16 0 QSD8250 (2) light 3 (ambient + directional x2 + point) GPU OS fps display pix/sec framebuffer --------------------------------------------------------------------- Mali-400MP A2.3 42.30 480x800 16.2M 8888 24 8 Exynos 4210 Adreno 220 A2.3 36.27 540x960 18.8M 8888 24 8 MSM8660 Adreno 220 A2.3 32.50 540x960 16.8M 8888 24 8 MSM8660 SGX 543MP2 i4.3 15.27 768x1024 12.0M 8888 24 8 A5 ULP GeForce A2.2 9.50 600x1024 5.8M 565 16 0 Tegra 250 ULP GeForce A3.1 5.90 800x1232 5.8M 565 16 0 Tegra 250 ULP GeForce A3.1 5.74 800x1232 5.7M 8888 16 8 Tegra 250 SGX 535 i4.3 4.76 640x960 2.9M 8888 24 8 A4 SGX 535 i4.3 14.75 320x480 2.3M 8888 24 8 S5PC100 Adreno 200 A2.2 3.52 480x800 1.4M 565 16 0 QSD8250 (3) light 1 (ambient + directional) GPU OS fps display pix/sec framebuffer --------------------------------------------------------------------- Mali-400MP A2.3 59.95 480x800 算出不可 8888 24 8 Exynos 4210 Adreno 220 A2.3 55.36 540x960 28.7M 565 16 0 MSM8660 Adreno 220 A2.3 48.20 540x960 25.0M 8888 24 8 MSM8660 SGX 543MP2 i4.3 45.49 768x1024 35.8M 8888 24 8 A5 ULP GeForce A2.2 17.10 600x1024 10.5M 565 16 0 Tegra 250 ULP GeForce A3.1 13.00 800x1232 12.8M 565 16 0 Tegra 250 ULP GeForce A3.1 12.10 800x1232 11.9M 8888 16 8 Tegra 250 SGX 535 i4.3 12.78 640x960 7.9M 8888 24 8 A4 SGX 535 i4.3 30.00 320x480 4.6M 8888 24 8 S5PC100 Adreno 200 A2.2 6.04 480x800 2.3M 565 16 0 QSD8250 (4) light 0 GPU OS fps display pix/sec framebuffer --------------------------------------------------------------------- Mali-400MP A2.3 59.94 480x800 算出不可 8888 24 8 Exynos 4210 Adreno 220 A2.3 60.00 540x960 算出不可 565 16 0 MSM8660 Adreno 220 A2.3 60.00 540x960 算出不可 8888 24 8 MSM8660 SGX 543MP2 i4.3 60.00 768x1024 算出不可 8888 24 8 A5 ULP GeForce A3.1 46.85 800x1232 46.2M 565 16 0 Tegra 250 ULP GeForce A3.1 34.35 800x1232 33.9M 8888 16 8 Tegra 250 SGX 535 i4.3 52.13 640x960 32.0M 8888 24 8 A4 SGX 535 i4.3 60.00 320x480 算出不可 8888 24 8 S5PC100 Adreno 200 A2.2 11.60 480x800 4.5M 565 16 0 QSD8250 OS = A:Android, i:iOS framebuffer = color depth stencil
画面解像度が異なるため fps で速度を比べることができません。
比較する場合は pix/sec の数値を見てください。
ただしシーンにはポリゴンの重なりがあるので厳密ではありません。
補足が多数あるので前回の記事もあわせてご参照ください。
GPU や転送能力と比べて解像度が高い傾向があるため、実行時間のほとんどが
ピクセルで費やされていることがわかります。(1)→(4) とピクセルシェーダー
(Fragment Shader) の負荷を軽くするとその傾向は下がります。
やはり GPU のおおまかなグループ分けとしては下記の 3つでだいたい合っている
ように思います。
低速 ↑ Group 1 | Adreno 200 | Group 2 | Adreno 205 / PowerVR SGX 535,540 / ULP GeForce(Tegra 250) ↓ Group 3 | Adreno 220 / PowerVR SGX 543MP2 / Mali-400MP 高速
関連エントリ
・OpenGL ES 2.0 Mobile GPU の速度比較 (dual core世代) 更新
・Android HTC EVO 3D GPU Adreno 220 の速度
・OpenGL ES 2.0 shader の演算精度
・Android Galaxy S2 ARM Mali-400 MP は速い (2)
大変参考になりました。
作ったアプリがお客様のAdreno 200の端末で極端に遅くて苦しんでいたのですが、これを見て納得しました。
QSD8250(Adreno 200) と MSM8255(Adreno 205) は
GPU だと 2倍くらい差がつきます。でも CPU 速度は
同一なので、UI とか canvas を使ったアプリだと
違いがないのがまたやっかいです。
Adreno205は2倍速ですか。
こちらのTegra2のテスト機で30〜50fps出るアプリがお客様のAdreno200で5〜8fpsとの事。フラグメントシェーダが絶望的に遅い感じです。
固定シェーダで書かれた同様のアプリは30fps出ているとの事。やっぱり古い世代のGPUですと固定シェーダを使った方が無難なのでしょうか。
それにしてもGroup 3の性能は凄いですね。これだけあれば相当な事が出来そうです。ただそれに合わせてアプリを作ってしまうとまた古い端末で性能問題で苦しみそうですが。
固定機能のパフォーマンスは試してませんでした。
確かに、初期の 1GHz Snapdragon (8250/8650世代) を基準に
プロファイルが作られた WindowsPhone (XNA) は、
プログラマブルシェーダーが使えず固定機能止まりです。
納得です。
ただこれからはプログラマブルシェーダーが優勢で
早い速度でハードウエアの置き換えが進んでいくと思われます。
http://wlog.flatlib.jp/arch…
↑こちらの記事で調べましたがケイブのゲームも
Group 2 以上で線引きをしているようです。
あれからうちで作っているゲームエンジンのサンプルアプリを公開してみたんですが
http://www.moedroid.jp/2297…
このスクリーンショットのfps値(画面左下)を見るとAdreno 205で87fpsとか出てるみたいで驚いています。Adreno200と10倍近い差があるみたいです。ちなみに物理演算もやってます。なんでこんなに差があるんでしょうね。
あと、Galaxy NEXUS(Android4.0.1)の人からは動いたと報告があったのにGalaxy Sではシェーダのコンパイルが通らなくて動かないようです。どちらもPowerVR SGX 540のはずなので、OSのバージョンの違いなのでしょうか。
頂点数はどれくらいでしょうか。
おそらく通常の端末だと 60fps が上限ではないかと思います。
手持ちの端末で動かしてみました。
Desire X06HT (QSD8250 Adreno200): 48fps
camera 映像はスムーズで追従性が良いのですが
3D は速度が落ちていて 48fps にはとても見えません。
5fps 程度に見えます。
Galaxy S2 SC-02C (Exynos4210 Mali400): 45fps
3D も非常になめらかで数値通りに見えます。
Snapdragon で表示されている fps の数値が 3D 描画と
一致していない可能性があります。
GLSL コンパイラの構文はメーカーごとに結構違います。
でも同じ PVR なら大きな違いはないと思われるので
おかしいですね。
初音ミクのモデルで頂点数46,000くらいです。
原因がわかりました。多分テクスチャのクリアを忘れていて、17に8が上書きされて87になっているのだと思います。大変お騒がせしました。
他の方の動画を見るとだいたい10~15fpsくらいのようですので、約2倍ということで計算は合いそうです。
Mali400で45fpsですか。
ASUS Transformer TF101(Tegra2)でカメラ有り25,カメラ無し40fpsなのを考えると、解像度の違いを考慮すれば思ったより差が無い感じですね。
原因がわかりました。どうやらuniformに配列を渡せないみたいです。配列を渡せないとGLSLスキニングが動かないのでかなり遅くなってしまいます。
しかしエラー行くらい表示して欲しいな・・・ぶつぶつ。
結構頂点負荷が高いようですね。
Tegra2 は頂点が強く、Mali400MP は頂点より Pixel が強力なので
そのせいもあるかと思います。
背景を入れたり重い FragmentShader で画面を埋めると
おそらく差が出ます。
Tablet でも試しましたが Landscape で起動するみたいなので
描画ピクセル数はほぼ同一ですね。
Galaxy S2 縦 800
3.0 Tablet 縦 800
配列が使えないのは SGX540 でしょうか。
Galaxy S や同じ S5PC110 を搭載したデバイスを
使ったことがありますが、shader も動いていました。
もちろん uniform の配列を渡してスキニングしています。
あれれ、Galaxy SでUniformに配列を渡せましたか?
NEXUSでは使えたのですがGalaxy Sでは駄目でした。
うーん、何が違うんでしょう。
いまGalaxy SではJava側でスキニングをやっているので5fpsくらいしか出ないようです。
使えるならGLSLスキニングをGalaxy Sでも使いたいです。
せめてエラー行が出れば原因を特定出来るのですが・・・
・・・まさか
uniform mat4 m_BoneMatrices[20];
が大きすぎるとか、そんな原因じゃないでしょうね・・・
一度サイズを10にして試してみます。
Tegra2ではフラグメントシェーダがボトルネックになっているので可能な限り頂点シェーダに処理を移しています。ですので頂点シェーダが重くなっています。
どうやら
vec4(0.0)
という書き方が悪かったようで、それを
vec4(0.0,0.0,0.0,0.0)
に変えたらGalaxy Sで動いたとの事です。
ただそれでもAndroid2.2系の機種では駄目みたいです。
SGX540はドライバーのバージョンが結構たくさんあるようです。
確かにその書式でエラーになった経験があります。
このような情報もどこかにまとめておきたいですね。
どうもSGX540は機種によって使えるuniform変数のサイズが異なるようです。
m_BoneMatrices[20]が通らない機種でもm_BoneMatrices[15]なら通ったりします。
しかしARROWS Xはm_BoneMatrices[3]でも通らないです。
メーカーによってドライバーのバージョンが違うのしょうか。
他のGPUでは全く問題が出なかったのですが、SGX540だけかなり苦労しています。
> このような情報もどこかにまとめておきたいですね。
そういうまとめは是非欲しいですね。
モバイル系GPUの情報はググってもなかなか見つかりませんので。
他に原因があるのではないでしょうか。
m_BoneMatrices 以外に消費している uniform は
どの程度でしょうか。
今まで集めたデータは下記に載せていますが
http://dench.flatlib.jp/ope…
http://dench.flatlib.jp/ope…
PowerVR 系はどれも 128 です。
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS)
やシェーダー内だと定数として
gl_MaxVertexUniformVectors
で参照できます。
ARROWS X は 4430 なので採用機種はかなり多いはずです。
もし OMAP4430 の SGX540 を触る機会があればこちらでも
調べてみます。
なるほど・・・PowerVRのuniform変数の領域はTegra2などの半分くらいなのですね。
uniform変数の数は後で調べてみますが、もしかするとぎりぎりなのかもしれません。
ただ、機種によって動いたり動かなかったりするのは不思議ですが(どれも同じ数しか使ってないはずですので)。
ARROWS Xは[3]にしても動かないのでuniformの領域不足ではないと思われます。ただ、ソフトウェアスキニングだと動きますのでGLSLスキニングのコードが原因になっているのは間違いないと思われます。
動かない原因が分かりました。
Imagination社にapkを送って調査してもらったところ、頂点シェーダに
precision mediump float;
と書いているのが原因との事でした。
PowerVRの一部の機種ではこれを書いてはいけないらしいです。
報告ありがとうございます。
なるほど納得です。
これは precision が使えないのではなく、
Vertex Shader で highp 以外をデフォルト宣言しているのが
問題なのだと思います。
precision highp float; ならエラーにならずに走るはずです。
やはり以前同様のエラーを経験したことがあります。
なので逆に VertexShader で precision mediump float が
使えるとは思いませんでした。
今試したら手持ちの端末ではエラーにならなかったので、
OS アップグレード前の古いバージョンだったのかもしれません。
また多くの GPU は頂点の場合にこの宣言を無視しているのでは
ないかと思います。
いただいた情報を踏まえて GLSL のページを作ってみました。
http://dench.flatlib.jp/ope…
きちんと確認していない部分もあるので少しずつ増やして
いきたいと思います。
> Vertex Shader で highp 以外をデフォルト宣言しているのが
> 問題なのだと思います。
そうだったんですか。
世間一般でVertex Shaderでそう宣言しているソフトは多いですし、問題が起きたのはPowerVRの一部の機種だけで、それも配列のサイズを変えただけで動いたり動かなかったりという挙動でしたので、そこが悪いとは思いもよりませんでした。
ではhighpに変更した方がいいのでしょうか。ただImagination社のエンジニアからは単純に削除しろと言われましたので、また検証するのが大変そうです。
しかし何も書かないでいると将来のバージョンのドライバーがOpenGL ES2.0の規格を厳格に守って、無いとエラーを出すようになったりするとまた動かなくなりそうで心配ではあります。
>いただいた情報を踏まえて GLSL のページを作ってみました。
ありがとうございます。
こういう情報はまだまだ少ないので、大変助かります。
読んで勉強させて頂きます。
頂点シェーダからprecision mediump float を削除したところ、Imagination Technologies社のエンジニアに「頂点シェーダでデフォルトをhighpにすると遅いから色などはlowpを使え」というアドバイスを頂きました。
wikiの方に
> ハードウエア的に VertexShader は highp 以外使えない
と書かれていますが、使えるみたいです。
すみません勘違いしていました。
指摘ありがとうございます。
早速修正しておきます。
default として宣言できないだけで変数個別の
lopw/mediump は VertexShader でも使っていました。
default の precision 宣言がエラーになったり
パフォーマンスの違いに繋がるということは
暗黙の gl 変数に影響を与えているのかもしれません。
時間ができたら詳しく調べてみたいと思います。
同じ PowerVR + 同じ shader でも 540 より
SGX543MP の方が ShadowMap が綺麗に出るので
モデルによって演算精度の違いもあるのかも
しれません。
IS05で特定モデルでOSごと落ちるとの報告があり調査しました。
落ちるのは透明テクスチャのあるモデルのみで、調べた所、フラグメントシェーダで透明部分をdiscardしていたのが原因でした。
その行をコメントにしただけで動くようになったのですが、そんな事があるのでしょうか。
ググっても同様の報告は無いようです。
ちなみにAdreno200では問題無く動いています。Adreno205で問題が発生するようです。
そんなばかなと思って試したら再現しました。
驚きましたが確かに落ちます。
ただし全てではなく動いているシェーダーもあります。
1. 3D model 用 shader
もともと discard を使っていませんでしたが、
命令を追加すると再現しました。
Adreno 200/220 問題なし
Adreno 205 停止
2. 2D Font shader
discard を使っていますが Adreno200/205/220 全てで
正しく動作しています。
その後条件を調べたところ、Adreno 205 でも最後の gl_FragColor
の直前に discard を挿入した場合は落ちないことがわかりました。
ここからは予想ですが、Adreno 205 のみ discard 命令の後で
テクスチャフェッチを行うと固まるのではないかと思います。
問題に気が付かなかった理由として、discard は PVR の TBDR と
極めて相性が悪いので、PVR 最適化のために使っていませんでした。
もしくは alpha test を使うのは単純なシェーダーなので
texture 1枚しか使っておらず、discard が必ず最後にありました。
驚きますよね、さすがに。
確かに私のシェーダではdiscardした後にトゥーンシェード用のテクスチャをフェッチしていました。これが原因だったのでしょうか。でしたら対処は簡単です。
メモリー消費量によって落ちる件については、Adreno200,205,220で起きています。
こちらはアプリレベルでの対処方法が見つからず、苦慮しています。
それにしてもこんな事くらいでOSごと落ちてしまうのは、携帯電話用GPUとしてどうなのでしょう。
将来AndroidにWebGLなどが降りてきたら、大丈夫なんでしょうか。
discardについてはQUALCOMM社のサポートに調査依頼を出しておきました。
今のところ返答は無しです。
1点、PowerVR系は128ベクタ以上のuniformを使えます。ただし128を超えると外部メモリーに入れられてしまうためなるべく使うなということだそうです。
非常に興味深い情報ありがとうございます。
GL_MAX_VERTEX_UNIFORM_VECTORS が 128 を返すので
OpenGL ES ではそれ以上使うことは無いと思いますが、
同じ PowerVR SGX535 は GMA500/600 として
Z シリーズの Intel Atom にも使われています。
こちらは Direct3D9 ShaderModel 3.0 に対応しているので
Constant Register (Uniform) が 256 個使えることになります。
なぜ GLES だけ 128 なのか長年疑問でしたが謎がひとつ解けました。
Direct3D10 の ConstantBuffer のようなバッファメモリに
なっているのかもしれません。
確か当初は D3D10 にも対応を予定していたと思います。