Search Results


Android 版 3DMark アプリの DEVICE CHANNEL から各機種の結果を見ることができます。
非常に興味深く、見ていて面白いデータです。
まとめてみました。

SoC      CPU       core  GPU              Score        CPU vs GPU
-----------------------------------------------------------------
APQ8064  Krait      x4   Adreno 320       8000-11000   CPU <= GPU*
Exynos5D Cortex-A15 x2   Mali-T604        7800        *CPU >  GPU
MSM8960  Krait      x2   Adreno 225       5000-6500    CPU <= GPU*
MSM8x60  Scorpion   x2   Adreno 220       3700-5000    CPU <= GPU*
Tegra3   Cortex-A9  x4   ULP GeForce(12)  3000-4000   *CPU >> GPU
K3V2     Cortex-A9  x4   Vivante GC4000   3400-3700   *CPU >> GPU
OMAP4470 Cortex-A9  x2   PowerVR SGX544   3600        *CPU >> GPU
Exynos4Q Cortex-A9  x4   Mali-400MP4      2500-3400   *CPU >> GPU
Z2460    Atom       x1   PowerVR SGX540   2400        *CPU >> GPU
Exynos4D Cortex-A9  x2   Mali-400MP4      1600-2100   *CPU >> GPU
OMAP44x0 Cortex-A9  x2   PowerVR SGX540   1300-3400   *CPU >> GPU
MSM8x55  Scorpion   x1   Adreno 205       1750         CPU <  GPU*
RK3066   Cortex-A9  x2   Mali-400MP4      1200-2800   *CPU >> GPU
Tegra2   Cortex-A9  x2   ULP GeForce(8)   1400-2100   *CPU >> GPU

・Score の値が大きい方が速い
・数値は常に変動しているので現時点での目安としてみてください。

一番右端の列は CPU と GPU どちらのスコアが高いかを示しています。

全体的に Adreno22x/320 の数値が高い傾向にあります。
右側の列を見てわかるように、CPU よりも GPU のスコアが高いのは
Qualcomm (Adreno) のプロセッサだけです。

Exynos/OMAP/Tegra 等、Quallcom 以外はすべて CPU の方が高くなっており、
その差も 2倍程度まで広がっています。

なぜこのような結果になっているのか考えてみます。


●CPU

CPU は 2グループあります。

(A) Cortex-A9, Scorpion
(B) Cortex-A15, Krait

(B) は新しい世代の CPU core で、動作クロックの違いもありますが
実行効率そのものが向上しています。
例えば (A) が 2命令 deocde の Out-of-Order 実行だったのに対し、
(B) グループは 3命令に引き上げられています。
同一クロック、同コア数でも Krait, Cortex-A15 の方が高速です。


●Adreno

各社の SoC/GPU は多種多様で得意分野がはっきりしています。
Adreno は ATI の流れをくむモバイル向け GPU で、
最も Desktop 向け GPU に近い機能を持っています。
これは他の GPU にはない大きな特徴です。

例えば頂点テクスチャや Volume Texture (3D Texture) など、
Mobile 向け用途ではあまり必要とされない機能にもしっかり対応しています。
実際に各種 GPU 機能を比較した表は下記のとおりです。

Mobile GPU の比較

Fragment Shader (PixelShder) の演算精度も fp32 の highp 固定で、
描画クオリティも Desktop GPU と同等です。
パフォーマンスを上げるために見た目を犠牲にする必要がありません。

その代わり初期の Adreno 20x/AMD Z430 では頂点キャッシュが無く、
Desktop GPU 同等の描画機能を有する反面、パフォーマンスが思ったように
伸びない傾向がありました。
この点は Adreno 22x 以降改良されており、描画プリミティブに依存せず
大きくスループットが上がっています。

複雑なシェーダーもかなり走るのですが、アプリケーションによっては
あまり速度が出ていないものが存在します。
あくまで想像にすぎませんが、Adreno は OpenGL ES 1.1 の固定パイプを
シミュレーションするのが苦手なのかもしれません。(未確認です)

Shader を使って描画を行う場合、Adreno はモバイルに特化した最適化を
極端に行う必要がなく、シェーダーを移植しても速度が落ちにくい傾向を持っています。
このあたりがベンチマークに有利に働いたのではないでしょうか。
まとめると

・highp 固定なので、演算精度を落とさなくても速度が変わらない。
 ・モバイル向けに mediump/lowp 化するなど特別な最適化を行う必要がない。
 ・PC の描画クオリティから落とす必要がない。
・Uniform 数, Sampler 数も多く Extension も豊富で互換性を取りやすい。
・Unified Shader なので、Vertex 負荷、Pixel 負荷どちらにも対応しやすい。

また Adreno 320 は OpenGL ES 3.0 に対応した新しい設計の GPU core なので
世代的にもかなり高性能です。
使われている API が ES 2.0 なので、まだ眠っている HW 機能があります。
今後さらにスコアが伸びるものと考えられます。

Mobile GPU bench mark


●Mali-400MP4

GPU の「Core 数」は GPU によって数え方が異なっており単位がばらばらです。
端末のスペックに GPU の core 数が書かれている場合がありますが、
性能の指標になるのはあくまで同一 GPU 同士を比べる場合だけです。

PowerVR SGX の MP1~4 は CPU とほぼ同じ概念で、
GPU そのものが複数存在し並列に動作します。

Tegra の core 数は GPU 内の演算ユニットの数を表しています。
G80以降 の Desktop GPU に合わせたもので、Unified Shader の
Stream Processor 相当で何個分なのかを表しています。
Discrete ですが Vertex, Fragment 両方カウントされます。

Mali-400 は下記のページの図 (Mali-400 MP Image) にあるように
Fragment Processor の UNIT 数を選択可能で、MP1~MP4 と呼ばれています。
この数には Vertex Processor が含まれていません。

ARM Mali-400 MP

Tegra2/3 でも 8→12 と core 数は増えていますが頂点 Unit 数は同一です。
もし仮に Mali-400MP 同様 Fragment Processor だけ数えるなら
Tegra2 の ULP GeForce(8) は Vertx 4 + Fragment 4 で MP1、
Tegra3 の ULP GeForce(12) は Vertex 4 + Fragment 8 で MP2 となるでしょう。

つまり Discrete Shader の GPU ではスペック表記上の core 数が増えても、
頂点性能が向上するとは限りません。

Galaxy S2 で Mali-400MP4 登場した時は非常に Pixel パフォーマンスが高く、
他の GPU と比べても良い性能でした。
ですがその後複雑な 3D シーンでは頂点性能がボトルネックになることが
わかっています。

上記のように MP4 でも頂点性能は増えておらず、
10~20万など比較的低いレベルで頭打ちになってしまうようです。

3DMark Ice Storm のポリゴン数はかなりハイポリゴンだと考えられるため、
Mali-400MP4 のパフォーマンスが振るわないのはそのためだと考えられます。

Pixel Shader は mediump なので、厳密には Desktop GPU より演算精度が落ちています。
ただし Tegra や PowerVR SGX のように、最適化で精度を削るほどシビアではありません。
頂点がボトルネックになるだけでピクセル側は mediump 固定なので、
あまり手を加える必要は無いようです。

Mali-T604 以降は Unified Shader なのでまた特性が異なっているはずです。


●Tegra2/3

Mali-400MP と同じ Discrete Shader ですが、特性は正反対です。
頂点に余裕がある代わりに Pixel が足りなくなります。
比較的ハイポリでシンプルなマテリアルの場合に良いパフォーマンスとなるようです。

Mali-400MP 同様 Pixel 精度は mediump までですが、複雑なシェーダーコードでは
lowp を併用して質よりも速度を優先する必要が生じます。
depth の解像度も他の GPU より落ちます。

他の GPU よりも対応 Extension が少なくなっており、ハードウエアの機能も大胆に削られてます。
例えば depth texture が使えないので、ShadowMap はカラーマップに
書き込む必要があります。
depth を圧縮しなければならないので、シェーダーにも追加の演算コードが必要です。
OpenGL ES 2.0 の仕様上 depth texture 対応は必須ではないのですが、
対応していない GPU が Tegra2/3 だけとなっています。

3DMark では比較的ハイポリでも Mali-400MP ほどスコアが落ち込むことはなくなっており、
GPU の能力として妥当な結果だと思います。

NVIDIA らしくない性能の GPU もおそらくこれが最後でしょう。
Tegra4 では機能面でも速度面でも大きく手が加えられており、
かなりスコアが伸びるものと考えられます。


●PowerVR SGX

以前の記事にも書いたように、PowerVR SGX 5xx は 2種類あります。
Android 端末では古い Series 5 (SGX540) が多いため、
GPU の性能的にもベンチマークのスコアがあまりよくないようです。
他にも考えられる原因はあります。

PowerVR SGX はどんな描画でもそつなくこなす傾向があります。
頂点が多いシーンでもピクセルが多いシーンでも柔軟に追従します。

使い方の自由度も高く、画質優先に振っても良いし、速度重視にもできるし、
用途によって使い分けられます。
その反面、決まった解法がなく状況に応じた判断を求められます。

例えば Uniform 数はパフォーマンスを考えるなら 128個以内、
移植性や使いやすさなら 256個使うなど。(過去記事の comment参照)

また Pixel に highp fp32 を使うことができるので、
Desktop GPU と同一の精度で描画することができます。
パフォーマンスがあまり上がらないので、速度を考えるなら
見た目を犠牲にしてでも mediump, lowp へと置き換えることになります。

他の GPU と違い TBDR なので、ALU の利用効率が全体のパフォーマンスに
与える影響が大きくなっています。

通常の GPU はラスタライザから PixelShader (Fragment Shader) が呼ばれるので、
パイプライン待ちのサイクルが存在します。
ラスタライザや depth test など、他のステージが詰まっているときは
Shader を削っても速度が大きく変化しません。

PowerVR SGX は Deffered Rendring なので、Pixel Shader が呼ばれるときは
ラスタライザ等他のステージが完了しています。
Shader の命令を削れば削るほど直接パフォーマンスに響いてくるので
最適化はシビアになりがちです。

ここが最も Adreno と違うポイントで、パフォーマンスを優先するならかなり
手を加える必要があります。高速化出来る余地が残っているともいえます。

なお見た目が変わるとベンチとしての正しい比較とは言えないかもしれないので、
3DMark は比較的高い演算精度でレンダリングしているのではないかと考えられます。
もしそうなら、Tegra/Mali とは違い PowerVR のスコアはまだ上がる余地が
残っていることになります。

iOS 版が出たら、どの程度 PowerVR SGX 向けに最適化されているのか
わかるのではないでしょうか。


・おそらく GPU 毎の Shader 最適化がそれほど強くないので、速度が落ちにくい Adreno が有利
・OpenGL ES 3.0 対応最新 GPU + 新 CPU と、いち早く世代交代した Qualcomm (Krait quad + Adreno 320) がやっぱり速い



関連エントリ
3DMark Android Edition Ice Storm v1.1 の結果
GPU 速度に関連するエントリ


oga at 02:26
Mobile Device はここ数年かなりの速度で向上しており勢いが衰えていません。
GPU, CPU ともに今までテストしてきたとおり、PC や専用機に匹敵する能力を
有するようになって来ました。


●個性が偏るモバイルプロセッサ

PC と同じように端末の性能には大きな開きがあります。

現時点で入手可能な最速の CPU は Snapdragon APQ8064 (Krait Quad core) Snapdragon 600 APQ8064T (Krait 300 Quad core) でしょう。
明日 2013/04/04 には 1.7GHz の Optimus G Pro L-04E が発売予定となっています。

日本で発売されたスマートフォン、Tablet 等の全リスト

今すぐ手に入る端末の GPU では間違いなく iPad4 の A6X が最速です。

Mobile GPU bench mark

PowerVR SGX500~ の型番を持つ GPU は数多く存在しますが、
大きく分けて 2種類あります。

PowerVR Series 5        SGX530, SGX535, SGX540
PowerVR Series 5XT      SGX543MP, SGX544MP, SGX554MP

型番が似ているのでややこしいですが、この両者は PVRTC2, ShadowSampler,
演算精度, MultiCore など機能的な違いもあります。
その中でも最上位 SGX554MP4 を搭載しているのは iPad4 の A6X だけです。


このようにハイエンドの端末といってもそれぞれ何を重視するかによって評価が変わります。
Apple は GPU を最優先しており、その反面 CPU で Quad core の端末はまだ存在していません。

方向性で真逆なのが NVIDIA Tegra です。
率先して Dual core, Quad core の Tegra2/3 を展開してきたものの
トレードオフとして GPU 機能が弱く、描画性能も芳しくありません。

よって、性能差だけでなく性格付けでも特性がバラバラなのがこれまでの
モバイルデバイスの特徴でした。

 ・トレードオフがあるため一部分だけ秀でている
 ・メーカー毎に強化している分野が異なる

ただし次の世代ではこれらのアンバランスさがかなり解消されると考えられます。



●世代交代

他社に先駆けて GPU/CPU ともに世代交代を果たした Qualcomm では、
特別突出した点はないものの平均的に全体の性能が高くなっています。

また今後登場予定の Tegra4 は CPU core が刷新されるだけでなく、
ようやく NVIDIA らしい GPU へと強化が行われるようです。

4gamer: [GDC 2013]タッチパネルは対応しなくていい? Androidの掟破りが連発された「Project SHIELD」向けゲーム開発指南

Tegra2/3 の GPU である ULP GeForce は Shader Unit が discrete で
あることから GeForce6800/7800 世代と言われていましたが、
機能的には大幅に削られたものでした。

例えば GeForce の特徴的な機能だった NVIDIA ShadowMap (PCF) が
Tegra2/3 には搭載されていません。
それどころか今まで試した GPU の中では、Tegra2/3 だけが 24bit depth
や depth_texture に未対応でした。
他社の GPU 、Adreno, PowerVR, Mali, Vivante はみなこれらの Extension
に対応しているにもかかわらずです。

上記サイトのスライド写真を見ると Tegra4 でようやく機能差が解消されており、
かつ Hardware PCF が搭載されるなど、期待した GeForce 6800/7800 クラスの
GPU となるようです。

ざっくりと 4 pixel pipe なので能力的にはおそらく無印 GeForce 6800 くらい
ではないでしょうか。
pixel rate は PS3/Xbox360 世代の半分ですが、メモリ帯域からも納得できる数値です。

Xbox360  22.4GB/s (+32.0GB/s)
PS3      22.4GB/s (+25.6GB/s)
Tegra4   14.9GB/s

もちろん予想に過ぎないので、実際に手に入れてみるまでは本当の性能はわかりません。

CPU/GPU 共に世代交代によって、一点集中型から平均的な性能向上に向かうと
考えられます。極端な個性付けはおそらく減っていくのではないでしょうか。



●コンソールとの比較

Xbox1/GC 時代のコンソールは確実に超えています。
まず CPU の速度が桁違いで、GPU 性能もシェーダーなどはるかに高機能です。
ただしフィルレートに特化した PS2 の特殊なハードウエアは正しく比べることができません。

またモバイルデバイスに要求される解像度はコンソールよりも高いので、
その点も考慮する必要があります。

          mem B/W                CPU          RAM    screen
---------------------------------------------------------------
GC        2.6GB/s (+?)           0.5GHz x1    24MB   SD 480
PS2       3.2GB/s (+48.0GB/s)    0.3GHz x1    32MB   SD 480
Xbox1     6.4GB/s                0.8GHz x1    64MB   SD 480
Xbox360  22.4GB/s (+32.0GB/s)    3.2GHz x3   512MB   HD 720
PS3      22.4GB/s (+25.6GB/s)    3.2GHz x7   512MB   HD 720
PS4     176.0GB/s                ?.?GHz x8     8GB   HD 1080

Tegra3    6.0GB/s                1.7GHz x4  1~2GB
APQ8064   8.5GB/s                1.7GHz x4           HD 1080
A5X      12.8GB/s                1.0GHz x2     1GB   HD 1536
Tegra4   14.9GB/s                1.9GHz x4
A6X      17.0GB/s                1.?GHz x2     1GB   HD 1536

誰が見ても明らかな点としては RAM 容量があります。
スマートフォンもタブレットも 1GB~2GB の RAM 容量が当たり前となっており、
この点では現行コンソールよりも余裕があります。



●実デバイスでの CPU の速度

実在のデバイスでの性能比較
(実測ではなくスペックからの算出値なので注意)

                             CPU           Clock  DMIPS/clock  DMIPS*core
-------------------------------------------------------------------------
Nexus 10            Exynos 5 Cortex-A15 x2  1.7GHz   3.5          11.90
ARROWS X F-02E      Tegra3   Cortex-A9  x4  1.7GHz   2.5          17.00
Optimus G Pro L-04E APQ8064T Krait 300  x4  1.7GHz   3.3          22.44

Xbox360             Xenon    PPC core   x3  3.2GHz   2.0~(3.2)   19.20~(30.72)

・DMIPS*core が総合性能(目安)で数値が大きい方が速い

CPU core が異なっていると比較が難しいためあくまで目安として見てください。
DMIPS/clock は同一 clock で比較した core 単体の能力で、
これを clock*core 倍したものが DMIPS*core となっています。

Xbox360 の DMIPS/clock はWikipedia Instructions per second を元にしています。
ただし同一性能のはずの PS3 PPE が 3.2 なので、Xbox360 の実際のスコアは
もっと高い可能性があります。(括弧内の数値は 3.2 を元にした場合)
PS3 の Cell は特殊で簡単に比較することができません。

CPU core list

今後登場するであろう Exynos 5 Octa (Cortex-A15 x4) や Tegra4 (Cortex-A15 x4)
のスコアを予想すると下記の通りです。

                             CPU           Clock  DMIPS/clock  DMIPS*core
-------------------------------------------------------------------------
Exynos 5 Octa                Cortex-A15 x4  1.6GHz   3.5          22.40
Tegra4                       Cortex-A15 x4  1.9GHz   3.5          26.60

あまり厳密な比較ではないかもしれませんが、CPU 能力で現行コンソールに
匹敵するレベルに達しつつあることは事実です。

ただし、単精度の浮動小数点演算能力では敵いません。

          CPU                fp-op/core   core   clock    GFLOPS
----------------------------------------------------------------
Xbox360   Xenon PPC            12         3      3.2GHz   115.2
PS3       Cell BE              12+8       1+7    3.2GHz   217.6
          Tegra3 Cortex-A9     4          4      1.7GHz    27.2
          APQ8064 Krait        8          4      1.7GHz    54.4
          Tegra4 Cortex-A15    8          4      1.9GHz    60.8

・GFLOPS が大きいほうが速い。
・理論値なのでこの通りの性能が出るわけではありません。

特に Cell は圧倒的で、フィルレートの怪物だった PS2 と同じように、
一部分(浮動小数点演算能力)において突出した能力を持っています。

予想では多分 PS4 でも CPU 単体の浮動小数点演算能力においては Cell に
届かないのではないかと思います。
その代わり GPU にストリーム処理を任せられるので、
GPU を補っていた Cell とは逆の立場になります。



GPU速度

・Mobile Device は非常に解像度が高い
GPU の構造が異なっている
・Tegra は演算精度が違う
・機能面は同等

Smartphone でも Full HD、Tablet だと 2048x1536 や 2560x1600 など
かなりの高解像度になりつつあります。
メモリ帯域も Shader サイクルも多くがピクセルに費やされます。
そのためたとえ GPU 性能が高くなっても相対的にはパワー不足に陥ります。


大半の GPU が TileBased となっており、Desktop GPU と構造が異なっています。
特に PowerVR は何もしなくても HW で Deferred Rendering を行うので、
ソフトウエアであまり凝ったことをすると逆効果となる可能性があります。

例えば Early Z Culling を効果的に使うには手前から描画しますが、
ピクセル単位でフラグメントが除去される TBDR では不要です。
またポストエフェクトのようにフレームバッファを再利用すると追加コストが
発生する可能性があります。
この辺りを意識して作られていない場合、ただ移植しただけでは
Mobile GPU ではあまり性能が出ないかもしれません。

その点 Tegra は Immediate Mode なので Desktop GPU と同じ考え方が通用します。
実際にテストしたわけではないので憶測ですが、上にも書いたとおり
およそ Tegra4 で現行 console の半分くらいではないかと思われます。

ただし Tegra シリーズの PixelShader は演算精度が mediump です。
精度が必要なシェーダーは動かない可能性がありますし、
HW Shadow Sampler の対応は必然だったのかもしれません。
また mediump を基準とするなら PowerVR もパフォーマンスが上がるので、
fp32 の GPU との単純な FLOPS 比較は無理があるように思います。


なお Qualcomm の Adreno は PixelShader の演算精度も GPU 機能も
コンソールと比べて遜色ありません。

・シェーダーや Extension 等、GPU 機能は現行コンソールと完全に同等
・描画速度では根拠となるデータが乏しい (が、おそらく負けてる)



●まとめ

結論としては、内部構造を熟知しているわけでも実測したわけでもないので根拠が
無いですが、GPU 性能やゲームで重要な単精度の浮動小数点演算性能でも
Xbox360/PS3 の方が上でしょう。
さらに高解像度であることやバス帯域の限界もあり、実アプリケーションでは
GPU 性能以上に隔たりが生じているのが現状ではないかと思います。
ただし性能の上昇は急激で、時間の問題であることは確かです。
特に RAM 容量では勝り、CPU の実行性能も差が無くなりつつあります。



関連ページ
SoC list
Mobile GPU/CPU 関連の情報まとめ

関連エントリ
PlayStation 4


昔 Direct3D 10 で作成した迷路シェーダーを Mobile GPU に移植してみました。
if 文の塊で非常に複雑な内容となっています。
そのため GPU によってはいくつか問題がありました。

迷路生成 (Nexus 10)
gpumaze 迷路生成

迷路探索 (Nexus 7)
gpudotmaze 迷路探索

このシェーダーでは各ピクセルが状態を持っており、自分の周囲のピクセルを
参照して次の状態を決定します。
例えば壁、床、成長点、移動判定中など、状態遷移の繰り返しで迷路の生成や
探索を行っています。
周囲のサンプリングは上下左右の 4点 + 自分自身を加えた 5回です。

プログラムでは毎フレーム迷路サイズの矩形を一回だけレンダリングしています。
例えば 512x512 なら、262144個のすべてのピクセルに対して上記の
サンプリングと遷移判定を行っていることになります。

そのため原理的にはテクスチャサイズ (迷路サイズ) だけで速度が決定し、
移動点や作業点が増えても (1つでも10万でも) 速度はほぼ変わらないことになります。
(2倍未満の若干の変化はあります。後述)

乱数は CPU で生成したものを毎フレーム GPU に渡しています。
バッファが小さいために固定パターンが目立ってしまうので、
これも GPU で生成できればもっと質の良い物が作れるかもしれません。

下記はさまざまな GPU で走らせた結果です。

              迷路生成 size                 迷路探索 size
              2048  1024   512   256   128  2048  1024   512   256   128
------------------------------------------------------------------------
1.Adreno 320  21.0  59.3  60.0  60.0  60.0  22.3  60.0  60.0  60.0  60.0
2.Mali-T604   11.1  41.3  60.0  60.0  60.0  19.0  58.5  60.0  60.0  60.0
3.Vivant GC4K  3.6  13.9  39.6  60.0  60.0   ---  13.4  41.3  60.0  60.0
4.Mali-400MP4  1.9   7.3  24.3  52.4  60.0   ---  13.8  38.1  60.0  60.0
5.Tegra 3      1.5   5.7  22.3  60.0  60.0   ---   6.0  20.3  43.8  60.0
6.PVR SGX540   0.5   5.2  21.0  60.0  60.0   ---   6.5  23.8  60.0  60.0
7.Adreno 220   ---   3.5  14.1  50.0  60.0   ---   ---  13.0  36.6  60.0※
8.Adreno 200   ---   ---   ---   ---  10.9   ---   ---   ---   ---   6.0※

・数値は FrameRate、値が大きい方が高速
・※ Adreno 220/200 は動作結果に問題あり

表示された fps 値を読み取っただけなので、あまり厳密な測定ではありません。
この中では Adreno 320 が圧倒的な速度となっています。

ほとんどの GPU では生成よりも探索の方が高速でした。
例外は Tegra3 で、探索の方が速度が落ちています。
Adreno 220/200 は一応速度を調べましたが正しく動いておりません。


● 条件分岐と条件付き代入

比較的すぐに動作する GPU と、対応のために修正が必要な GPU がありました。
一番問題だったのは Adreno 220 で、初期のコードではコンパイルが通るものの
Link Error が発生します。

// (A)
vec4 Head( vec4 color )
{
    if( isUp( color ) ){
       ~
       return  vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }
    if( isDown( color ) ){
       ~
       return  vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }
    if( isLeft( color ) ){
       ~
       return  vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }
    if( isRight( color ) ){
       ~
       return  vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }
    ~
    return  color;
}


// (B)
vec4 Head( vec4 color )
{
    if( isUp( color ) ){
       ~
       color= vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }else if( isDown( color ) ){
       ~
       color= vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }else if( isLeft( color ) ){
       ~
       color= vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }else if( isRight( color ) ){
       ~
       color= vec4( D_RESERVED, color.y, 0.0, 0.0 );
    }else{
    	~
    }
    return  color;
}

いろいろ試した結果、(A) のように条件分岐していた命令を、
(B) のように条件代入に置き換えることでエラーを回避出来ました。
コンパイル自体は通っていたので、命令スロットやレジスタなど、何らかの
GPU リソースが Link 時にあふれていた可能性があります。

Adreno 220 でもシェーダーは動作するようになりましたが、
生成結果が意図したものになっておらずまだ問題があります。

             迷路生成                 迷路探索
------------------------------------------------------
Mali-400MP4  壁が切れることがある     正しく動作する
Adreno 220   成長が途中で止まる       ドットが動かない
Adreno 200   正しく動作するが重い     ドットが動かない

Mali-400MP4 は一見正常に見えるものの、壁が途切れている部分があります。
Adreno 200 は Adreno 220 よりまともですが処理能力が足りていません。

また (A) を (B) のように書き換えることで、
他の GPU でもパフォーマンスに影響が生じました。

(C)表              迷路生成
                   2048x2048    1024x1024    512x512   256x256
--------------------------------------------------------------
1.(A) Adreno 320   25.7~16.3   60.0~58.8   60.0         60.0 
1.(B) Adreno 320   18.6~17.7   60.0         60.0         60.0
2.(A) Mali-T604    11.9~10.3   42.8~39.9   60.0         60.0 
2.(B) Mali-T604    12.2~10.5   43.4~42.8   60.0         60.0
3.(A) Vivant GC4K   3.6~       13.9~8.8    46.8~32.5   60.0 
3.(B) Vivant GC4K   3.6~       14.6~9.3    47.6~31.2   60.0
4.(A) Mali-400MP4   1.9~        7.3~       24.6~24.0   52.4 
4.(B) Mali-400MP4   1.9~        7.4~7.3    23.8~23.5   54.0
5.(A) Tegra 3       1.5          5.7         22.3         60.0 
5.(B) Tegra 3       1.8          7.0         27.3         60.0     
6.(A) PVR SGX540    0.5          4.5~5.9    18.4~23.6   60.0
6.(B) PVR SGX540    0.5          4.5~6.0    17.8~23.8   60.0

・数値は FrameRate、値が大きい方が高速

特に Adreno 320 は、(B) に書き換えることで著しく速度が落ちました。
逆に Tegra 3 は (B) の方が高速になっています。
他の GPU でもここまで顕著ではありませんが影響が出ているようです。

予想よりも GLSL は、比較的書いたとおりにそのままコンパイルされて
いるのではないかと考えられます。
その様子は動的分岐の結果からもわかります。


●動的分岐

(C)表の fps 値で「25.7~16.3」と範囲が書かれているものがあります。
これは迷路生成初期が 25.7fps で、全部埋まる頃に 16.3fps まで
落ちていることを意味しています。

考えられる要因としてシェーダーの動的分岐があります。
迷路生成初期はほとんど全部床面の状態なので、レンダリング時は
同一ブロック(WARP)内のピクセルが同じ方向に分岐していると考えられます。
この場合他の分岐状態を実行する必要がありません。

終盤になって複雑になると、ブロック内の各ピクセルの状態がばらばらになるので
シェーダーは可能性のあるすべての分岐コードを実行していると考えられます。

Adreno 320 / Vivante / Mali-T604 などの OpenGL ES 3.0 世代の GPU
fps 値が変化しているので、分岐の複雑さが速度に影響を与えていると考えられます。

特に Adreno 320 は変化が大きくなっています。
また (A) の分岐コードを (B) の条件代入に置き換えると、fps の変化が
大幅に少なくなることもわかります。
ここからも、記述通りに代入命令に置き換わっているのではないかと考えられます。

Adreno 320 の (B) のコードは最初は遅いものの、分岐判定のコストが
無いためか、複雑な終盤は落ち込みが少なく速度を維持しています。

Tegra 3 / Mali-400MP は速度が一定しておりほとんど変化がありませんでした。
おそらくすべての分岐を通過しているか、またはコンパイラが
分岐命令を置き換えているのではないかと思います。

Tegra 3 は (B) の方が速いので、命令置換ではなくそのまま分岐命令の分
コストが発生していると考えられます。

Adreno 220 はそもそも (B) でなければ動かないので変化が生じていません。
PowerVR SGX540 は理由はわかりませんが、条件が複雑になる終盤の方が
速度が上がっており特徴的な結果となっています。


●その他修正など

Tegra 3 は Fragment Shader で Uniform 配列に対する動的な index による
アクセスができません。
OpenGL ES 2.0 は Unified Shader が多いので忘れていましたが、
もともと Direct3D 9 ShaderModel 3.0 の仕様でも PixelShader では
index が使えませんでした。Tegra 3 の仕様で正解です。

PowerVR SGX540 では (B) の置き換えでシェーダーが動作しなくなる問題がありました。
lowp の誤差が原因で、PowerVR では mediump 以上を使用しています。

安定して動作したのは Adreno 320, Mali-T604, Vivante です。
いずれも OpenGL ES 3.0 対応 GPU です。


●アプリ

移植したシェーダーを Android の Live壁紙 にしてみました。

Google Play: GPU迷路 (作成のみ)
Google Play: GPUドット迷路 (作成+迷路探索)

上記の速度テストは、アプリのプレビュー(画面モード=ズーム)で測定しています。
GPU によっては負荷が高すぎるため 2048x2048 は除外しています。


●テスト機の詳細

   Device         OS   SoC                        GPU
-------------------------------------------------------------------
1. Nexus 7 2013   4.3  Snapdragon S4 Pro APQ8064  Adreno 320
2. Nexus 10       4.3  Exynos 5 Dual (5250)       Mali-T604
3. dtab 01        4.1  K3V2                       Immersion.16 (Vivante)
4. MOMO7 DE       4.1  RK3066                     Mali-400MP4
5. Nexus 7 2012   4.3  Tegra 3                    ULP GeForce(12)
6. Kindle Fire    4.2  OMAP4430                   PowerVR SGX540
7. EVO 3D ISW12HT 4.0  Snapdragon S3 MSM8660      Adreno 220
8. Desire X06HT   4.1  Snapdragon S1 QSD8250      Adreno 220


関連エントリ
GLSL について、互換性や問題点など
2007/09/19 Direct3D 10 ShaderModel4.0 迷路の自動探索Shader
2007/09/18 Direct3D ShaderModel4.0 Shaderで迷路作成


Nexus 10 のデータを追加しました。
Nexus 10 の Exynos 5 Dual は Krait + Adreno 320 の APQ8064 と同じように、
CPU (Cortex-A15)、GPU (ARM Mali-T604) ともに新しい世代の core が用いられています。

Mobile GPU の OpenGL ES Extension

下記 GPU 機能の比較表も更新しました。

Mobile GPU の機能比較表

Mali-T604 は OpenGL ES 3.0 世代の GPU ですが、今のところ使えるのは
Adreno 320 同様 OpenGL ES 2.0 API の範囲に限られます。

Adreno の場合 OpenGL ES 2.0 API でも ETC2/EAC Texture など、
部分的に OpenGL ES 3.0 の機能が取り込まれていました。
Mali-T604 では特に OpenGL ES 3.0 を先取りしているような部分はないようです。

新しい core なので動作速度も十分高速でシェーダーパフォーマンスも良好です。
前世代の Mali-400MP では TBR ながら discrete 構成で頂点性能に難がありました。
Mali-T604 は Unified Shader となったため総合的に性能が上がっています。
構造の違いは機能面からもわかります。

例えば Shader Constant (Uniform) 数、Vertex Texture mapping 、
Pixel Format/Vertex Format、Shader の演算精度など、
さまざまな面で Vertex と Pixel (Fragment) の機能差が無くなっています。

Uniform数      Vertex Fragment
----------------------------------------
Tegra2/3        256    1024     discrete
Mali-400MP      128    1024     discrete
Mali-T604       256     256     unified
Adreno          251     221     unified
PowerVR SGX 5   128      64     unified

Tegra2/3, Mali-400MP の Fragment Shader は Uniform 数に 1024 と極端に
大きな値を返しています。
おそらく古い GeForce と同じように、Pixel (Fragmen) の場合だけ
Shader Program のバイナリを直接書き換える仕組みで、
事実上制限が無いのだと思われます。

T604 は Vertex / Fragment との差がなく他の GPU に近い数値になりました。

これまで Unified Shader の GPU は大きく分けて、highp 固定精度と
highp/mediump/lowp 可変精度の 2種類ありました。

Unified Shader GPU     Precision
---------------------------------------------------------
Adreno 200/300         highp のみ          (highp 固定)
Vivante GC             highp のみ          (highp 固定)
PowerVR SGX 5          highp/mediump/lowp  (3種類の可変)
Mali-T604              highp/mediump       (lowp 無し)

Mali-T604 は PowerVR のように precision 宣言が有効ですが、
highp と mediump の 2種類しかありません。
mediump 固定で lowp が無かった Mali-400MP に似ています。

highp に対応しているにも関わらず GL_OES_fragment_precision_high が
無いので、Mali-400MP と同じように Fragment Shader (PixelShader) では
mediump を使って欲しいのかもしれません。

ただし下記の記事にも書いたように glGetShaderPrecisionFormat() の返す値は
実際の動作と異なっている場合があります。まだ実測していません。

OpenGL ES 2.0 GLSL precision 宣言と GPU 毎の演算精度を調べる
Mobile GPU の比較 Precision


●全然関係ないシェーダーのはまり

GPU 機能とは関係なく、Nexus 10 の解像度の高さに自分のシェーダーが対応できて
いませんでした。
もともと浮動小数点の演算を利用して複数のデータを圧縮して格納していたのですが、
2560x1600 のスクリーン座標がオーバーフローしていることが原因でした。
やはり演算精度は実機できちんと測定しておいた方がよさそうです。


関連エントリ
Qualcomm APQ8064 GPU Adreno 320 の速度
OpenGL ES 2.0 GLSL precision 宣言と GPU 毎の演算精度を調べる
GPU 速度に関連するエントリ


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  (2011/10/12修正)
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


(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  (2011/10/12修正)
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


(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  (2011/10/12修正)
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


(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  (2011/10/12修正)
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


OS = A:Android, i:iOS
framebuffer = color depth stencil

(※ 2011/10/12更新 表のデータを追加しました)

それぞれ機種ごとに解像度が違うので、フレームレート(fps)での比較が
できないことに注意してください。

頂点よりもピクセル負荷の方が高いため、秒間の描画ピクセル数に変換しました。
pix/sec の数値を比べてください。

あくまで自作プログラム+自前シーンでの比較なので参考程度にお願いします。


●補足事項など

ARMv7 Cortex-A9 dual core (or Scorpion dual core) 相当の CPU
搭載機のみピックアップしています。CPU の動作クロックはそれぞれ異なります。

Android は OS2.2 ターゲットで NDK + OpenGL ES 2.0 を使っています。
armeabi-v7a の NEON 無しです。

背景込ですべてピクセル単位のライティングを行なっています。
シェーダーに動的分岐はありません。

Tegra2 は depth_texture が使えないため shadow map で同一条件の
比較ができません。(1) では texture_half_float を使っており他の GPU より
負荷が高くなります。

Tegra2 は 16bit depth しか選択することができません。
逆に Mali-400MP 等は 24bit depth + 8bit stencil しか選択できません。

543MP2 はプラットフォーム(OS) が異なりますが、完全に同一コード+
同一シェーダーで走らせています。ただし完全に同一状態とは言い切れない
ので、実際の数値はもう少し変動するかもしれません。

テクスチャはできる限り GPU 専用の圧縮フォーマットに変換しています。
DXT(S3TC), PVR, ATC, ETC1 の 4フォーマット対応です。

(3) で Mali-400MP の pix/sec が算出不可能なのは 60fps の上限に張り付いて
しまっているからです。

ポリゴンの重なりが多少あるので画面サイズから求めた pix/sec は厳密な値では
ありません。が、TBDR の PowerVR のようにポリゴンの重なりで Shader が無駄に
走らないことを特徴としている GPU もあるためそのまま比べます。



●テスト結果について

描画面積で速度が決まっており、ボトルネックは完全にピクセル負荷
(Fragment Shader) となっています。
(1), (2) などシェーダーが複雑になるほどテクスチャサイズの影響が無くなる
ため、純粋に Fragment Shader が複雑すぎるようです。

PowerVR, Tegra2 など precision 宣言が有効な GPU ほど速度が出ていない
のでシェーダー最適化が不十分で能力を発揮できていない可能性があります。

PVR SGX 543MP は (1) を見ると低速に見えますが、Fragment Shader の
複雑さが下がるほど急激に速度が上がっています。
(3) では上位 GPU にほぼ匹敵していることがわかります。
(4) では逆転するかもしれません。
最適化が足りないか、または実行命令ステップ数の影響を受けやすい GPU のようです。

Mobile GPU ではこの面積で (1),(2) のような複雑なシェーダーを走らせる
ことが想定されていなかったのかもしれません。
それでも Mali, Adreno 220 は意外なほどよく動いています。

Tegra2 はあまり良い結果が出ていませんが、1年以上前から製品に載っている
プロセッサなので、GPU 自体は一世代前のグループに属するのだと考えられます。
年内に出る Tegra3 と比べるべきかもしれません。

ゲームで互換性を考えるとおそらく (3)~(4) の範囲で作ることになるかと思います。
しかしながら Mali-400MP や Adreno 220 など新しい世代の GPU
複雑なシェーダーでも非常によく動いています。
Mobile のゲームも、もう一段階上の表現が十分可能になってきているといえます。


これまでの結果から大体の GPU 速度のグループ分けは下記のとおりです。

Group 1 | Adreno 200
Group 2 | Adreno 205 / PowerVR SGX 535,540 / Tegra 250
Group 3 | Adreno 220 / PowerVR SGX 543MP2 / Mali-400MP


以下 2011/10/12 22:00 追記

iOS 時の計測方法に問題があったため表の数値を変更しました。
PowerVR SGX 543MP2 の数値が大きく増えています。
さらに PVR 向けに shader 最適化の余地があったため修正しました。

その結果、予想通りシェーダー負荷が軽くなるほど SGX543MP2 の数値は
高くなっており (3) で Adreno 220 を超えています。
Group 3 世代の性能を持っているといえます。

表 (2),(3),(4) のテスト結果も追加しました。



関連エントリ
Android HTC EVO 3D GPU Adreno 220 の速度
OpenGL ES 2.0 shader の演算精度
Android Galaxy S2 ARM Mali-400 MP は速い (2)


前回までのテストはピクセル性能に左右されていたため、ほぼ頂点だけの
描画を行ってみました。

GPU           Processor    Sh Unit   OS    display    fps   tri/sec
--------------------------------------------------------------------------
Mali-400MP    Exynos 4210  discrete  A2.3  480x800    9.21  10.3M (1031万)
Adreno 220    MSM8660      unified   A2.3  540x960   29.50  33.0M (3303万)
ULP GeForce   Tegra 250    discrete  A3.1  800x1232  20.85  23.3M (2334万)
PVR SGX543MP2 A5           unified   i5.0  768x1024  56.10  62.8M (6281万)

50880 ポリゴン(25919頂点) の球のモデルを 22個表示しています。
シーン内合計 1119360ポリゴン。

Fragment Shader はライティングなし、テクスチャなし、描画面積を減らすため
中央に小さく表示。
頂点フォーマットは float x 3 の座標値のみ。(stride = 12byte)
Vertex Shader は vec4 * mat4 だけの単純なものです。

球のモデルデータなので共有頂点が多く、Vertex Cache が有効な GPU にとっては
理想的なデータです。
頂点数は 25919 なので、もし仮に V-Cache が完全に hit したと考えると
1ポリゴンあたり 1頂点未満で描画できる計算になります。
実際にシミュレートしてみると 66% hit、つまり strip 変換相当でした。

ただしテストした GPU にどれだけ V-Cache が搭載されているか判明していません。
Strip 変換していないため、もし V-Cache 無しの GPU の場合は本来の能力を
発揮できていないことになります。
この場合はおそらくピーク性能の 1/3 程度の結果になっていると考えられます。

また GPU の Shader Unit の構造に注意してください。
GPU が Unified Shader の場合はおそらく突出した数値が出ていますが現実的
ではありません。
本来 Fragment Shader として機能する分の演算能力の多くが頂点に割り振られて
いると考えられるからです。
一般的な描画のシーンではピクセルの面積分だけ頂点性能が削られます。


● Mali-400MP

描画面積の多いシーンでは最強だった Mali-400MP の意外な弱点が判明しました。
Mali-400MP の構成を見ると、
Vertex Processor x 1 + Fragment Processor x 1~4
という構造になっているようです。MP4 なら Fragment Processor x4 です。
頂点 Unit 自体の個数は変化しません。

頂点性能をそこまで求めない代わりにピクセル性能が高く、比較的長い
Fragment Shader を走らせても動作効率が落ちませんでした。
このことから、ピクセル性能重視型 GPU として設計してあるようです。

おそらく Fragment Shader で様々なテクニックを駆使して絵作りを行うべき
GPU だと言えるでしょう。(ただし mediump のみ)

スマートフォンやタブレットなど、GPU 性能の向上よりも速いペースで解像度が
増加したため、用途として非常にバランスが良かったのだと思われます。

こちらによればピーク値 30M tri/s だそうです。


● Tegra 250

Mali とは逆に予想以上の数値を出したのが Tegra2 です。
Mali 同様 discrete タイプで「後藤弘茂のWeekly海外ニュース」によると
Shader の core は Vertex 4unit、Pixel 4unit とのこと。

おそらく Fragment Shader のシェーディングで工夫するよりもハイポリゴンに
した方が綺麗な絵が出せる GPU だといえます。

次の Kal-El (Tegra3) は Vertex unit そのままで Pixel Unit が 2倍になる
らしいので、弱点を補う意味でも理にかなった拡張です。


● Adreno 220

Unified Shader なのでこの値は控えめに見積もってください。
他の GPU が比較的一点集中型で、得意な項目と苦手な点がはっきりしている
のに対して、どのテストでもそつなく高い数値を出す傾向があります。

ピークが突出していない代わりに速度が落ちにくいバランスとなっているようです。
唯一 Vertex Texture が使えたり、Pixel 演算も highp で高精度だったりと
機能面でも手を抜いておらず、たいへん扱いやすい GPU です。


● PVR SGX543MP2

ピクセル負荷が減ると極端に速度が向上する特性を示していましたが、
頂点数が増えてもその傾向は変わらないようです。
Unified Shader なので通常利用時の性能ではありませんが、潜在能力が
高いのは間違いありません。

ピーキーな特性で、特に Fragment Shader の最適化は僅かな修正でも大きな
違いとなって現れます。
頂点とピクセルのバランス取りなど、使いこなしはまさに利用者の腕次第と言った
感じです。


今回のテスト結果を下記のページに追加しました。

Mobile GPU 速度比較のまとめ


関連エントリ
A5 PowerVR SGX543MP2 は iOS 5 だと速い
さらに OpenGL ES 2.0 Mobile GPU速度比較
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)


Transformer Prime, EeePad TF201 手に入れました。
NVIDIA の新しい Mobile プロセッサ Tegra 3 を搭載しています。
CPU は Cortex-A9 の quad core で GPU は ULP GeForce 12 core 版
となります。

CPU は 4 core 認識しています。Tegra2 と違い NEON あります。

Processor	: ARMv7 Processor rev 9 (v7l)
processor	: 0
BogoMIPS	: 1992.29

processor	: 1
BogoMIPS	: 1992.29

processor	: 2
BogoMIPS	: 1992.29

processor	: 3
BogoMIPS	: 1992.29

Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 9

GPU の方は Tegra2 と比べて特に機能的な違いがありませんでした。
depth は 16bit のままで depth_texture もありません。

Mobile GPU の機能比較

GL_VERSION: OpenGL ES 2.0 12.01014
GL_RENDERER: NVIDIA Tegra 3
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL 1.00

Extension は下記のページに追加しました。

OpenGL ES Extension


GPU 速度

いつもの pixel 負荷の高い描画テストを走らせてみました。
Tegra2 と比べて 3倍弱といった数値になっています。

(2) light 3 (ambient + directional x2 + point )
-----------------------------------------------------
Tegra 3 / ULP GeForce(12)  15.70fps   EeePad TF201
Tegra 2 / ULP GeForce(8)    5.74fps   ICONIA TAB A500


(3) light 1 (ambient + directional )
-----------------------------------------------------
Tegra 3 / ULP GeForce(12)  30.10fps   EeePad TF201
Tegra 2 / ULP GeForce(8)   12.10fps   ICONIA TAB A500

shader core は Pixel が 2倍らしいので、Mali400 と同じ表現を
使えば MP2 相当です。2倍以上の性能差は動作クロックの違いだと
考えられます。

他の GPU との比較は下記のページにまとめました。

Mobile GPU bench mark

pix/sec の欄を見ると、速度的にはほぼ 3世代目グループである
Mali-400MP4/Adreno220/SGX543MP2 に並んでいることがわかります。

NVIDIA といえば GPU のイメージが強いですが Tegra はむしろ逆です。
優先しているのは CPU の方で、半世代先行した設計で Quad 化を
実現しています。
それに対して GPU は決して突出した性能ではなく、やっとライバルに
並んだところです。

Group3 | Adreno 220, PVR SGX543MP2, Mali-400MP4, ULP GeForce(12,Tegra3)
Group2 | Adreno 205, PVR SGX530/535/540, ULP GeForce(8,Tegra250)
Group1 | Adreno 200, AMD Z430


関連エントリ
OpenGL ES 2.0 Mobile GPU の比較、重いテクスチャ
頂点性能の比較 その2 (OpenGL ES 2.0 Mobile GPU)
OpenGL ES 2.0 Mobile GPU の頂点性能を比較する
A5 PowerVR SGX543MP2 は iOS 5 だと速い
さらに OpenGL ES 2.0 Mobile GPU速度比較
OpenGL ES 2.0 Mobile GPU速度比較 (dual core世代) 更新


Apple の製品紹介には、前モデルからどれだけパフォーマンスが向上したか比較値が載っています。この数値をまとめてみました。

iPad mini/iPad 2 はどちらも Apple A5 (Cortex-A9 1.0GHz dual/PowerVR SGX543MP2) が用いられており同一です。これを 1.0 とした時の速度の比較は下記のとおり。数値が大きい方が高速です。

iPad mini SoC CPU 速度 GPU 速度
iPad mini A5 1.0 1.0
iPad mini 2 A7 4.0 8.0
iPad mini 3 A7 4.0 8.0
iPad mini 4 A8 5.2 12.8
iPad SoC CPU 速度 GPU 速度
iPad A4 0.5 0.1
iPad 2 A5 1.0 1.0
iPad 3 A5X 1.0 2.0
iPad 4 A6X 2.0 4.0
iPad Air A7 4.0 8.0
iPad Air 2 A8X 5.6 20.0
iPad Pro A9X 10.1 40.0

誤差が含まれていると思われるため目安程度にお願いします。
iPad mini2/3, iPad Air はどちらも A7 を搭載しており、きちんと同じ数値になっています。実際は mini と Air は CPU Clock で僅かに (7%ほど) 違いがあります。

GPU速度向上が著しいことがよくわかります。
iPad Pro に至っては CPU 10倍、GPU 40倍という結果に。Metal でも新たに iOS GPUFamily3 が追加されているので、A9/A9X (または A9X のみ) には新しい GPU が搭載されている可能性があります。

元にした数値は下記の通り。

iPad mini 2 A7 iPad mini (A5) の CPU 4倍 / GPU 8倍
iPad mini 3 A7 iPad mini2 (A7) と同一
iPad mini 4 A8 iPad mini3 (A7) の CPU 1.3倍 / GPU 1.6倍
iPad mini 4 A8 iPad mini (A5) の CPU 5.2倍 / GPU 12.8倍
iPad 3 A5X iPad 2 (A5) の CPU 1.0倍 / GPU 2.0倍
iPad 4 A6X iPad 3 (A5X) の CPU 2.0倍 / GPU 2.0倍
iPad Air A7 iPad 4 (A6X) の CPU 2.0倍 / GPU 2.0倍
iPad Air 2 A8X iPad Air (A7) の CPU 1.4倍 / GPU 2.5倍
iPad Pro A9X iPad Air2 (A8X) の CPU 1.8倍 / GPU 2.0倍
iPad Pro A9X iPad (A4) の CPU 22倍 / GPU 360倍

これらのデータは下記公式ページより。

Apple: iPad Pro
Apple: iPad Pro Technology
Apple: iPad mini 4
Apple: iPad mini 4 パフォーマンス
Apple、iPad Air 2を発表—これまでで最も薄く、最もパワフルなiPad
Apple、iPad Airを発表 劇的に薄く、軽く、よりパワフルなiPad
Apple、iPad miniを発表
Apple、新しいiPadを発表


ベンチマークソフトを手持ちのデバイスで試してみました。

Sillicon Studio MOBILE GPUMARK

MOBILE GPUMARK                             GEMS   DP   NB   GPU Total
---------------------------------------------------------------------
iPhone5             A6  PowerVR SGX543MP3   751  902  474  4068  6195
iPad4               A6X PowerVR SGX554MP4   665  729  429  3943  5757
iPad mini           A5  PowerVR SGX543MP2   582  695  362  2852  4491
Nexus 7             Tegra3 ULP GeForce(12)  362  623  231  3271  4487
EVO 3D ISW12HT      MSM8660 Adreno220       431  564  245  2235  3475
iPod touch5         A5  PowerVR SGX543MP2   385  450  239  2338  3412
Galaxy S2 SC-02C    Exynos4210 Mali-400MP4  577  730  174  1196  2677
Optimus Pad L-06C   Tegra2 ULP GeForce(8)   121  220   81  1838  2260
Galaxy Nexus SC-04D OMAP4460 PowerVR SGX540 160  161   63  1273  1657
HONEYBEE 101K       APE5R PowerVR SGX543MP  407  572  240 10673 11892 ※無効

・数値が大きいほうが高速。スコアは v1.0 時のもの
・GEMS=RIGID GEMS, DP=DEAD PARKING, NB= NATURAL BONE, GPU=GPU BENCHMARK
・CPU はすべて dual core 以上

iPad4 より iPhone5 の方が良い結果でした。
画面の解像度が小さい方が多少有利に働くのかもしれません。

SC-04D は非常に低速で、ひと通り完了を待つだけでもかなり時間がかかりました。
見かけの速度は速いですが、SGX540 はやはりひと世代前の GPU であることがわかります。
Galaxy S2 はそこそこのスコアですがディザがかかったような画面に見えるのが気になりました。

HONEYBEE 101K が突出した値に見えますが実は描画が正しく行われておりません。
もともとこの端末は OpenGL ES 2.0 で問題が生じることが多かったのですが、
GEMS,DP,NB の描画はラスタ状に一瞬見える程度でほとんど暗転しており、まるで
V-Sync を待たずにフレームバッファがクリアされているような画面になっています。
よってこのスコアは無効です。

GPU BENCHMARK の内容をさらに詳しく比較したのが下記の表です。

GPU BENCHMARK                 fill high many vert spec  pix norm  420  800 1280
-------------------------------------------------------------------------------
iPhone5      PVR SGX543MP3     538   82  242 1013  871  343  310  364  203  102
iPad4        PVR SGX554MP4     403  137  296  765  726  412  393  234  269  172
iPad mini    PVR SGX543MP2     484   62  158  640  560  241  222  274  144   67
Nexus 7      Tegra3 ULP GF(12) 185   56  116  828  571  288  235  667  218  107
EVO 3D       8660 Adreno220    283   98  123  384  378  320  279  191  132   47
iPod touch5  PVR SGX543MP2     286   39  130  601  513  183  164  243  123   56
Galaxy S2    4210 Mali-400MP4  253   37   26  193  138  159  145  196   29   20
Optimus Pad  Tegra2 ULP GF(8)   75   22   77  572  409  125  102  317   98   41
Galaxy Nexus 4460 PVR SGX540    87   31   48  302  265  190  131  134   62   26
HONEYBEE101K PVR SGX543MP     7768   72   91 1038  595  385  416  161  102   45

・数値が大きいほうが高速。スコアは v1.0 時のもの
・fill=Fill Test, high=High Polygon Model, many=Many Models
・vert=Per Vertex Lighting, spec=Per Vertex Lighting & Specular
・pix=Per Pixel Lighting & Specular, norm=Per Pixel Lighting & Specular & Normal Map
・420=YEBIS Resolution 420x234, 800=YEBIS Resolution 800x450, 1280=YEBIS Resolution 1280x720

PowerVR 系は頂点(vert,spec)とピクセル(pix,norm)のスコアに極端な差が
ついていることがわかります。
Unified Shader である PowerVR 系はピクセル負荷が下がった分だけ頂点性能が
大きく向上します。

同じ Unified ながら全く性質が異なるのが Adreno 220 系で、
頂点(vert,spec)とピクセル(pix,norm)の差がわずかです。
全体の負荷を下げてもピーク性能が上がらない代わりに、ある程度複雑な
ピクセルシェーダーを走らせても性能が落ちにくい傾向があります。

Discrete Shader である Tegra は頂点性能が非常に高いことがわかります。
ピクセル負荷に影響を受けず、Tegra2 でもアンバランスに見えるほど
頂点スコアが高くなっています。
Tegra3 はピクセルも強化されていますが、PowerVR とは異なり
シェーダーの演算能力よりも fill が弱点になっているようです。

Tegra と正反対なのが同じ Discrete の Mali-400MP4 です。
4 core あるのはピクセルユニットだけなので、どうしても相対的に頂点性能が
足りないようです。
spec, pix を比べるとわかりますが、頂点でライティングするよりもむしろ
ピクセルでライティングした方が速くなっています。
GEMS, DP だけを見ると上位に食い込むスコアなので、NB を含めて
ハイポリ系が大きくスコアを落とす原因となっているようです。

HONEYBEE 101K では 420,800,1280 (YEBIS) の描画が完全に壊れていました。
よってこのスコアは正しくないことに注意してください。
それ以外は一見正しく描画されていましたが fill の値だけなぜか突出しています。
この機種だけ Android 2.3 であることも何か関係しているかもしれません。


実際のラインキングを見ると Snapdragon S4 (Adreno225/320) がかなり
上位を占めているようです。

MOBILE GPUMARK - RANKING

ポストエフェクトなどスクリーン系エフェクトは TBDR の PowerVR 等とは
相性がよくなく、Mobile 系 GPU ではあまり用いられていませんでした。
このソフトでは非常によく動いており各種効果による違いもよくわかります。

PowerVR はかなり特徴が偏っているため、PC と同じアプローチだと他の GPU
あまり差がつかないかもしれません。その点 Tegra の方が素直です。
また highp 演算が多い場合やピクセルの演算命令が複雑な場合は Adreno が有利です。

今後は様々な GPU が登場し、レンダリング手法も幅が広がってくるものと思われます。
Adreno 320 では TBR だけでなく Direct Rendering Mode も使い分けられるので、
このようなケースでも今まで以上に最適化が可能となるようです。

新しい世代の Adreno 320/Mali-T604 をまだ入手できていないので、
機会があればぜひ比べてみたいと思います。


関連エントリ
iPad 4 Apple A6X GPU PowerVR SGX554 MP4 の速度


最適な頂点形式を割り出すため strip 変換時のパフォーマンスも調べて
みました。

          Mali-   Adreno  Adreno  AMD     ULP      PVR SGX  PVR
          400MP   220     200     Z430    GeForce  543MP2   SGX535
-------------------------------------------------------------------
List       9.07   29.49*   1.71    2.34   20.96    57.08*   14.51*
NStripC   16.42   25.81    3.09    4.30   24.28*   50.96    12.18
NStripL   18.11*  24.38    4.05    5.52   21.02    56.08    14.20
QStrip    17.20   18.41    4.14*   5.79*  21.18    56.06    14.20

単位は fps (大きい方が速い)

テスト条件は前回と同じです。
50880ポリゴンの球モデルを 22個、画面あたり 1119628ポリゴンの描画を
行なっています。

GPU 毎に最も高速だった項目に '*' マークをつけています。

各項目の詳細は下記のとおりです。

format   indices   DrawElements
----------------------------------------------------------------------
List      152640   GL_TRIANGLES        無変換 (v-cache hit率 66% 前後)
NStripC    74766   GL_TRIANGLE_STRIP   NVIDIA NvStrip。Cache 優先
NStripL    52873   GL_TRIANGLE_STRIP   NVIDIA NvStrip。長さ優先に修正
QStrip     51518   GL_TRIANGLE_STRIP   Qualcomm Qstrip 使用。

List よりも Strip の方が速いのは
Mali-400MP, ULP GeForce(Tegra2), Adreno 200 の 3種類です。
(AMD Z430 は Adreno 200 とほぼ同一のものです)

逆に Strip 化で速度が落ちたのは Adreno 220, PowerVR です。
この両者は適量の Vertex Cache が搭載されていると考えて間違い無いでしょう。

Strip の方が速い GPU でも、興味深いことに最適なフォーマットがどれも
ばらばらでした。

Mali-400MP = NStripL
ULP GeForce = NStripC
Adreno200/Z430 = QStrip

以下細かく見ていきます。


● Mali-400MP

頂点性能がぱっとしませんでしたが Strip 化で大きくスコアが伸びました。
実測で 20.3M tri/sec まで出せることが確認できました。
List 比 2倍程度なので V-Cache が全く無いわけではなさそうです。

NStripL は cache を無視して出来るだけ長くつながるよう NvStrip を設定
したものです。
同様に長さ優先と思われる QStrip ではなぜか速度が落ちました。


● ULP GeForce(8) (Tegra2)

さすが NVIDIA 製ツールと相性が良いです。
NvStrip の通常設定で一番スコアが伸びました。

Strip の方が高速ですが速度向上率が 16% と小さいため、V-Cache を搭載
しつつ、さらに Strip も速いハードだと考えられます。

たとえぶつ切りでも Cache 効率を優先して並べ変えた NStripC が速く、
無駄な index が無い NStripL/QStrip はかえって速度が落ちることに
なっています。


● Adreno 200/Adreno 205/AMD Z430

Strip 化でおよそ 2.4倍と大幅に伸びています。
このことから基本的に V-Cache が無く、Strip 化することで約 3倍まで
近づくハードウエアであると考えられます。

当然のように Qualcomm 製ツールで変換した場合が最も良い結果となっています。

ただし同じ Qualcomm でも、新型の Adreno 220 では逆に速度が落ちて
しまうので要注意です。


● PowerVR SGX535/SGX543MP2

List の方が高速です。
ただし今回のデータは List でも 66% と Cache hit 率が strip 相当なので
思ったより差が出ていません。

Cache 最適化された NStripC よりも、無駄な index が無い NStripL/QStrip
の方が速度が出ています。縮退 Triangle の効率が悪いのか、Index 転送量の
問題なのかわかりません。

SGX535 は iPod touch3/4 共に同じ数値でした。
画面解像度が影響せず、実行時間をほとんど頂点が占めていることがわかります。


● Adreno 220

List の方が高速です。
V-Cache 搭載 GPU として最も予想通りの結果で、どうすれば速いのか、
何をすれば遅くなるのか感覚的にも受け入れやすいものとなっています。

またこの結果から、Adreno 200/205 と Adreno 220 との間には
アーキテクチャ的な大きな変更があったことがわかります。

Adreno 200 向け最適化 (Qstrip) を行うと cache 効率が下がって却って
速度が落ちます。


●結論

全てに都合の良い頂点形式はありませんでした。
ぎりぎりの頂点性能を求めるなら各 GPU 毎に変換する必要があります。

最低限の頂点性能で幅広いハードで動作することを優先するなら、
遅い GPU の底上げ(Qstrip)でしょうか。

Adreno のように今後は速いペースで GPU の機能が desktop GPU に追いついて
いく事が考えられます。将来を視野に入れたデータ構造にするなら
Cache 優先の List になるでしょう。

ただ現状は頂点よりも圧倒的に pixel の方が速度を圧迫しているため、
このような頂点構造の違いは大した問題ではないかもしれません。

Mobile GPU 速度比較のまとめ

テスト機材一覧
 Mali-400MP         Exynos 4210   Samsung Galaxy S2 SC-02C
 Adreno 220         MSM8660       HTC EVO 3D ISW12HT
 Adreno 200         QSD8250       HTC Desire X06HT
 AMD Z430           i.MX51        Creative ZenTouch2
 ULP GeForce        Tegra 250     Acer ICONIA TAB A500
 PowerVR SGX543MP2  A5            Apple iPad2
 PowerVR SGX535     A4/S5PC100    Apple iPod touch4/iPod touch3


関連エントリ
OpenGL ES 2.0 Mobile GPU の頂点性能を比較する
A5 PowerVR SGX543MP2 は iOS 5 だと速い
さらに OpenGL ES 2.0 Mobile GPU速度比較
OpenGL ES 2.0 Mobile GPU速度比較 (dual core世代) 更新
Android HTC EVO 3D GPU Adreno 220 の速度


ベンチマークの結果を更新しました。

Mobile GPU bench mark

Android 4.1 以降かつ対応しているデバイスでは SwapInterval を 0 に
変更したので 60fps 以上出ています。(関連)

GPU            SoC   CPU clock OS    Screen     fps       pix/sec
---------------------------------------------------------------------
Adreno 330     MSM8974 2.2GHz  A4.2  1920x1200  71.98fps   165.8M
Adreno 320(64) APQ8064 1.5GHz  A4.4  1920x1104  40.97fps    86.8M
Mali-T604     Exynos5D 1.7GHz  A4.4  2560x1504  20.73fps    79.8M
ULP GeForce(72) Tegra4 1.8GHz  A4.3   1126x800  44.58fps    43.4M
ULP GeForce(12) Tegra3 1.2GHz  A4.4   1280x752  15.70fps    15.0M (*1)

*1: Shadow Map 無し, 16bit depth

Adreno 330 は予想以上に速く、Adreno 320 比でもおよそ 2倍の速度が出ています。
ついに一番負荷が高い設定でも Full HD (1920x1200) で 60fps を超えるように
なってしまいました。
2010 年の GPU では 800x480 でもわずか 3fps でした。

対する Tegra 4 はあまり速度が伸びていません。
負荷を下げても速度が上がらないので、SwapInterval 設定が効いていないか
何かしら問題が発生している可能性があります。

その代わり Tegra 3 で省かれていたさまざまな extension をサポートしており
描画結果が他の GPU とほぼ一致するようになりました。

特に GL_EXT_shadow_samplers は単なる Hardware ShadowMap ではなく
PCF にきちんと Bi-linear Filter もかかります。
GL_EXT_shadow_samplers は OpenGL ES 3.0 以降のデバイスはどれも対応
していますが、必ずしも Filter がかかるとは限らないようです。
下記はいくつかテストした結果です。

                               depth-tex sh-samplers PCF Filter
----------------------------------------------------------------
8064 Adreno 320 OpenGL ES 3.0      ◎        ◎      ◎   --
8064 Adreno 320 OpenGL ES 2.0      ◎        --      --   --
Mali-T604       OpenGL ES 3.0      ◎        ◎      ◎   ◎
Tegra 4         OpenGL ES 2.0      ◎        ◎      ◎   ◎
Tegra 3         OpenGL ES 2.0      --        --      --   --
iOS PVR 543MP3  OpenGL ES 2.0      ◎        ◎      ◎   ◎
Vivante GC4000  OpenGL ES 2.0      ◎        --      --   --
Mali-400MP4     OpenGL ES 2.0      ◎        --      --   --
PowerVR SGX540  OpenGL ES 2.0      ◎        --      --   --

この辺りはもう少し詳しく調べたいと思っています。
なお Tegra4 の Extension 詳細は下記のページに追加しました。

CPU/GPU OpenGL ES Extension (Mobile GPU)


関連エントリ
Android OpenGL ES と V-Sync (eglSwapInterval)
Nexus 10 GPU Mali-T604
Qualcomm APQ8064 GPU Adreno 320 の速度
さらに OpenGL ES 2.0 Mobile GPU速度比較
GPU 速度に関連するエントリ


Mac の Metal API 対応機種が明らかになっています。mid 2012 以降、Mac Pro のみ 2013以降となります。これらの機種を GPU に照らし合わせると下記の通り。

・Intel HD Graphics 4000 Gen7 以降 (Ivy Bridge)
・GeForce Kepler 以降
・RADEON GCN 以降

Metal はもともと Mobile OpenGL ES 3.1 世代向けの API なので、機能面の要求はそれほど厳しくなく Direct3D 12 よりも多くの GPU に対応しています。ですが予想よりも対応 GPU には差が少ないことがわかりました。

比較すると下記の通りです。いずれも Direct3D 11 世代以降の GPU となります。

GPU D3D12 Metal OSX
GeForce Fermi N(Y) N GTX 400
GeForce Kepler Y Y GTX 680
GeForce Maxwell GM1 Y Y GTX 750
GeForce Maxwell GM2 Y Y GTX 980
RADEON GCN 1.0 Y Y HD 7000
RADEON GCN 1.1 Y Y R9 200/300
RADEON GCN 1.2 Y Y 285/380/Fury
Intel HD Graphics Gen7 N Y Ivy Bridge
Intel HD Graphics Gen7.5 Y Y Haswell
Intel HD Graphics Gen8 Y Y Broadwell
Intel HD Graphics Gen9 Y Y Skylake

一番の違いは Metal が Intel HD Graphics 4000 Ivy Bridge に対応していることです。
この世代の GPU は BayTrail として Windows Tablet の多くに採用されていますが D3D12 を使うことができなくなっています。

iOS の Metal 対応機種は下記の通り

Device SoC 64 GPU Metal GPU Family
iPhone 4S A5 N SGX 543MP2 N
iPad 2 A5 N SGX 543MP2 N
iPad mini A5 N SGX 543MP2 N
iPod touch 5 A5 N SGX 543MP2 N
iPad 3 A5X N SGX 543MP4 N
iPhone 5 A6 N SGX 543MP3 N
iPhone 5c A6 N SGX 543MP3 N
iPad 4 A6X N SGX 554MP4 N
iPhone 5s A7 Y G6430 Y Family1
iPad Air A7 Y G6430 Y Family1
iPad mini 2 A7 Y G6430 Y Family1
iPad mini 3 A7 Y G6430 Y Family1
iPhone 6/Plus A8 Y GX6450 Y Family2
iPod touch 6 A8 Y GX6450 Y Family2
iPad mini 4 A8 Y GX6450 Y Family2
Apple TV A8 Y GX6450? Y Family2
iPad Air 2 A8X Y GX6850 Y Family2
iPhone 6s/Plus A9 Y ? Y Family3
iPad Pro A9X Y ? Y Family3

下記ページも更新しました

GPU 世代対応表 (API 対応表)
Metal (iOS/OS X)

Mac 対応機種は下記より。

Apple Mac Developer Library : Metal Feature Set Tables


関連エントリ
歴代 iPad の CPU/GPU 速度の比較と iPad Pro の速度の目安
3D 低レベル API の違い Direct3D 12/Metal
3D 低レベル API の現状 Direct3D 12/Metal


HONEY BEE 101K は Renesas SH-Mobile APE5R を搭載した
Android スマートフォンです。
CPU Core は ARM Cortex-A9 1.2GHz の dual、
GPU core は PowerVR SGX543MP2 と意外なほどパワフルです。

KYOCERA HONEY BEE 101K

GPU である PowerVR SGX543MP2 は iPhone 4S/iPad2 に使われており、
4core 版 SGX543MP4 は iPad 3 や PS Vita で有名です。

ところが Android ではほとんど見かけることがありませんでした。
触る機会があったので試してみました。

CPU info/GPU Caps/Extension 等

Android なので PVRTC だけでなく ETC1 もサポートされています。
テクスチャサイズが 4096 になっただけで、Extension 等それ以外の
機能は PowerVR SGX540 とほとんど同じです。
GL_EXT_shadow_samplers も無く iOS 5 になる前の iPad2 に
似ているかもしれません。

GPU ベンチマーク

速度はそこそこですが走らせるにあたりいくつか問題がありました。

(1) GL_OUT_OF_MEMORY が出やすい

glDrawElements() で GL_OUT_OF_MEMORY が発生することがあります。
CPU info/GPU Caps/Extension 等」のページに meminfo の値も追加してみました。
比べてみると GPU に割り当てられていると思われる領域が
101K の場合少ないようです。
ただしこれが本当に GPU memory に影響しているのか、
また GL_OUT_OF_MEMORY の原因なのかどうかはわかりません。

                        OS    RAM     MemTotal  (RAM-MemTotal)
--------------------------------------------------------------
ZEN Touch2              2.1   256MB   185.2MB     70.8MB
ZiiO 7                  2.1   512MB   408.3MB    103.7MB
LuvPad AD100            2.2   512MB   438.3MB     73.7MB
Desire X06HT            2.2   576MB   415.2MB    160.1MB
Galaxy S SC-02B         2.2   512MB   302.1MB    209.9MB
Xperial arc SO-01C      2.3   512MB   335.4MB    176.6MB
Xperial ray SO-03C      2.3   512MB   335.4MB    176.6MB
HONEY BEE 101K          2.3   512MB   478.1MB     33.9MB
Novo7 Paladin           4.0   512MB   334.9MB    177.0MB
SXZ-PD10                4.0   512MB   368.3MB    143.7MB
EVO 3D ISW12HT          2.3  1024MB   808.1MB    215.9MB
Galaxy S2 SC-02C        2.3  1024MB   836.9MB    187.1MB
Galaxy Nexus SC-04D     4.0  1024MB   631.2MB    392.8MB
Optimus Pad L-06C       3.1  1024MB   662.3MB    361.7MB
Galaxy Tab 10.1 SC-01D  3.2  1024MB   756.7MB    267.3MB
EeePad TF201            4.0  1024MB   983.2MB     40.8MB (*1)

*1: DirectMap4k/DirectMap2M

例えば Tegra3 である TF201 も少なくなっています。
その代わり他のデバイスには存在しない DirectMap4k/DirectMap2M という
エントリが存在しており、おそらく他のデバイスとは異なる方法で
GPU メモリを管理していると考えられます。


(2) 3D 描画しているのに CPU clock が低下する

画面を操作している間だけ描画フレームレートが上昇することに
気が付きました。
CPU clock をモニタリングしてみると、ベンチマークの 3D 描画中も
300MHz 程度まで clock が下がっているようです。
画面を連打していると 1.2GHz 近くまで上がるため、ユーザー操作が
ない場合は描画負荷が高くても cpu を寝かせる仕様なのかもしれません。


ハイエンド機ではないので当然かもしれませんが、RAM も少な目で
GPU をあまり活かしきれていないのが少々残念でした。


REGRA Tablet AT703 より、Tegra4 の GL Extension です。

Extension:
GL_OES_rgb8_rgba8
GL_OES_EGL_sync
GL_OES_surfaceless_context
GL_OES_fbo_render_mipmap
GL_NV_depth_nonliner
GL_NV_draw_path
GL_NV_draw_texture
GL_NV_texture_npot_2D_mipmap
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_vertex_half_float
GL_OES_mapbuffer
GL_NV_draw_buffers
GL_NV_multiview_draw_buffers
GL_EXT_color_buffer_half_float
GL_EXT_packed_float
GL_EXT_texture_rg
GL_OES_texture_half_float
GL_NV_texture_array
GL_OES_compressed_ETC1_RGB8_texture
GL_EXT_texture_compression_latc
GL_NV_texture_compression_latc
GL_EXT_texture_compression_dxt1
GL_EXT_texture_compression_s3tc
GL_NV_texture_compression_s3tc
GL_EXT_texture_filter_anisotropic
GL_NV_get_tex_image
GL_NV_read_buffer
GL_NV_shader_framebuffer_fetch
GL_NV_copy_image
GL_NV_fbo_color_attachments
GL_EXT_bgra
GL_EXT_texture_format_BGRA8888
GL_EXT_read_format_bgra
GL_EXT_unpack_subimage
GL_NV_pack_subimage
GL_NV_texture_compression_s3tc_update
GL_NV_read_depth
GL_NV_read_stencil
GL_NV_uniform_buffer_object
GL_NV_map_buffer_range
GL_EXT_robustness
GL_OES_standard_derivatives
GL_NV_EGL_stream_consumer_external
GL_EXT_separate_shader_objects
GL_NV_copy_buffer
GL_NV_3dvision_settings
GL_EXT_debug_marker
GL_EXT_debug_label
GL_KHR_debug
GL_EXT_texture_storage
GL_NV_pixel_buffer_object
GL_NV_framebuffer_blit
GL_NV_non_square_matrices
GL_NV_explicit_attrib_location
GL_OES_vertex_array_object
GL_NV_smooth_points_lines
GL_OES_texture_half_float_linear
GL_NV_texture_border_clamp
GL_OES_depth_texture
GL_OES_depth_texture_cube_map
GL_NV_shadow_samplers_cube
GL_NV_shadow_samplers_array
GL_EXT_shadow_samplers
GL_OES_depth24
GL_EXT_sRGB
GL_NV_sRGB_formats
GL_NV_generate_mipmap_sRGB
GL_EXT_occlusion_query_boolean
GL_NV_occlusion_query_samples
GL_NV_timer_query
GL_NV_framebuffer_multisamples
GL_EXT_frag_depth
GL_NV_instanced_arrays
GL_NV_draw_instanced
GL_NV_secure_context

以前の Tegra2/3 と比べて Extension の数が大幅に増えています。
Tegra3 (Nexus 7) 比で 1.7倍、初期の Tegra2 の 2倍くらいあります。

Tegra2/3 (ULP GeForce) の単なる強化版ではなく、GPU 機能そのものが
大きく変わっていることがわかります。

また NV 拡張機能の割合が非常に多くなっています。
51% も占めており、ハードウエアを使いこなすために NVIDIA がかなり力を
入れている様子が伺えます。

ただ開発サイドとしては、独自拡張よりも他社 GPU との互換性が高まった
ことの方が嬉しいというのが本音です。
例えばこれとか。

GL_OES_depth24
GL_OES_depth_texture

今まで見てきた OpenGL ES 2.0 GPU で 24bit depth が使えなかったのは
Tegra2/3 だけでした。
Tegra4 以降は広い空間のレンダリングも 24bit 前提で作ることができます。
depth_texture も同じで、ShadpwMap を使う場合 Tegra2/3 の場合だけ
別処理が必要でした。

Tegra4 はこれらの欠点を補うどころか、むしろ積極的に機能拡張が
行われているようです。

GL_EXT_shadow_samplers

OpenGL ES 3.0 では標準となる機能ですが、PowerVR SGX 5XT など一部の
GPU ではすでに使えるようになっています。
ただしフィルタリングがかかりませんでした。
未確認ですが Tegra4 はおそらく PCF に対応していると考えられます。

他にも sRGB や draw_instanced など、OpenGL ES 3.0 に対応していないものの
同等の描画が出来るだけの拡張が施されていることがわかります。

他の GPU との比較はこちら↓から。

CPU/GPU OpenGL ES Extension (Mobile GPU)

関連エントリ
Nexus 10 GPU Mali-T604
3DMark Android 版の結果から
HiSilicon K3V2 の GPU
2013/01/09:Qualcomm APQ8064 GPU Adreno 320 の速度


そろそろパフォーマンスの測定もしようと思い同期周りを調べてみます。
ゲームでは CPU と GPU の同期の設計が重要です。描画パフォーマンス優先なら CPU と
GPU ができるだけ並列動作するようにスケジューリングしておきます。
動的な頂点生成で CPU からデータを転送する場合、またはクエリによって GPU の結果を
CPU で受け取る場合など、お互いに待っている時間をなくすようにします。
ここで間違うとパフォーマンスに大きく影響を与えることがあります。


●インターバルの設定

Direct3D 同様に描画時間の管理を自前で行っていたのですが、ウエイト無しにしても
必ず 60fps 前後で止まってしまうことに気がつきました。
ヘッダを見ていたら wglSwapIntervalEXT() を見つけたので使えるか確認。
GeForce GTX280 + 190.57 、"WGL_EXT_swap_control" が含まれています。

wglSwapIntervalEXT( 0 );

これで Display と同期せずに最大速度で描画するようになりました。
モニタのリフレッシュレート依存だと思いますが、 1 を与えると 60fps 固定、
2でその半分となりました。


●フェンス

D3D では ID3D11Query を用いて GPU の状態を受け取ることが出来ます。
レンダリングしたピクセル数、演算頂点数といったレンダリング結果の問い合わせだけでなく、
同期のための Event (Fence) や TimeStamp も含まれています。

OpenGL にも glBeginQuery() ~ glEndQuery() があります。
こちらはもともと実際にレンダリングした pixel 数を返す Occlusion Query の機能だった
ようです。Direct3D にも昔からあるもので、この手のオクルージョン判定は高速化のためと
言うよりレンズフレアの描画などに用いられていました。

同期用の機能は別の API になっていて、glSyncFence() を使います。
fence は描画コマンドと同じように PushBuffer (CommandBuffer) に記録されます。
レンダリングが fence に到達すると、対応する同期オブジェクトを Signal 状態にします。
CPU では同期オブジェクトの状態を見ることで、描画の進行具合と同期を取ることが出来ます。

// 挿入
GLsync  SyncObject;
SyncObject= glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );

// 同期待ち
glClientWaitSync( SyncObject, 0, 0 ); // no wait
glWaitSync( SyncObject, 0, GL_TIMEOUT_IGNORED );

// 削除
glDeleteSync( SyncObject );

glClientWaitSync() は Timeout 時間を指定可能で、状態を返すことが出来ます。
glWaitSync() は Signal 状態になるまで、つまり完了するまでブロックします。
glSynciv() を用いて、現在の状態を参照することも出来るようです。

SwapBuffers() の動作をまだ厳密につかんでいないので、これで正しいかどうか
必要なのかどうかもわかりませんが、同期の例としてはこんな感じで。

static GLsync  SyncObject[2];
static int     SyncCurrent= 0;
static int     FenceCount= 0;

void Render()
{
    ~

    SyncObject[SyncCurrent]= glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );

    SwapBuffers( hDC );

    Current^= 1;
    if( FenceCount ){
        glWaitSync( SyncObject[SyncCurrent], 0, GL_TIMEOUT_IGNORED );
        glDeleteSync( SyncObject[SyncCurrent] );
    }
    FenceCount= 1;
}


速度の測定

当初 TimeStamp が見つからなかったのですが Extension の方にありました。
GL_EXT_timer_query です。GeForce は対応していました。

glBeginQuery() ~ glEndQuery() が拡張されていて、GPU 処理の経過時間を
計測することが出来ます。

// 作成
const int maxid= 8;
GLuint  idbuffer[maxid];
glGenQueries( maxid, idbuffer );

// 削除
glDeleteQueries( maxid, idbuffer );

// 計測
glBeginQuery( GL_TIME_ELAPSED_EXT, idbuffer[0] );
~ // 計測期間
glEndQuery( GL_TIME_ELAPSED_EXT );

// 結果が準備できているか調べる&待つ
GLuint   qret= FALSE;
do{
    glGetQueryObjectuiv( id, GL_QUERY_RESULT_AVAILABLE, &qret );
}while( qret != TRUE );

// 計測結果の受け取り
GLuint64EXT    data= 0;
glGetQueryObjectui64vEXT( id, GL_QUERY_RESULT, &data );

Begin ~ End 区間に発行した GPU 命令の実行時間が返ります。値は nano 秒です。

Direct3D とは少々使い方が異なります。D3D11_QUERY_TIMESTAMP の場合は絶対時間、
つまり GPU クロックの参照に相当し、かつ単位は GPU/ドライバ によって異なります。
また計測期間が連続しているとは限らないため、その結果も受け取る必要があります。
D3D11_QUERY_TIMESTAMP_DISJOINT はこれらの追加情報を返します。

実際に用いる場合は query を 2重化して、1~2フレーム前の結果を受け取るようにします。
これで数値がとれるようになったので、あとは実際に試すだけです。

glquery00.jpg
↑計測の例

OpenGL ES にはこの手の API が無いので、出来れば一通り追加して欲しいところです。


関連エントリ
OpenGL のはじめ方 (2) wgl
OpenGL 3.2 GeometryShader をもう少し使ってみる
OpenGL GLSL のバージョン
OpenGL 3.2 の GeometryShader
OpenGL のはじめ方
OpenGL ES 2.0 Emulator
OpenGL ES 2.0
OpenGLES2.0 DDS テクスチャを読み込む
OpenGLES2.0 Direct3D とのフォーマット変換
OpenGLES 2.0 頂点フォーマットの管理
OpenGLES2.0 の頂点
OpenGLES2.0 D3D座標系
OpenGLES2.0 シェーダー管理


Direct3D 11 対応 GPU RADEON HD 5870/5850 が発表されました。
Windows7 発売に間に合うし、Direct3D 11 SDK も直前に RTM しています。
足並みが揃った良いタイミングです。
あとは安定して入手できるかどうか、ドライバが間に合うかどうかでしょう。

AMD、業界初DirectX 11対応GPU「Radeon HD 5800」シリーズ ~上位モデルは1,600SP搭載の2.7TFLOPS

最近は GPU の世代が代わり 機能が増えても一時的なパフォーマンスの低下は見られなく
なりました。GeForce 6800 や 8800 の時もそうでしたがむしろ倍のスコアを出しています。
速度を求める場合も機能が目的でも、安心して手を出せるのは嬉しいところです。

Direct3D 10 → Direct3D 11 の更新は API 的なデザインの変更は少ないものの、
Direct3D 8 → Direct3D 9 と同じように増えた機能はかなりあります。

・汎用性の向上 Compute Shader
・グラフィックス機能の進化 Tessellation, BC6H/BC7
・管理機能の強化 Dynamic Shader Linkage
・スレッド対応 Deferred Context


一見地味な Dynamic Shader Linkage や Deferred Context も、開発者にとっては
大変嬉しい機能です。
Dynamic Shader Linkage は描画発行時にシェーダー内の飛び先を決定することが出来ます。
いわば関数ポインタのようなもので、シェーダーの種類を増やさずに機能の切り替えを
容易にしてくれます。
Deferred Context は他のスレッドが発行した描画命令を Display List としてバッファリングし、
コンテキストに矛盾が生じないようにします。

シェーダーの機能切り替えも効率よいスレッドの活用も、これまではアプリケーション側で工夫して
実現する必要がありました。
つまり DirectX 11 では従来 CPU 側で行ってきたいくつかの分野もアクセラレーションの
対象となっているといえます。GPGPU に限らず GPU の役割は徐々に広がっているようです。

今後 CPU/GPU もお互いに相手の機能を取り込むだけではなく、より連携しやすいような歩み寄りも
必要ではないでしょうか。例えば CPU にも積極的に GPU 連携のための命令が追加されるとか。
SSE5 の half 型変換命令はその一つの好例かもしれません。

DirectX/GPU 年表 も更新しました。


関連エントリ
DirectX SDK August 2009 の解説と Direct3D 11 RTM
Direct3D11/DirectX11 (18) GPU を使ったアウトラインフォントの描画の(6)
Direct3D11/DirectX11 (13) TessFactor とシェーダーリンクの補足など
Direct3D11/DirectX11 (12) テセレータのレンダーステート他


iOS, Android 共に数多くの端末が登場していますが、CPU は ARM アーキテクチャ、
GPU は OpenGL ES 2.0 世代でほぼ統一されています。

iOS の場合 ES 2.0 世代の GPU は 1種類のみ。
Android の場合は調べてみると予想以上に多彩なことがわかります。
完全に 2強(+1)のデスクトップ GPU と違い、まるで DirectX 初期の頃のように
さまざまなメーカーが参入しています。

iOS:
CPU
    Cortex-A8

GPU 
    PowerVR SGX 535


Android OS:
CPU
    ARM11      ARMv6 (MSM7227)
    Cortex-A8  ARMv7 (S5PC110/ZMS-08)
    Scorpion   ARMv7 (Snapdragon)
    Cortex-A9  ARMv7 (Tegra2)

GPU
    Adreno 200       (Snapdragon QSD8x50/MSM7227)
    Adreno 205       (Snapdragon QSD8x55)
    PowerVR SGX 540  (S5PC110)
    Tegra 250 GPU    (Tegra2)
    ZMS-08 GPU       (ZMS-08)

ATI/AMD のモバイルチップだった Imageon Z430/460 は、Qualcomm になってから
名称が変更されているようです。

Qualcomm Adreno developer
Wikipedia Imageon
Wikipedia Snapdragon (processor)

Adreno のステートを見ると、テクスチャの ATC サポートなど ATI の影響が
残っています。
現行のスマートフォンでは Adreno 200 を搭載した QSD8x50 が多いですが、
HTC Desire HD 001HT の QSD8255 など、今後 Adreno 205 搭載機も
増えてくると思われます。
Z430(200?) が思ったよりも速度を引き出しづらい特性だったので 205 には
期待しています。


昨日ニュースに出ていた Creative の ZiiO は独自のプロセッサ ZMS-08 を
採用しています。

クリエイティブ、Androidメディアプレーヤーを国内販売
Zii LABS

開発はあの 3DLABS (ZiiLABS) なので気になる存在です。


進化速度が速いので、モバイル向け GPU の 3D 性能も大きく向上していく
ものと予想されます。


oga at 03:27

いろんなプロセッサの端末が揃ったのでベンチマークソフトを走らせてみました。
使用したソフトは下記のとおり。

(1) Benchmark 1.03
(2) CPU Benchmark 1.7.1
(3) GPUBench 1.0.0
(4) Quadrant standard 1.1.5
(5) Linpack 1.1.8

                     Desire   ZenTouch2   ZiiO7     LuvPad   ODROID-S
---------------------------------------------------------------------
Android OS              2.2       2.1       2.1       2.2       2.2
Processor            QSD8250    i.MX51    ZMS-08   Tegra250  S5PC110
CPU Hz                 1GHz     800MHz     1GHz     1GHz x2   1GHz
---------------------------------------------------------------------
(1) Bench Graphcis     28.16    225.21    395.79    293.48    517.90
(1) Bench CPU Float  2049.57    432.77    581.37   2816.16   1675.83
(1) Bench Memory      339.03    183.67    721.17    516.18    680.16
(2) CPU Benchmark     759ms    1207ms    1038ms     436ms     719ms
(3) GPU Absolute     14633     22071       ---       ---       ---
(3) GPU Relative     11587     26300       ---       ---       ---
(4) Quadrant          1259       979      1995      1827      1040
(5) Linpack           32.82      5.66      5.97     36.71      ---
----------------------------------------------------------------------
* (2) のみ値が小さいほうが速い

テスト環境は厳密に合わせたわけではないので結果は参考程度にお願いします。
例えば通信の接続状況とか起動中のサービスなど。

OS の違いを考慮する必要があります。
Android OS 2.2 では JIT が搭載されたため、Java アプリの場合は実行内容に
よっては 2.1 と 2.2 で極端な差が出ます。(1) の CPU や (5) など。
ZEN Touch2 と ZiiO7 で全体的に速度が低いのはそのためです。

GPU Test は OpenGL ES 2.0 ですが、動かないケースが多くあまり比較
できませんでした。

Quadrant は Disk/DB 速度が含まれているのでプロセッサのみの結果では
ないようです。例えば Desire の結果とプリセットされている結果を比べると
OS 2.2 になって 2倍程スコアが上がっていることがわかります。
その分を考慮すると OS 2.1 の ZEN Touch 2 や ZiiO7 はかなり突出した
値が出ているように見えます。原因は不明です。

LuvPad の Tegra は GPU 側をきちんと評価できていませんが、とりあえず
CPU core が高速なことがわかります。おそらく多くのテストは Single Thread
だと思われるので、A9 Dual ならもっと速いのではないでしょうか。

厳密ではなく大雑把な傾向ですがおそらく同クロックの場合

整数: A9 > A8 > Snapdragon1
浮動小数 VFP: A9 > Snapdragon1 > A8
(NEON: A8 ≧ Snapdragon1)

といった印象です。
GPU は残念ながらデータ不足です。
ただ同一と思われた GPU でも違う結果が出ています。
画面サイズやバス速度の差もあるのかもしれません。

結果の詳細はこちら
CPU/GPU Benchmark

ちなみにベンチマーク結果と実際の使用感、体感速度は全くの別物です。
現状だとほぼ Desire X06HT とそれ以外の 2つに分けられます。
ZEN Touch2/ZiiO7 はパネルにさえ慣れれば反応は良好な方です。


テスト端末

・Desire
 HTC Desire X06HT
 Qualcomm Snapdragon QSD8250, Scorpion 1GHz, Adreno 200
 Android 2.2
 800x480
 RAM 576MB

・ZenTouch2
 Creative ZEN Touch 2 (8GB) TN-T28G
 Freescale i.MX51, Cortex-A8 800MHz, AMD Z430
 Android 2.1
 480x320
 RAM 256MB(?)

・ZiiO7
 Creative ZiiO 7 (8GB) ZO-7S
 ZiiLabs ZMS-08 HD, Cortex-A8 1GHz, ZMS-08
 Android 2.1
 800x480
 RAM 512MB

・LuvPad
 MouseComputer LuvPad AD100
 NVIDIA Tegra 250, Cortex-A9 x2 1GHz, Tegra 250
 Android 2.2
 1024x600
 RAM 512MB

・ODROID-S (借り物)
 HardKernel ODROID-S
 Sumsung S5PC110, Cortex-A8 1GHz, PowerVR SGX 540
 Android 2.2
 480x320
 RAM 512MB



OpenGL ES 2.0 では使用可能な圧縮テクスチャ形式が GPU 毎に異なっています。
カラー向けのフォーマットは現在大きく分けて下記の 4 通りあります。

(1) PVRTC 系
(2) ATITC 系
(3) S3TC(DXT) 系
(4) ETC 系

iOS
  PowerVR SGX           PVRTC

Android
  Qualcomm Adreno       ETC1, ATITC, 3DC, PALETTE
  ATI Imageon           ETC1, ATITC, 3DC, PALETTE
  Imagination PowerVR   ETC1, PVRTC
  NVIDIA Tegra2         ETC1, S3TC(DXT), LATC
  ZiiLabs ZMS-08 HD     ETC1, S3TC(DXT), PALETTE


●(1) PVRTC 系

PowerVR SGX 系各種。
iOS 系の全機種で使われているため対応ハードはかなり多いはずです。
Android の場合は Galaxy S/Tab の Samsung S5PC110 等。
フォーマットは下記の 4通り。

PVRTC  RGB   4bpp
PVRTC  RGBA  4bpp
PVRTC  RGB   2bpp
PVRTC  RGBA  2bpp

PVRTC は 2bpp/4bpp 選択可能で alpha チャンネルを含めることができるため
同一解像度なら他のフォーマットよりも少ない容量に変換されます。

反面、正方形しばりがあります。元画像が正方形でない場合は引き伸ばすことに
なるため逆に容量が大きくなるケースがあります。
2倍までのスケーリングなら 2bpp に落とすことでほぼ同等の画質と容量を維持
することができると思われます。


・元画像が 256x256 なら 4bpp に変換
・元画像が 128x256 なら 256x256 に拡大+ 2bpp に変換

変換ツールは開発者サイト PowerVR Insder にあります。

Imagination PowerVR Insider

テクスチャは専用の pvr 形式で保存しますが、pvr 形式自体は ETC,DXT 等
さまざまなフォーマットを格納可能です。


●(2) ATITC 系

ATI の Imageon 及び、Qualcomm の Snapdragon 等に搭載されている Adreno
シリーズで対応しています。
Android に限定すると対応端末はかなり多いと思われます。

             FourCC  bpp
ATITC  RGB   'ATC '  4bpp
ATITC  RGBA  'ATCA'  8bpp Explicit Alpha
ATITC  RGBA  'ATCI'  8bpp Interpolated Alpha

4bpp 時に 1bit alpha を含められない以外は圧縮率も機能共にほぼ
DXT1/DXT3/DXT5 と同等になっているようです。画質に関しては未調査。

圧縮ツールは AMD(ATI) 製のものがあります。
このツールは ATC や ETC を DDS 形式で保存します。

AMD The Compressonator

Adreno と改名した後 Qualcomm も開発者向けページを用意しています。

Adreno Graphics

ATITC 系 GPU は法線などカラー以外に応用可能な 3DC (BC4/5) も対応している
のが特徴です。


●(3) S3TC/DXT 系

NVIDIA Tegra2, 3DLabs ZMS-08 HD, PC 向け GPU 各種。
DirectX の標準フォーマットであり、OpenGL でも多くの PC 向け GPU
対応しています。
とにかく対応しているツール数が多く、変換や扱いで困ることがありません。

             FourCC  bpp   dx10
S3TC   RGB   'DXT1'  4bpp  BC1
S3TC   RGBA  'DXT1'  4bpp  BC1 (1bit alpha)
S3TC   RGBA  'DXT3'  8bpp  BC2
S3TC   RGBA  'DXT5'  8bpp  BC3

DXT1 は 1bit の alpha 値を含めることが出来ますが、OpenGL の場合この
両者を区別しています。厳密には 4x4 pixel の block 単位で切り替えられる
ため DirectX では区別がありません。
DXT1/DXT3/DXT5 は Direct3D 10 以降 BC1/BC2/BC3 と呼ばれます。


●(4) ETC 系

Android の場合すべての GPU で利用できます。
ARM Mali など ETC のみ対応している GPU もあります。

iOS では PowerVR 一つなので問題ありませんが、Android では GPU 毎に
互換性のない様々な圧縮テクスチャ形式を持っています。
Android で唯一の共通フォーマットとして利用出来るのが ETC1 圧縮です。
Froyo 2.2 以降 ETC1 専用の API も用意されています。
iOS では使えませんが Android 上では PowerVR も ETC1 が使えます。

             FourCC  bpp
ETC    RGB   'ETC '  4bpp

ETC1 の圧縮は比較的多くのツールで対応しています。
例えば ATITC で紹介した AMD The Compressonator も ETC 変換可能で DDS として
保存できます。
ただし ETC 圧縮時に画質(変換速度)を指定できず、プレビューで極端に劣化した
画像が表示されることがあります。PVR 用の PVRTexTool ツールで読み込ませると
正しく表示されるため、The Compressonator だと ETC 画像の読み込み部に
何らかの問題がありそうです。

Ericsson 本家及び Mali のツールがあります。

Ericsson Texture Compression
Mali Developer Center


●ファイルフォーマット

     PVRTC ATITC S3TC  ETC  拡張
----------------------------------
DDS   --    ◯    ◎    ◯  FourCC
PVR   ◎    --    ◯    ◯
KTX   ◯    ◯    ◯    ◯  GL_*
PKM   --    --    --    ◎


●DDS

DirectX 標準フォーマットです。mipmap, cubemap, volume, array など各種形式に
対応可能で、古くから使われているためツール類が揃っています。
特殊なフォーマットは FourCC で識別しているので、4文字のコードが決まれば
新しい圧縮形式でも対応できます。

DDS Texture format memo


●PVR

PVRTC だけでなく DXT/ETC などさまざまな画像フォーマットに対応しているようです。
ATITC のファイルタイプは定義されていないので格納できません。
比較的ツールも揃っているようです。


●KTX

OpenGL / OpenGL ES 向けに新たに作られたフォーマットのようです。
PVRTexTool が対応しています。
GL のシンボル値をそのまま格納するので GL API と相性が良いのが特徴。
OpenGL で数値が定義されていれば、新しい圧縮形式でもそのまま保存する
ことが出来ます。

Khronos KTX File Format Specification

画像格納時の優先順が DDS と逆で、3d/cube/array を持ったデータが mipmap 個
並ぶ順番になっています。
ツールでは画像の上下など GL の定義に厳密に変換される可能性があるようです。
メタデータ KTXorientation を調べることで uv の向きがわかります。

ヘッダが Bigendian/Littleendian 両対応しているなど、ターゲットハードに
最適化した実行時向けのフォーマットと思われます。


●PKM

ETC1 (PACKMAN) のための専用フォーマットのようです。
Android の ETC1 用 API が対応しています。


●Android とテクスチャ

効率を考えると GPU Native なフォーマットの方が有利ですが管理が大変です。
それでも速度最優先なら全部持つしかなさそうです。

1. alpha 不要なら ETC1
2. alpha が必要で速度優先なら PVRTC,ATITC,S3TC,非圧縮 全部



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)


HTC J butterfly HTL21 (AQP8064) を手に入れたので、
今更ながらやっと Krait と Adreno 320 を試せるようになりました。

Krait は Qualcomm が開発した ARMv7A CPU の CPU core で
Scorpion の後継にあたります。
ARM でいえば Cortex-A15 の世代に相当し、Apple A6/A6X の CPU core も同様に
この世代に属します。

これら ARM, Qualcomm, Apple 3つの CPU は同じ ARMv7-A の命令
アーキテクチャでアプリケーションに互換性がありますが、
Intel と AMD のように設計や性能は異なります。

ARM            Qualcomm    Apple
---------------------------------------------------------
Cortex-A8/A9   Scorpion                    vfpv3   ~2012
Cortex-A15     Krait       Apple A6        vfpv4   2012~

この中で Krait が最も先に登場しており、日本でも 5月の HTC J 以降
Snapdragon S4 MSM8960/8260A/8660A 搭載機種が増えています。
むしろ LTE では Krait でないスマートフォンの方が少ないかもしれません。


Snapdragon S4 Pro APQ8064 のもう一つ新しい点は、GPU も世代交代していることです。
GPU Adreno 320 はハードウエア的には OpenGL ES 3.0 に対応しており、
こちらも他社に先駆けて手に入る状態となりました。

実際に調べてみると、OpenGL ES 3.0 の新しい圧縮テクスチャ形式である
ETC2 / EAC に対応していることがわかります。

TextureFormat 26
tc[00]=87f9  GL_3DC_X_AMD
tc[01]=87fa  GL_3DC_XY_AMD
tc[02]=8c92  GL_ATC_RGB_AMD
tc[03]=8c93  GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
tc[04]=87ee  GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
tc[05]=8d64  GL_ETC1_RGB8_OES
tc[06]=8b90  GL_PALETTE4_RGB8_OES
tc[07]=8b91  GL_PALETTE4_RGBA8_OES
tc[08]=8b92  GL_PALETTE4_R5_G6_B5_OES
tc[09]=8b93  GL_PALETTE4_RGBA4_OES
tc[10]=8b94  GL_PALETTE4_RGB5_A1_OES
tc[11]=8b95  GL_PALETTE8_RGB8_OES
tc[12]=8b96  GL_PALETTE8_RGBA8_OES
tc[13]=8b97  GL_PALETTE8_R5_G6_B5_OES
tc[14]=8b98  GL_PALETTE8_RGBA4_OES
tc[15]=8b99  GL_PALETTE8_RGB5_A1_OES
tc[16]=9270  GL_COMPRESSED_R11_EAC
tc[17]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[18]=9272  GL_COMPRESSED_RG11_EAC
tc[19]=9273  GL_COMPRESSED_SIGNED_RG11_EAC
tc[20]=9274  GL_COMPRESSED_RGB8_ETC2
tc[21]=9275  GL_COMPRESSED_SRGB8_ETC2
tc[22]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[23]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[24]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[25]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC

OpenGL ES 2.0 のままでも列挙されるので、すでに利用できる状態となっています。
ETC1 も同列に列挙されるのは OpenGL ES 2.0 API だからだと思われます。

また GPU Extension に GL_EXT_sRGB が増えています。
sRGB 対応もやはり OpenGL ES 3.0 の新機能です。

Extension の詳細は下記のページに追加しました。

OpenGL ES Extension (Mobile GPU)

GPU 比較はこちら

Mobile GPU の比較


いつものベンチマークはデータをとっている最中です。
使った感じは GPU が非常に速いです。
一番重いケースでも 30fps を余裕で超えており、とても Full HD (1920x1080)
でレンダリングしているとは思えません。

傾向としては Adreno 220 と同じでシェーダーの演算負荷に強く、同じ
Unified Shader ながら PowerVR のように面積が増えても極端に処理落ちしません。
演算精度によるペナルティが無いため、プログラマにとっては非常に扱いやすく
かつ演算精度が高いのでレンダリング結果も綺麗です。

ピクセルシェーダーの命令が少なく演算負荷が軽いケースでは PowerVR が
飛び抜けていますが、ピクセル(フラグメント)の演算量が多い場合はおそらく
A5X の PowerVR SGX543MP4 より速く、A6X の SGX554MP4 に近い数値が出るようです。
もちろん条件によるので万能ではありません。

CPU のデータも計測中ですが CPU core 単体では A6/A6X よりも遅いようです。
やはり A6/A6X は速いです。
その代わり core 数が A6/A6X の 2倍 (Quad core) なので、
総合的な能力では十分だと思います。


関連エントリ
iPad 4 Apple A6X GPU PowerVR SGX554 MP4 の速度
iPhone 5 / A6 の CPU 速度 その 3
iPhone 5 / A6 の CPU 速度 その 2
OpenGL / OpenGL ES ETC1 の互換性と KTX の落とし穴
OpenGL 4.3/ES 3.0 ETC2 Texture 圧縮の仕組み (PVRTC2,ASTC)
OpenGL 4.3 と GL_ARB_ES3_compatibility


DirectX SDK Novemver 2008 には DirectX11 (D3D11) の beta SDK が含まれています。
Direct3D11 API の機能や詳細が明らかになってきました。

Direct3D10 で大幅に変更された API の路線は継承されていますが
さらに現実的な改良がいくつも施されています。
中でも驚いたのが、D3D10 の時よりも間口を広げたこと。

手持ちの RADEON HD4850 でも D3D11 サンプルが動作しました。
(Windows Vista x64 + HD4850 CATALYST 8.10)
サンプルによっては、Reference でなくアクセラレートが利いているものもあります。
D3D9 GPU では一切動かなかった D3D10 とはえらい違いです。
信じられないくらい。


■D3D9 → D3D10 の場合

・Preview SDK が出ても当時は Vista 発売前だったため Reference Driver ですら
 動かなかった。
・D3D10 専用 GPU (ShaderModel 4.0 以上) が無いと一切ハードウエアアクセラレータ
 が利かなかった。(Reference のみ)


■D3D10 → D3D11 の場合

・Vista 上なら旧ビデオカードでも Reference Device で動く。
・D3D10 GPU でも D3D11 API が使えた。Feature Level が制限されるだけで API
 自体は置き換えられる。未対応の機能さえ使わなければアクセラレートされるらしい。
・さらに WARP Driver (WARP Device) が使える。(詳細は後述)


D3D9 以前は CAPS 情報があったため、旧 GPU でも使えない機能が判別できました。
D3D10 はデバイスの性能を特定する仕組みが無く、D3D10 の全機能が必須となり
 旧 GPU は切り捨てられました。
D3D10.1 では FeatureLevel が導入され、10.0 と同居可能となりました。
D3D11 では同じように FeatureLevel で各 GPU のレベルを判別します。

Feature Level
  11.0 = ShaderModel 5.0
  10.1 = ShaderModel 4.1
  10.0 = ShaderModel 4.0
   9.3 = ShaderModel 3.0
   9.2 = ShaderModel 2.0
   9.1 = ShaderModel 2.0

上記 FeatureLevel の定義を見ると、D3D10 GPU どころか D3D9 世代、
ShaderModel 2.0~3.0 にも対応しているように見えます。
もしこれが本当なら、Direct3D10 よりも Direct3D11 の方が対応 GPU の範囲が広い
ことになります。
Direct3D10 は動かないけど Direct3D11 なら動く可能性があるということ。

Direct3D9 の固定パイプライン(HW T&L) が使えないだけで、従来の D3D9Ex も
D3D11 API に統合可能なのかもしれません。

互換性を保った API の置き換えは D3D9 以前の DirectX では当たり前だったため、
元に戻っただけともいえます。
それでも D3D10 の仕様を考えると非常に大きな路線変更です。

Direct3D10 へ移行するのはものすごい骨が折れるし敷居も高かったので良い傾向です。

FeatureLevel 9.2 と 9.1 の違いは不明です。
ShaderModel は vs3.0/vs2.0 ではなく、vs_4_0_level_9_1 等 4.0 の制限版と
なるようです。


●Device Type (Driver Type)

Device Type が増えました。
目新しいのは Null Reference Device と WARP Device です。

・Hardware Device (HAL)
・Null Reference Device
・Reference Device
・Software Device
・WARP Device


Null Reference Device は Reference Device 同様ソフトウエア動作しますが
レンダリング機能が無いようです。API 呼び出しだけソフトウエアでシミュレート
することで、現実的な速度でデバッグを行うのが目的のようです。

WARP Device (Windows Advanced Rasterizer) は高速なソフトウエアラスタライザ
のようです。Multi Core CPU が当たり前になり GPU との差が埋まりつつあるため、
ソフトウエアラスタライザが復活といったところでしょうか。
WARP Device は D3D11/D3D10.1 の置き換えが出来るそうです。
詳しい説明がないため中身はわかりませんが、RAMP とか MMX RGB Driver が存在
していた D3D5~D3D6 あたりを思い出します。

実際に D3D_DRIVER_TYPE_WARP を使ってみたところ、D3D10WARP_beta.dll が
読み込まれているのを確認しました。
Dual Core CPU で試したためあまり参考にならないかもしれませんが、確かに動作は
REFERENCE Driver より高速でした。
Reference で 0.3fps 程度のサンプルが、数fps 程度には向上しています。
Quad 以上ならもっと効果が顕著だと思われます。

これから CPU の core 数は増加していきます。例えば Core i7 は Quad + HT で
ハードウエア 8 スレッドらしいので、今後はさらに期待できそうです。


DirectX11 に関しては下記関連エントリも参考にしてください。


関連エントリ
Direct3D11 シェーダーの動的リンクやテクスチャ
Direct3D11 マルチスレッドのための機能
Direct3D11 テセレータとシェーダー
Direct3D11 のパイプライン
Direct3D11 Compute Shader など
Gamefest2008 と Direct3D 11



AMD Z430 は PowerVR と同じようにタイルベースのレンダリング (TBR) を行うことで
知られています。TBR も Unified Shader の仕様も AMD は Xbox360 の GPU がベース
だと説明していますが、その両者の性能差は桁違いです。
一方は強力な GPU が要求するバス帯域に応えるため、もう一方はモバイル向けでタイトな
メモリ速度でもそれなりの性能を維持するため。同じ技術でも応用先の GPU が真逆なのは
面白いところです。

AMD Next-Gen Tile-Based GPUs (pdf)
AMD Next-Generation OpenGLR ES 2.0 Graphics Technology Achieves Industry Conformance

NetWalker に用いられている i.MX515 は GPU core として AMD (ATI) imageon Z430
を搭載しています。
ここ最近 NetWalker で OpenGL ES 2.0 を触っていますが、まだ Z430 の特性がうまく
つかめておらずあまり速度が出ていません。調べている最中です。
偶然 TBR のタイル領域の大きさを知ることが出来ました。


●タイルサイズ

NetWalker_OpenGLES03.jpg

フレームバッファをクリアしないで描画した場合の画面がこれです。GPU のタイルバッファも
クリアせずに上書きされているようです。
1024x600 の画面なので、上の写真のケースだと 1タイルは 256x128 ドット。
以下バックバッファの組み合わせ毎にタイルサイズをまとめてみました。

Color   Depth/Stencil   Tile
-----------------------------------
16bit   none            512x128
16bit   16bit           256x128
32bit   16bit           128x128
16bit   24bit/8bit      128x128
32bit   24bit/8bit      128x128

◎タイルバッファの容量

 少なくても 128KByte 存在しています。予想より大容量です。

◎Depth/Stencil との組み合わせ

 使用可能な depth の幅はカラーの影響を受けることが多いのですが、こちら
 書いたとおり Z430 では任意の組み合わせを選べます。PowerVR もそうだったので
 やはり TBR 専用のバッファを持っているおかげだと思われます。

◎32bit Color or 24bit Depth 利用時の速度低下

 Color か Depth どちらかを 16bit より増やすと速度に影響が出ます。
 その原因はバス帯域だと思っていましたが、この結果を見るとタイル分割数の増加が
 負担になっているのかもしれません。


● Extension

まだ試していませんが TBR を制御する API があります。

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: AMD Z430
GL_VENDOR: Advanced Micro Devices, Inc.
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00
GL_EXTENSIONS:
    GL_AMD_compressed_3DC_texture
    GL_AMD_compressed_ATC_texture
    GL_AMD_performance_monitor
    GL_AMD_program_binary_Z400
    GL_AMD_tiled_rendering
    GL_EXT_texture_filter_anisotropic
    GL_EXT_texture_type_2_10_10_10_REV
    GL_EXT_bgra
    GL_OES_compressed_ETC1_RGB8_texture
    GL_OES_compressed_paletted_texture
    GL_OES_depth_texture
    GL_OES_depth24
    GL_OES_EGL_image
    GL_OES_EGL_image_external
    GL_OES_element_index_uint
    GL_OES_fbo_render_mipmap
    GL_OES_fragment_precision_high
    GL_OES_get_program_binary
    GL_OES_packed_depth_stencil
    GL_OES_rgb8_rgba8
    GL_OES_standard_derivatives
    GL_OES_texture_3D
    GL_OES_texture_float
    GL_OES_texture_half_float
    GL_OES_texture_half_float_linear
    GL_OES_texture_npot
    GL_OES_vertex_half_float
    GL_OES_vertex_type_10_10_10_2
    GL_NV_fence


● NetWalker の速度比較

描画面積を出来るだけ小さくして頂点速度を測定しようとしたもの。

AMD Z430          48000x1 =  48000 Tris/s 30fps = 約 1.44M Tris/s  (1024x600)
PowerVR SGX 535   48000x4 = 192000 Tris/s 45fps = 約 8.64M Tris/s  ( 480x320)

フレームバッファのサイズが極端に違うし、どちらも Unified Shader なので頂点に
ピクセルの影響が全くないとは言い切れません。Clear → Swap だけでもあまり速度
出ないので、広い画面が仇になっている可能性があります。
タイル+転送だけである程度の負荷がかかり、頂点も圧迫しているのでしょうか。
1024x600 は 480x320 のちょうど 4倍の面積です。

1024x600 = 614400 pixels  8 倍  NetWalker
 640x480 = 307200 pixels  4 倍  VGA
 480x320 = 153600 pixels  2 倍  iPhone
 320x240 =  76800 pixels  1 倍  QVGA


● VRAM 容量

PC のチップセット内蔵 GPU と同じように、VRAM はメインメモリから確保していると
考えられます。NetWalker の RAM は 512MB ですが 480MB しか見えないので、残りの
32MB が VRAM の取り分かもしれません。

1024x600 x16bit は 1.2MB (fb は 2.5MB) なので、32MB もあると少々無駄に感じる
かもしれません。ところが OpenGL ES 2.0 を使っていたらあっという間に VRAM が
溢れました。(GL_OUT_OF_MEMORY を返す)

その原因は自分のローダーでした。Z430 が DXT に対応していないため、圧縮された
テクスチャを 8888 に展開していたからです。あらかじめ ATC/3Dc/ETC へ変換して
おけば解決するはずです。計算したらテクスチャを 23MB も読み込んでいました。

もう一つ考えられる理由は TBR による遅延レンダリングです。
システムメモリからの逐次転送できず、シーンに必要なリソースを全部 VRAM に乗せて
おかないと描画できないのかもしれません。何らかの確証があるわけではなくあくまで
想像です。

どちらにせよ、設定を変えられるなら VRAM 容量はもうちょっと増やしたいところです。


●立ったまま OpenGL ES 2.0 プログラミング

帰りの電車の中では立ったまま、EGLConfig のパラメータを変えて make したりタイルの
データ取りをしてました。この大きさで開発+実行できるのは良いですね。


関連エントリ
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (3)
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (2)
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0
OpenGL ES 2.0 Emulator


Nexus 7 (2013) が発売されたので、
Adreno 320 上でも OpenGL ES 3.0 のテストができるようになりました。
現時点で OpenGL ES 3.0 を走らせるには、
Android 4.3 と OpenGL ES 3.0 対応 GPU が必要です。

                 SoC                 CPU             GPU
---------------------------------------------------------------
Nexus 10         Exynos5 Dual        Cortex-A15 x2   Mali-T604
Nexus 7 (2013)   Snapdragon APQ8064  Krait x4        Adreno 320

現在 OpenGL ES 3.0 + Android 4.3 に対応しているのは上記 2機種です。
(おそらく明後日 30日発売の Nexus 4 も可能だと思われます)

新しい Nexus 7 を下記ページに追加しました。

CPU/GPU OpenGL ES Extension (Mobile GPU)

Qualcomm Snapdragon APQ8064 自体は、昨年末から採用端末が多数
登場しているので、今となってはあまり目新しいものではないかもしれません。
ですが、AQP8064 は CPU core, GPU core の両方が世代交代した
アーキテクチャとなっており、開発用途では非常に興味深い内容となっています。

当初から ETC2 など OpenGL ES 3.0 の仕様が部分的に含まれていましたし、
3DMark でもかなり優秀な成績を収めています。
でもこれはまだ DX10 対応 GPU で DX9 のデモを走らせているようなもの。

Android 4.3 + OpenGL ES 3.0 でようやく GPU の世代に一致したシェーダーを
走らせることができるようになります。

以下 Nexus 7 (2013) からの抜粋L

GL_VERSION: OpenGL ES 3.0 V@14.0 AU@  (CL@)
GL_RENDERER: Adreno (TM) 320
GL_VENDOR: Qualcomm
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00

Extension:
GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_texture_filter_anisotropic
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float

下記は Nexus 10 の Mali-T604 との比較

				        Nexus 7 (2013)  Nexus 10
                                         Adreno 320     Mali-T604
-----------------------------------------------------------------
=== GL3:texture
GL_MAX_3D_TEXTURE_SIZE                      1024          4096
GL_MAX_TEXTURE_SIZE                         4096          4096
GL_MAX_ARRAY_TEXTURE_LAYERS                 256           4096
GL_MAX_TEXTURE_LOD_BIAS                     15.984375     255.996094
GL_MAX_CUBE_MAP_TEXTURE_SIZE                4096          4096
GL_MAX_RENDERBUFFER_SIZE                    4096          4096
GL_MAX_DRAW_BUFFERS                         4             4
GL_MAX_COLOR_ATTACHMENTS                    4             4
GL_MAX_VIEWPORT_DIMS                        4096          4096
=== GL3:elements
GL_MAX_ELEMENTS_INDICES                     -1            16777216
GL_MAX_ELEMENTS_VERTICES                    -1            16777216
=== GL3:vertex
GL_MAX_VERTEX_ATTRIBS                       16            16
GL_MAX_VERTEX_OUTPUT_COMPONENTS             69            64
=== GL3:pixel
GL_MAX_FRAGMENT_INPUT_COMPONENTS            71            60
=== GL3:program
GL_MIN_PROGRAM_TEXEL_OFFSET                 -8            -8
GL_MAX_PROGRAM_TEXEL_OFFSET                 7             7
GL_MAX_VARYING_COMPONENTS                   64            60
GL_MAX_VARYING_VECTORS                      16            15
=== GL3:output stream
GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 64       64
GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS       4        4
GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS    4        4
GL_MAX_SAMPLES                                   4        4
=== GL3:uniform block
GL_MAX_VERTEX_UNIFORM_COMPONENTS            1024          1024
GL_MAX_VERTEX_UNIFORM_VECTORS               256           256
GL_MAX_VERTEX_UNIFORM_BLOCKS                12            12
GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS   --            50176
GL_MAX_FRAGMENT_UNIFORM_COMPONENTS          896           4096
GL_MAX_FRAGMENT_UNIFORM_VECTORS             224           1024
GL_MAX_FRAGMENT_UNIFORM_BLOCKS              12
GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 197504        53248
GL_MAX_UNIFORM_BUFFER_BINDINGS              24            36
GL_MAX_UNIFORM_BLOCK_SIZE                   65536         16384
GL_MAX_COMBINED_UNIFORM_BLOCKS              24            24
=== GL3:tex
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS           16            16
GL_MAX_TEXTURE_IMAGE_UNITS                  16            16
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS         32            32

Mali では Fragment で使える Uniform 数の方が Vertex よりも多いですが
Adreno では少なくなっているようです。
少々特殊な 896 / 224 という数値は OpenGL ES 3.0 の仕様を満たしています。
むしろ Adreno に合わせた数値(仕様)だと思われます。

実際にプログラムを走らせてみたのですが、残念ながら
Adreno 320 の OpenGL ES 3.0 ではまだ複雑なシェーダーが正しく動いていません。
簡単なシェーダーと、OpenGL ES 2.0 互換モードでは動作を確認できました。
Shader の Link 時に Internal error が発生しているので、
原因を調べているところです。


関連エントリ
Android 4.3 と OpenGL ES 3.0
Nexus 10 CPU Cortex-A15 の速度
Nexus 10 GPU Mali-T604
3DMark Android 版の結果から


・Android Adreno 320 OpenGL ES 3.0 (Nexus 7 2013)
adreno320_nexus7_es3.png

・Android Adreno 320 OpenGL ES 2.0 (HTC J butterfly HTL21 )
adreno320_es2.png

・Android Mali-T604 OpenGL ES 3.0 (Nexus 10 2012)
malit604_nexus10_es3.pngmalit604_nexus10_es3_b.png

・Android Tegra 4 ULP GeForce(72) OpenGL ES 2.0 (Tegra Note 7)
tegra4_note_es2.png

・Android Tegra 3 ULP GeForce(12) OpenGL ES 2.0 (Nexus 7 2012)
tegra3_nexus7_es2_colorbuffer.png

・iOS7 PowerVR SGX543MP3 OpenGL ES 2.0 (iPhone 5)
pvr543mp3_iphone5_es2.png

・iOS7 PowerVR G6430 OpenGL ES 3.0 (iPhone 5s)
pvrg6340_iphone5s_es3.png

・RK3066 Mali-400MP4 OpenGL ES 2.0 (MOMO7)
mali400mp4_es2.png

・Vivante GC4000 OpenGL ES 2.0 (dtab 01)
vivante_gc4000_es2.png

OpenGL ES 2.0 デバイスの大半は GL_OES_depth_texture だけに対応しており
フィルタはかかりません。
depth_texture が無い Tegra2/3 は ColorBuffer で代用しています。

Tegra 4 は OpenGL ES 2.0 ですが Extension で GL_EXT_shadow_samplers に
対応しておりハードウエアで sampling できるようになっています。

同じように iOS の PowerVR Series5XT も OpenGL ES 2.0 ながら早くから
GL_EXT_shadow_samplers に対応していました。
iOS5/6 の当初は PCF もなく見た目が全く変わらなかったのですが、
iOS7 ではいつの間にかフィルタがかかるようになっていました。

なお同じ PowerVR Series5XT の GPU でも Android では残念ながら
shadow_samplers が使えない場合が多いです。

OpenGL ES 3.0 以降は PC 同様そのまま shadow samplers が使えます。
ただし結果は GPU やドライバによってかなり差があるようで、
Adreno 320 や PowerVR G6430 が 4 tap PCF のみ。
逆に Mali-T604 のフィルタは他より質が高くなっています。

                        OS  OpenGL depth-tex sh-sample PCF Linear
-----------------------------------------------------------------
APQ8064 Adreno 320      A44 ES 3.0     ◎       ◎      ◎   --
APQ8064 Adreno 320      A41 ES 2.0     ◎       --      --   --
Exynos5 Dual Mali-T604  A44 ES 3.0     ◎       ◎      ◎   ◎
Tegra 4 ULP GeForce(72) A43 ES 2.0     ◎       ◎      ◎   ◎
Tegra 3 ULP GeForce(12) A44 ES 2.0     --       --      --   --
A6 PowerVR SGX543MP3    i70 ES 2.0     ◎       ◎      ◎   ◎
A7 PowerVR G6430        i70 ES 3.0     ◎       ◎      ◎   --
K3V2 Vivante GC4000     A41 ES 2.0     ◎       --      --   --
RK3066 Mali-400MP4      A41 ES 2.0     ◎       --      --   --
OMAP4430 PowerVR SGX540 A42 ES 2.0     ◎       --      --   --

Tegra 2 → Tegra 3 は core 数(速度) が違うだけで機能は全く同一でした。
対して Tegra 4 の GPU は、Tegra2/3 と比べると大幅に拡張されています。
機能面で見ればほぼ別 GPU といえるほど差があるのですが、
OpenGL ES 3.0 未対応など先行する他 GPU より見劣りする部分もあります。

DX9 世代の G70 ベースの限界なのか、それとも単に Tegra2/3 で
削っていた能力を元に戻しただけなのかもしれません。

一般的に NVIDIA に期待するイメージは強力な GPU でしょう。
ですがこれまでの Tegra は真逆で CPU に偏重した作りでした。
次の Tegra K1 以降はようやく NVIDIA らしい GPU になりそうです。


関連エントリ
OpenGL ES 2.0 Adreno 330, Tegra 4 の GPU 速度


低消費電力の Desktop PC 向け CPU として Intel からは BeyTrail-D、
AMD からは Kabini が登場しています。
BayTrail-D Celeron J1900 と Kabini Athlon 5350 は、
どちらも 4 core CPU + マザーボードでちょうど 1万円。
価格帯もスペックも良く似ているので比べてみました。

                    BayTrail-D              Kabini
                    Celeron J1900         Athlon 5350
-----------------------------------------------------
CPU core             Silvermont             Jaguar
CPU cores                4                    4
CPU clock            2.0-2.41GHz           2.05GHz
RAM                DDR3-1333 dual         DDR3-1600
MEM BW                21.3GB/s             12.8GB/s
L2                      2MB                  2MB
SSE                    SSE4.2               SSE4.2
AVX                      --                  AVX
AES                      --                 AES-NI
CPU SP              24 fop/clock         32 fop/clock
CPU SP FLOPS        57.81 GFLOPS          65.6 GFLOPS
CPU DP               6 fop/clock         12 fop/clock
CPU DP FLOPS        14.46 GFLOPS          24.6 GFLOPS
GPU core         Intel HD Graphics 3G    RADEON R3 (GCN)
GPU clock            688-854MHz             600MHz
GPU SP              64 fop/clock         256 fop/clock
GPU SP FLOPS         54.7 GFLOPS         153.6 GFLOPS
OpenGL Windows       OpenGL 4.0           OpenGL 4.3
OpenGL Linux         OpenGL 3.3           OpenGL 4.3
TDP                     10W                  25W

Intel Celeron Processor J1900
AMD Athlon

浮動小数点演算能力

VFP Benchmark     Celeron J1900    Athlon 5350
-------------------------------------------------
SingleT SP max:   14.477 GFLOPS    15.943 GFLOPS
SingleT DP max:    3.619 GFLOPS     6.127 GFLOPS
MultiT  SP max:   57.902 GFLOPS    63.737 GFLOPS
MultiT  DP max:   14.471 GFLOPS    24.504 GFLOPS

・値が大きいほうが高速

前前回の予想通り浮動小数点演算能力は Jaguar (Kabini/Athlon) の方が高くなっています。
J1900 (BayTrail) は動作クロックの高さで補っている形です。

演算能力/clock    Single FP   Double FP
-----------------------------------------------
Celeron J1900         6          1.5
Athlon 5350           8            3

再測定して気が付きましたが、以前のエントリで J1900 の倍精度演算の
性能評価が間違っていました。下記訂正しましたので申し訳ありませんでした。
Atom Bay Trail の浮動小数点演算能力


前回のコンパイル速度比較を Kabini でも試してみました。
驚くほど拮抗しています。

flatlib3 Linux       clock  core  RAM   OS   arch compiler    time sec
-------------------------------------------------------------------------
Kabini Athlon 5350  2.05GHz  x4   8GB  14.04  x64  clang-3.5    54.8
BayTrail-D J1900    2.41GHz  x4   8GB  14.04  x64  clang-3.5    54.6

・time が小さい方が速い

テストした環境は下記の通り。

Test 環境
Celeron J1900 (Q1900B-ITX DDR3-1333 dual   8GB  21.3GB/s)
Athlon 5350   (AM1l       DDR3-1333 single 8GB  10.7GB/s)

Kabini は DDR3-1600 が使えますが、テスト環境では手持ちの DDR3-1333 を使用しています。
本来の能力よりもスコアが低くなっていると考えられますので予めご了承ください。


AES 変換テスト

AES CTR 599MByte  Celeron J1900    Athlon 5350
-------------------------------------------------
Table1               18.708          18.964
Table2               15.409          14.600
Table3               14.902          12.374
AES-NI                   --           4.238

・単位は秒、値が小さい方が速い, Single Thread

AES-NI が使えるため Jaguar (Athlon/Kabini) の方が高速です。
同じアルゴリズム同士でもわずかに Jaguar の方が速いようです。
メモリ速度、CPU の動作クロックともに J1900 (BayTrail) の方が上なので、
Jaguar (Athlon/Kabini) は Core 性能そのものが高いのだと思われます。


簡単なシーンのレンダリング速度の比較

Ubuntu 14.04   GPU                    API            fps
----------------------------------------------------------
Celeron J1900  Intel HD Graphics 3G   OpenGL 3.3     17fps
Athlon 5350    RADEON R3              OpenGL 4.3     89fps

・fps が大きい方が速い

比べるまでもなく内蔵 GPU の性能では圧倒的な差があります。
RADEON は OpenGL で新しい API が使える点もポイントが高いです。
J1900 の GPU は使用していて少々性能不足を感じます。


CPU core の基本性能は Jaguar (Athlon/Kabini) の方が上。
メモリ速度や動作クロックを加味すると両者かなり近い性能になっています。

GPU は当然 RADEON (Athlon/Kabini) の方が速く、
性能差には数倍の開きがあります。

● BayTrail-D (Celeron J1900/Silvermont)
・消費電力が低くファンレス
・メモリ帯域が広い

● Kabini (Athlon 5350/Jaguar)
・浮動小数点演算能力が高い
・AVX/AES 命令に対応している
GPU 性能が非常に高い


関連エントリ
コンパイル時間の比較 BayTrail
Atom Bay Trail の浮動小数点演算能力


ZiiO 7inch 手に入れました。

Creative ZiiO 7

LuvPad のように回線契約なしに買える Android タブレットです。

特徴は比較的安価なこと。8GB モデルで 24800円。
その代わり抵抗膜式タッチパネルを使っておりマルチタッチも非対応です。

LuvPad と違い HOME 画面は独自で、さまざまな Zii アプリケーションが用意
されています。


●気がついたことなど簡単に

・HDMI端子あり
・Android マーケット無し
・ボタン類もタッチ式、抵抗膜パネルの一部
・タッチパネルのキャリブレーション
  設定 → サウンド&画面設定→ Touch screen calibration
・ZiiAcademy というブックリーダー付き。
・タスクマネージャーが最初から入ってる
・RAM 512MB
・タッチパネル反応は慣れると良好
使用感などは後ほど


●デバッガの接続

adb 接続は下記のページを参考にさせていただきました。

でじものがたり Creative ZiiO 7"のフォント変更(再度更新)

同様の手順を以前 LuvPad の時も行いました。下記のページも参考になります。

Developing on a Device


●NDK と GPU

CPU はごく普通の Cortex-A8 1GHz です。
もちろん NEON + VFPv3-D32 です。

GPU は ZiiLabs のオリジナル。
テストプログラムを走らせてみました。

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: ZMS-08
GL_VENDOR: ZiiLABS
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.0


Extension:
  GL_OES_read_format
  GL_OES_compressed_paletted_texture
  GL_OES_byte_coordinates
  GL_OES_fixed_point
  GL_OES_single_precision
  GL_OES_matrix_get
  GL_OES_point_size_array
  GL_OES_point_sprite
  GL_EXT_texture_compression_dxt
  GL_EXT_texture_compression_dxt1
  GL_ZIILABS_fog_mask
  GL_EXT_texture_lod_bias
  GL_EXT_blend_func_separate
  GL_OES_blend_func_separate
  GL_APPLE_texture_2D_limited_npot
  GL_OES_query_matrix
  GL_OES_draw_texture
  GL_OES_element_index_uint
  GL_OES_matrix_palette
  GL_OES_extended_matrix_palette
  GL_OES_compressed_ETC1_RGB8_texture
  GL_OES_framebuffer_object
  GL_OES_rgb8_rgba8
  GL_OES_depth32
  GL_OES_stencil8
  GL_OES_mapbuffer 


tc[00]=8b90  GL_PALETTE4_RGB8
tc[01]=8b91  GL_PALETTE4_RGBA8
tc[02]=8b92  GL_PALETTE4_R5_G6_B5
tc[03]=8b93  GL_PALETTE4_RGBA4
tc[04]=8b94  GL_PALETTE4_RGB5_A1
tc[05]=8b95  GL_PALETTE8_RGB8
tc[06]=8b96  GL_PALETTE8_RGBA8
tc[07]=8b97  GL_PALETTE8_R5_G6_B5
tc[08]=8b98  GL_PALETTE8_RGBA4
tc[09]=8b99  GL_PALETTE8_RGB5_A1
tc[10]=8d64  GL_ETC1_RGB8_OES
tc[11]=83f0  GL_COMPRESSED_RGB_S3TC_DXT1_EXT
tc[12]=83f1  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
tc[13]=83f2  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
tc[14]=83f3  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT

Tegra2 のように DXT 対応です。
ETC も使えます。

VertexShader constant: 128
FragmentShader constant: 16

・頂点テクスチャあり
・shader binary format あり


自前のアプリを移植しましたがシェーダーを読み込んだところで止まります。
ndk サンプルの hello-gl2 も Shader の Link error が出て描画されず
まだうまく動いていません。

GL ES 1.1 のアプリは動いているようです。
速度はものすごく速いといった印象はないです。
OS の違いもあるかもしれません。


GPU 等のまとめ

これまで試した GPU や CPU をまとめました。

OpenGL ES 2.0 モバイル GPU CPU

Android 端末の一覧をこちらに作ってみました。WindowsCE 一覧 の続きのようなもの。

Android 端末一覧


関連エントリ
OpenGL ES 2.0 世代の Mobile GPU
Android LuvPad AD100 を1日持ち歩いた


今までテストに使用してきたプログラムが安定して動作しないため
Adreno 320 では速度の計測ができていませんでした。
LG Optimus G LGL21 を借りることができたのでもう一度テストしてみました。

Mobile GPU ベンチ OpenGL ES 2.0
CPU benchmark
OpenGL ES Extension (Mobile GPU)

GPU bench の (1) 以外は 60fps に達するため数値が出ていません。
GPU 性能が上がったため、もはやこのテストは計測に向いていないことになります。

また Adreno 320 は OpenGL ES 3.0 世代の GPU ですが、
現在の OS から使う限り API は OpenGL ES 2.0 になります。
GPU 性能をまだ引き出せていない可能性があります。

テストプログラムのエラーの原因は特定のケースでシェーダーのコンパイルが
エラーになるもので、回避方法はわかったもののまだ詳しい条件が
特定できていません。

VFP test では HTC J HTL21 よりも良い結果が出ています。

                 (1)     (2)     (3)      (4)    (5)     (6)
                 iPad3  Touch5   EVO 3D  iPad4 Butterfly OptimusG
                 A5X     A5      8660     A6X    8064    8064
                 C-A9    C-A9   Scorpion Swift   Krait   Krait
----------------------------------------------------------------
a:mat44 neon_AQ  4.784   5.979   2.879   1.204   1.919   1.354
b:mat44 neon_BQ  2.408   3.008   1.146   1.266   1.273   0.930
c:mat44 neon_AD  4.781   5.974   3.079   1.554   2.453   1.862
d:mat44 neon_BD  2.406   3.007   1.440   1.344   2.041   1.521
e:fadds      A   4.010   5.013   3.460   2.882   3.791   2.831
f:fmuls      A   4.010   5.012   4.361   2.953   3.671   2.793
g:fmacs      A   4.012   5.011   4.034   5.763   7.334   5.599
h:vfma.f32   A   -----   -----   -----   5.765   3.725   2.743
i:vadd.f32 D A   4.111   5.136   3.493   2.877   3.706   2.724
j:vmul.f32 D A   4.110   5.136   3.502   2.950   3.667   2.767
k:vmla.f32 D A   4.512   5.650   3.638   2.951   7.557   5.462
l:vadd.f32 Q A   8.023  10.036   3.408   2.878   3.677   2.717
m:vmul.f32 Q A   8.022  10.028   3.427   2.952   3.647   2.741
n:vmla.f32 Q A   8.025  10.028   3.400   2.955   7.362   5.446
o:vfma.f32 D A   -----   -----   -----   2.494   3.676   2.709
p:fadds      B   4.014   5.013   5.972   5.757   4.664   3.388
q:fmuls      B   5.013   6.265   5.960   5.760   4.583   3.384
r:fmacs      B   8.023  10.024   8.573  11.521   8.266   6.246
s:vfma.f32   B   -----   -----   -----  11.519   4.611   3.622
t:vadd.f32 D B   4.113   5.137   5.945   2.881   4.746   3.406
u:vmul.f32 D B   4.118   5.145   5.098   2.951   4.680   3.454
v:vmla.f32 D B   9.027  11.278   8.498   5.757   8.361   6.140
w:vadd.f32 Q B   8.021  10.023   5.950   2.879   4.702   3.481
x:vmul.f32 Q B   8.029  10.023   5.095   2.951   4.595   3.412
y:vmla.f32 Q B   9.026  11.277   8.497   5.762   8.464   6.249
z:vfma.f32 D B   -----   -----   -----   5.759   4.660   3.413
---------------------------------------------------------------
↑数値は実行時間(秒) 数値が小さい方が速い

(1)=Apple iPad 3           A5X      ARM Cortex-A9 x2  1.0GHz
(2)=Apple iPod touch 5     A5       ARM Cortex-A9 x2  0.8GHz
(3)=HTC EVO 3D ISW12HT     MSM8660  Scorpion      x2  1.2GHz
(4)=Apple iPad 4           A6X      A6 (swift)    x2    ?GHz
(5)=HTC J butterfly HTL21  APQ8064  Krait         x4  1.5GHz
(6)=LG Optimus G LGL21     APQ8064  Krait         x4  1.5GHz

Krait の FP 性能は Swift に並ぶ新 core であることがよくわかります。

前回のテスト時はクロックが上限まで上がっていなかった可能性があります。
HTC J butterfly が修理から戻ってきたらもう一度計測してみたいと思っています。


関連エントリ
Adreno 320 Snapdragon S4 Pro APQ8064


Desktop GPU で Vertex Shader と Pixel Shader の仕様が完全に
統一されたのは Direct3D 10 の ShaderModel 4.0 からです。
それまでは使える命令や Constant 領域、レジスタ数、プログラムサイズ、
テクスチャ命令など様々な違いが残っていました。

Hardware の Unified Shader 化は ATI の Xbox360 GPU が先行しています。
これが今の Qualcomm Adreno に繋がっていきます。
その後一般の Desktop PC 向けにも NVIDIA GeForce 8800 (G80) が登場し、
以後 Unified Shader model が当たり前となっています。

OpenGL ES 2.0 の Shader 世代は Direct3D 9 の Shader Model 3.0 に相当
するのですが、Mobile GPU の多くはすでに Unified Shader です。
そのためあまり Vertex と Fragment Shader の機能差を意識する必要が
ありませんでした。

そんな中、Tegra2/3/4 は G70 ベースの GPU であり、Unified Shader 化する前の
制限が残っている珍しいケースとなっています。

コメントで Tegra の Fragment Shader は動的ループが使えないとの
指摘を頂いたので試してみました。

// (1) 動的ループ
int loop= int( uniform_value );
for( int i= 0 ; i < loop ; i++ ){
   ...
}

↑ループ回数を動的に求めた場合、Vertex Shader は通りますが
Fragment Shader ではコンパイル時にエラーが発生します。

以前書いたように Uniform 配列の index アクセス ↓(2) も
Tegra の Fragment Shader ではエラーとなります。
どちらも Direct3D 9 世代の制限と考えられます。

// (2) Uniform 配列
uniform vec4 src_color[30];
~
int index= int(tex_color.x);
vec4 color= src_color[ index ]; // Tegra の Fragment Shader では Error

Tegra 4 でも同様なので、大幅に機能拡張されていても GPU のベースは
同じであることがわかります。
なお Tegra と同じように Discrete Type の Shader Unit を備える
Mai-400MP では動きました。

	     Vertex Shader            Fragment Shader
	     動的Loop  Uniform配列    動的Loop  Uniform配列
-----------------------------------------------------------
Unified      ◯         ◯              ◯         ◯
Mali-400MP   ◯         ◯              ◯         ◯
Tegra2/3/4   ◯         ◯              ERROR     ERROR

ただし Tegra でも動的分岐はできるので、実行時にループ回数が変動する
場合でも同等の処理を実現することは可能です。

// (3) Tegra向け 動的分岐によるループ
for( int i= 0 ; i< 100 ; i++ ){
    if( i >= Loop ){
        break;
    }
    ~ 動的ループ相当
}

以下まとめ (いずれも Fragment Shader の場合)

コンパイル時にループ回数が定まらない場合はエラー。

// (4) ループ回数不定  -- Tegra で ERROR
for( int i= start ; i< end ; i++ ){
    ~
}

ループの範囲が決まっていればコンパイル可能。

// (5) 上限が決まってる場合 -- Tegra でも OK
for( int i= 0 ; i< 100 ; i++ ){
    if( i >= start && i < end ){
        ~ 動的ループ相当
    }
}

おそらく下記のように展開されているものと考えられます。

i= 0;
if( i >= start && i < end ){
    ~
}
i= 1;
if( i >= start && i < end ){
    ~
}

~

i= 99;
if( i >= start && i < end ){
    ~
}

Tegra K1 以降は ShaderModel 5.0 世代の GPU core になるので
このようなハードウエア的な制限はなくなるでしょう。

GPU 互換性など気軽に相談してください。


関連エントリ
OpenGL ES 2.0 Adreno 330, Tegra 4 の GPU 速度
OpenGL ES 2.0 で迷路シェーダー
GLSL互換性


C++ で開発していた OpenGL/OpenGL ES の Project を Emscripten でビルドしてみました。
Native Code 向けのプログラムがそのままブラウザ内で動いています。

・Windows Firefox (29.0.1)

Emscripten Windows

・Android Firefox (29.0.1)

Emscripten AndroidEmscripten Android + animation

Chrome では 7 fps 程度なので asm.js (Firefox) の効果は絶大でした。
Android でも十分な速度で動いています。

追記 2014/05/24: その後 Chrome でも 60fps 以上出るようになりました。詳しくはこちら

Windows 8.1 Firefox 29    60fps 以上   (Core i7-3615QM)
FireOS 3.0  Firefox 29    60fps 以上   (Kindle Fire HDX7 MSM8974)
Android 4.4 Firefox 29    34fps 前後   (Nexus 7 2013 APQ8064)

Windows 8.1 Chrome 34      7fps 前後   (Core i7-3615QM)
FireOS 3.0  Silk           3fps 前後   (Kindle Fire HDX7 MSM8974)
Android 4.4 Chrome 34      3fps 前後   (Nexus 7 2013 APQ8064)

・fps の値が大きい方が高速
・FireOS 3.0 = Android 4.2.2 相当

もともと OpenGL ES 2.0 / EGL に対応していたこともあり、
修正箇所はごく僅かで済んでいます。
使えなかった API は pthread だけで、
追加したのは Mouse/Touch/Keyboard などの Event 周りです。
Network (socket系) とサウンドは未着手。
ソースコード数は 600 file, 26万行ほど。

Native を想定して書いたコードが、拍子抜けするほどあっさりと
ブラウザ内で動いています。

以前から何度か NativeClient (NaCl) への対応化にも取り組んでいたのですが、
あまり本質的でない部分で躓いていました。
同期型 FileIO や Thread 周りといった API 制限だけでなく、
gcc (4.4) が古くて C++11 のコードが通らなかったためです。
その後確認したところ、ARM や pnacl では比較的新しいコンパイラに
置き換わってるようです。

今回使用した Emscripten では何も問題はなく Native 向け API もそのままです。
詳しい説明は次回。


● Emscripten

emscripten wiki

Android では Java, iOS では Objective-C が使われているように、
プラットフォームによってアプリケーション記述言語はまちまちです。
ただ多くの場合 C/C++ も併用できることが多く、
C/C++ 言語 + OpenGL ES 2.0 の組み合わせは、
移植性の高い共通言語&API としての役割も担っています。
主にゲームで。

Web Browser も OpenGL ES 2.0 (WebGL) に対応しており、
NativeClient (NaCl) や Emscripten といった C/C++ のコードを
走らせる仕組みも登場しています。
C/C++ が使えるようになったことで、同じソースコードのまま
さらに多くの環境にアプリケーションを移植できるようになりました。

NaCl はコンパイルしたバイナリをブラウザ内で走らせますが、
Emscripten は仮想マシンとして JavaScript を利用しています。
ポインタを駆使した C Native なコードが JavaScript に変換されると聞いても
少々奇妙な印象を受けるかもしれません。
しかしながら JavaScript の性能向上は著しく、モバイル含めて
十分な速度で動いているこれらの結果にはやはり驚きを隠せません。


速度比較

1. 960x640 63万Tri/191万Vertices, 一部 Bone Animation あり

CPU                  GPU            OS           Browser      fps
------------------------------------------------------------------------
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Win+OpenGL  100fps 前後
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Firefox      60fps 以上*1
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Chrome        7fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  X11+OpenGL    8fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  Firefox       5fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  Chrome         動作せず
Kabini Athlon5350    GeForce GTX650 Ubuntu14.04  X11+OpenGL  880fps 前後
Kabini Athlon5350    GeForce GTX650 Ubuntu14.04  Firefox      30fps 前後
Kabini Athlon5350    GeForce GTX650 Ubuntu14.04  Chrome        4fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   NDK+ES3.0    50fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Firefox      34fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Chrome        3fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   NDK+ES3.0    60fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   Firefox       8fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   Chrome         動作せず
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Firefox      60fps 以上*1
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Silk           fps 前後

・fps の値が大きい方が高速
・*1 : VSyncの上限
・Firefox 29, Chrome 34
・FireOS 3.0 = Android 4.2.2 相当
・APQ8064 = Nexus 7(2013), Exynos5D = Nexus 10, MSM8974 = Kindle Fire HDX7

2. 960x640 63万Tri/191万Vertices

CPU                  GPU            OS           Browser      fps
------------------------------------------------------------------------
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Win+OpenGL  110fps 前後
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Firefox      60fps 以上*1
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Chrome       10fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  X11+OpenGL    8fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  Firefox       5fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  Chrome         動作せず
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  X11+OpenGL  900fps 前後
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  Firefox      30fps 前後
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  Chrome        6fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   NDK+ES3.0    50fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Firefox      30fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Chrome        5fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   NDK+ES3.0    60fps 以上*1
Exynos5D Cortex-A15  Mali-T604      Android4.4   Firefox       8fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   Chrome         動作せず
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Firefox      60fps 以上*1
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Silk          5fps 前後

・fps の値が大きい方が高速

3. 960x640 6万Tri/19万Vertices

CPU                  GPU            OS           Browser      fps
------------------------------------------------------------------------
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Win+OpenGL  520fps 前後
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Firefox      60fps 以上*1
Ivy Core i7-3615QM   Intel HD 4000  Win8.1 x64   Chrome       15fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  X11+OpenGL   60fps 以上*1
BayTrail-D J1900     Intel HD       Ubuntu14.04  Firefox       5fps 前後
BayTrail-D J1900     Intel HD       Ubuntu14.04  Chrome         動作せず
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  X11+OpenGL 1020fps 前後
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  Firefox      38fps 前後
Kabini Athlon 5350   GeForce GTX650 Ubuntu14.04  Chrome        9fps 前後
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   NDK+ES3.0    60fps 以上*1
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Firefox      60fps 以上*1
APQ8064 Krait 1.5GHz Adreno 320     Android4.4   Chrome        8fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   NDK+ES3.0    60fps 以上*1
Exynos5D Cortex-A15  Mali-T604      Android4.4   Firefox       9fps 前後
Exynos5D Cortex-A15  Mali-T604      Android4.4   Chrome         動作せず
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Firefox      60fps 以上*1
MSM8974 Krait 400    Adreno 330     FireOS 3.0   Silk          8fps 前後

・fps の値が大きい方が高速

描画負荷を変えても速度が大きく変わらないものは CPU (JavaScript) 側の
限界と思われます。
Chrome, BayTrail-D, Kabini, Exynos 5D(Nexus10) が相当します。
また Native との差が少ないものは GPU 側も上限に近いことを意味しています。

Animation ありの場合骨の計算分 JS の負担が増えます。(頂点blendは GPU)
GPU に余裕があるのに 1. と 2. で大きく差が生じる場合は、
JavaScript の演算能力にも余裕がないことを示しています。

BayTrail-D は描画と CPU (JS) 両方共限界に達しているようです。
Native (X11+OpenGL) の 1./2. のテストでは、画面拡大時に速度が上がり、
オブジェクトが画面に全体が収まる場合は Firefox に近い速度まで下がります。
おそらく頂点性能が足りていないと思われます。

また同時に BayTraild の Firefox では拡大しても速度が上がらず一定なので、
JavaScript の動作速度も制限となっていることがわかります。
倍精度浮動小数点演算が苦手なことも影響しているかもしれません。

Kabini は外付けの GeForce がオーバースペック過ぎて CPU が追いついていません。
CPU (JS) 自体は BayTrail よりはかなり速いようです。

Android の Native (NDK+ES) は Fullscreen 動作となり、1920x1200, 2560x1600 で
レンダリングしているため他と条件が異なっています。

JavaScript の動作は Cortex-A15 よりも Krait/Krait 400 の方が高速でした。
Krait (APQ8064) は 3. のテストで制限がかかっていないため、
JavaScript 自体は余裕があるものの GPU で落ちているようです。
GPU の演算能力に余裕がある Krait 400 (MSM8974) はどのテストでも 60fps
超えています。

Desktop の Kabini よりも Krait/Krait 400 の方が JavaScript の
動作速度が速いこともわかります。

Cortex-A15 の速度が全然出ていませんが、VFP Benchmark の結果でも
倍精度演算は Krait の方が良い結果を出しています。
ただそれ以上に大きく差が開いているので、他にも何らかの要因があるのでは
ないかと思われます。

同じ Cortex-A15 のTegra Note 7 (Tegra4) でも試したかったのですが
RAM 容量が足りず動きませんでした。
今のところ Android + Firefox の組み合わせは RAM 2GB でぎりぎりです。
まだビルドを通したばかりでプロジェクトが巨大なせいもあります。


● まとめ

・Emscripten で C/C++ と OpenGL ES 2.0 のコードがブラウザ上でそのまま走る
・Firefox なら速度も速い (asm.js のおかげ)
・Android でも Firefox + Krait は高速動作 (Cortex-A15 が遅い原因は不明)

追記 (2014/05/20) : Tegra4 (Cortex-A15) では高速に動作することを確認しました

追記 (2014/05/24) : Chrome で速度が遅かった原因がわかりました。修正により 60fps 以上出ています。

続きます:「Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (2)」


関連エントリ
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす 一覧



iPad2 を iOS5 にアップデートしたら 3D の描画性能が大幅に向上しました。
テスト内容は前回までと同じです。

iPad2 ( A5 : PowerVR SGX543MP2 )

(1) light 3 + shadow map
------------------------------------
iOS 5    15.81 fps      13.0Mpix/sec
iOS 4    11.83 fps      12.4Mpix/sec


(2) light 3
------------------------------------
iOS 5    20.67 fps      16.3Mpix/sec
iOS 4    15.27 fps      12.0Mpix/sec


(3) light 1
------------------------------------
iOS 5    57.04 fps      44.9Mpix/sec
iOS 4    45.49 fps      35.8Mpix/sec

iOS5 では 15fps → 20fps 、 45fps → 57fps とスコアが伸びています。

iOS5 ではドライバレベルで大きく手が加えられているようです。

まず OpenGL が返す Extension List が増えています。
Extension の中身は下記のページに追加しました。

Mobile CPU/GPU の詳細 OpenGL Extension など

さらにレンダリング可能な解像度と最大テクスチャサイズも 2048 から 4096 へと
拡張されました。

iOS4 までは互換性重視なのか PowerVR SGX535 と全く同じ値を返していました。
iOS5 でやっと PowerVR SGX543MP 本来の能力を引き出せるようになったのかもしれません。

速度に大きな差があることから、シェーダーコンパイラの最適化がより進んだ
可能性があります。

残念ながら PowerVR SGX535 搭載の iPod tpuch3/4 では iOS5 に更新しても
速度は変わりませんでした。


今までのテスト結果を下記のページにまとめました。

Mobile GPU 速度比較のまとめ

シェーダー負荷が小さいケースではおそらく PowerVR SGX543MP2 の圧勝です。
重いシェーダーでは Mali-400MP, Adreno 220 に届きませんが差は縮まっています。
やはりこの 3 GPU が現段階での最速候補のようです。


関連エントリ
さらに OpenGL ES 2.0 Mobile GPU速度比較
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)


iPad 4 のベンチマークスコアを追加しました。
Apple A6X の GPU はこれまでの PowerVR SGX543 とは別のもので、
PowerVR SGX554 でした。
同じ 4 core でも性能的に公称 2倍。
実際のベンチマークでも 2~3 倍の速度が出ています。

Mobile GPU bench mark

Retina で Pixel 数が 4倍もあるにもかかわらず、
実際の動作速度で iPad 2 を超えているケースも少なくありません。
描画だけでなく CPU core 自体も大きく高速化されており、
システム全体として非常にパワフルになった印象です。

特に PowerVR SGX554 はシェーダーの演算能力自体が上がっているようで、
これまで苦手としてきたシェーダー負荷が高いケースでもきちんと速度
出るようになっています。

間違いなく現時点では最速に分類され、
Retina や Mobile GPU であることを言い訳にできなくなっています。
ただし今のところ Extension に違いはなく、PVRTC2 や OpenGL ES 3.0
に向けた新しいフューチャーに対応しているかどうかは不明です。

今年になって CPU core も GPU core も世代交代が進んでいます。
A6, Krait, Cortex-A15 といった CPU core だけでなく、
Adreno 320, Mali-T604 等 OpenGL ES 3.0 世代の GPU も揃って来ました。
あとは OS や SDK の対応を待つばかりです。

OS の対応が始まれば世代交代はさらに早まるものと考えられます。


関連エントリ
iPhone 5 / iPod touch 5 の GPU 速度
iPad 3 PowerVR SGX543MP4 の速度


CPU の結果も追加しました。
今回から CPU もグループごとに速い順に並び替えています。

CPU benchmark

GPU に iPad mini も追加しました。

Mobile GPU bench mark

CPU/GPU ともに刷新された A6X が最速です。
GPU はより上位のプロセッサに置き換わってますがまだ同世代。
CPU と同じようにそろそろ次のアーキテクチャが出てきても
良いのではないでしょうか。

CPU では iPad mini の方が iPod touch 5 より速いですが
GHz あたりの演算速度ではほぼ同一の値です。
同じ A5 であることがわかります。


関連エントリ
iPad 4 Apple A6X GPU PowerVR SGX554 MP4 の速度
iPhone 5 / iPod touch 5 の GPU 速度
iPad 3 PowerVR SGX543MP4 の速度


NetWalker は OpenGL ES 2.0 テスト機として活躍しています。
解像度が高いのでフルスクリーンだと遅いけどシェーダーもきちんと動くし、
コンパイルは遅いけど自分でビルドできるのですっかり開発用になってしまいました。
GPU だけでなく ARM Cortex-A8 のテストにも良い感じで使えます。

NetWalker に使われている Freescale i.MX515 の GPU は AMD (ATI) Z430 です。
未確認ですが、おそらく Snapdragon 系 (QSD8250等) に使われているものと同じだと
思われます。ただし CPU core は同じ ARM v7 世代ですが異なるものです。

       NetWalker     iPhone 3GS    Nexus One他
       i.MX515        S5PC100       QSD8250 (Snapdragon)
GPU    ATI Z430      PVR SGX535     ATI Z430
CPU    Cortex-A8     Cortex-A8      Scorpion

どれも ARM v7 で OpenGL ES 2.0 対応です。
Cortex-A8 は VFP が低速なので、速度を優先する場合はたとえスカラーであっても
積極的に NEON 命令を用いる必要があります。(参考)
Scorpion の VFP/NEON の場合は、果たしてどのような特性を示すでしょうか。


ほぼ 2択となった Desktop と違い、Mobile 向け GPU はまだまだ種類が豊富です。
それぞれ GPU 毎に各社から OpenGL ES 2.0 Emulator が提供されているようです。
ARM 製, NVIDIA 製のものもありました。

AMD OpenGL ES Emulator
Imagination POWERVR Insider
ARM mali Developer Center OpenGL ES 2.0 Emualtor
NVIDIA Developer Zone Tegra 250 Developer SDK



関連エントリ
ARM Cortex-A8 の NEON と浮動小数演算最適化
OpenGL ES 2.0 Emulator
Direct3D Mobile と T-01A の Snapdragon


OpenGL の動きが活発です。
OpenGL 4.0/3.3 のリリースが今年の 3月。
早くも OpenGL 4.1 が出ました。

OpenGL Registry

NVIDIA のサイトにはすでに GeForce (Fermi) 系向けのドライバもあります。

NVIDIA OpenGL 4.1 driver

OpenGL は 3.x で徐々に新しい機能セットに移行し、従来との互換性は Profile
指定による互換モードで保っています。
互換性の枷がなくなったことで新機能への追従が容易になったのでしょう。
DirectX に比べて遅れていた機能面の取り込み速度が格段に早くなっています。
4.0 以降、Direct3D 11 との機能差はほぼなくなっているようです。

DirectX も細かな改良は定期的な DirectX SDK のリリースで続けられていますが、
世代の変化は OS の更新と同調する必要もあり、ここしばらく core には目立った
動きもありませんでした。
むしろ Game Console が D3D9 世代ということもあり、さらに XP の制限も
あったため、API が完全刷新された Direct3D 10 への移行すらあまり積極的に
進んでいない状況です。
その点 OpenGL の方が世代間を移行しやすいので、D3D10/D3D11 相当の機能は
OpenGL の方がより広く使われることになるかもしれません。


もう一つ OpenGL の勢いを決定づけた点がモバイル向け API OpenGL ES の存在です。
すでにモバイル向け 3D API の標準は OpenGL ES 2.0 だと断言して構わないでしょう。

DirectX Mobile は固定機能の D3D8 ベースから更新されておらず、
WindowsPhone 7 でも XNA を通したサブセットで、シェーダーどころかさらに機能
制限される形になりそうです。モバイル向け GPU も進化し続けていますが、
その可能性を引き出せる API にはならないようです。


モバイル開発との相互移植性の高さは OpenGL の魅力の一つです。
この点は十分認知されているようで OpenGL 4.1 ではさらに OpenGL ES 2.0 との
互換 Profile が追加されました。考えられるメリットは下記の通り。

・HW 機能の再現が不要なら Emulator 無しに GL core だけで動作確認できる
・相互移植のしやすさ、desktop 向け OpenGL ES 2.0 アプリの開発

これまでもデスクトップで動作する OpenGL ES 2.0 Emulator が各 GPU メーカー
から公開されています。それぞれ完成度が高く、アプリがすんなり動いていたので
このままリリースしてもいいのではないかと疑問をいだいていたのも事実。


● OpenGL の問題点や Direct3D との違い

すっかり OpenGL / OpenGL ES 2.0 を使う機会が多くなりました。
とはいえ D3D11 にも良い点がかなりあります。
今後それぞれ改良されていくものと思われます。
以下いくつか問題と感じていた点。


・コンパイラ互換性

DirectX は OS 間の互換性を保つことが出来ませんが、そのかわり GPU の違いは
かなり吸収してくれます。
特にシェーダーコンパイラは共通バイトコードが定義されており、どの GPU でも
MS 製の同じコンパイラでバイナリ化出来ます。

OpenGL の GLSL コンパイラは GPU ドライバ依存なので、言語仕様の小さな差異が
問題になることがあります。
同じ C++ 言語でも VC と gcc で違いがあるように、GPU メーカー毎に異なる
コンパイラが存在しているからです。


・エラーコード

Direct3D 10 以降のエラーメッセージに慣れていると OpenGL API のエラーコードに
戸惑います。GL_INVALID_ENUM 等の数種類のコードの使い回しなので、すぐに問題を
特定することが出来ません。慣れかもしれませんが、この点は Direct3D の方が
ずっと分かりやすいし親切だといえます。


・シェーダーコンパイル時間

GLSL はアプリケーション起動のたびに毎回コンパイルが必要でした。
OpenGL 4.1 ではシェーダーを独立してバイナリ化するための専用 API が追加
されているので、今後解決していくものと思われます。


・テクスチャ圧縮フォーマット

Direct3D で当たり前に使える DXT/BC のありがたみがよく分かります。


・スレッド対応

OpenGL の場合自分で工夫する必要あり。
Direct3D 11 が便利すぎたので。


関連エントリ
OpenGL 4.0 / OpenGL 3.3


oga at 23:57
IDEOS U8150-B も追加しました。
S21HT と違い IDEOS は ARMv6 世代で最初から Android です。

           Desire   ZenTouch2  ZiiO7    LuvPad   ODROID-S     S21HT     IDEOS
-----------------------------------------------------------------------------
Android      2.2       2.1       2.1       2.2       2.2        2.2       2.2
Processor QSD8250    i.MX51    ZMS-08   Tegra250  S5PC110  MSM7201A   MSM7225
CPU clock    1GHz    800MHz      1GHz   1GHz x2      1GHz    528MHz    600MHz
CPU Arch   ARMv7A    ARMv7A    ARMv7A    ARMv7A    ARMv7A   ARMv6TEJ  ARMv6TEJ
CPU       Scorpion  CortexA8  CortexA8  CortexA9  CortexA8 ARM1136EJ ARM1136EJ
FPU      VFP3,NEON VFP3,NEON VFP3,NEON     VFP3  VFP3,NEON      ---       ---
GPU      Adreno200  AMD Z430   ZMS-08   Tegra250 PVRSGX540 Adreno130      ---
GL ES         2.0       2.0       2.0       2.0       2.0       1.1       1.1
RAM         576MB     256MB?    512MB     512MB     512MB     192MB     256MB
Display   800x480   480x320   800x480  1024x600   480x320   640x480   320x240
-----------------------------------------------------------------------------
(1)Graph    28.16    225.21    395.79    293.48    517.90      9.38     21.34
(1)Float  2049.57    432.77    581.37   2816.16   1675.83    128.41    290.60
(1)Memory  339.03    183.67    721.17    516.18    680.16    116.95    153.40
(2)CPU      759ms    1207ms    1038ms     436ms     719ms    4698ms    2971ms
(3)GPU Abs  14633     22071       ---       ---       ---       ---       ---
(3)GPU Rel  11587     26300       ---       ---       ---       ---       ---
(4)Quadrant  1259       979      1995      1827      1040       434       ---
(5)Linpack  32.82      5.66      5.97     36.71     14.03      1.98      3.78
-----------------------------------------------------------------------------
* 値が大きいほうが速い, (2) のみ値が小さいほうが速い

MSM7225 の CPU core は MSM7201A とほぼ同等だと思っていましたが予想よりも
高い数値が出ています。動作周波数も 528MHz ではなく 600MHz でした。
それでも ARMv7 世代とは比べ物にならず、VFP がないこともあって数倍から
一桁程度の差が付いています。

ただ処理速度と体感的な速度は全くの別物で、パネルの反応や追従性の方が
大きく影響します。
プロセッサは最速だけどタッチに反応しないことがある LuvPad よりも、
遅いはずなのにきちんと操作に反応する IDEOS の方がずっと好印象なのは
面白いところです。

MSM7225 は GPU として 3D アクセラレータが搭載されておらず、
OpenGL ES の API は CPU によるエミュレーションが行われているようです。

ラスタライズはパースペクティブ補正がかからずテクスチャマップが歪みフィルタもなし。
Depth は 16bit のみで Stencil 無しです。
GPU 系のテストは動作しないものが多くなっています。
アプリによってはそこそこ 3D が動くのは解像度が低いせいかもしれません。

比べると S21HT (TouchDiamond) の MSM7201A は解像度が高く非常に遅いものの
GL の描画は正しく行われていました。3D GPU が機能していたことがわかります。


関連エントリ
各種 Android 端末のベンチマークテスト (2)
各種 Android 端末のベンチマークテスト


ベンチは走らせてませんが 3D 描画は速い。
今まで試した Android の中では最速でした。

GPU

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: Mali-400 MP
GL_VENDOR: ARM
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00

[GL_OES_texture_npot]
[GL_OES_compressed_ETC1_RGB8_texture]
[GL_OES_standard_derivatives]
[GL_OES_EGL_image]
[GL_OES_depth24]
[GL_ARM_rgba8]
[GL_ARM_mali_shader_binary]
[GL_OES_depth_texture]
[GL_OES_packed_depth_stencil]

API=0  Shader=100
pconst=1024 vconst=128 vin=16 vout=12 ptex=8 vtex=0 combotex=8 maxrender=4096 maxtexsize=4096 cubetexsize=1024 viewdims=4096

TextureFormat 1
tc[00]=8d64  GL_ETC1_RGB8_OES

Unified でなく unit が独立しているせいもあるかもしれませんが、
比較的長い pixel shader も意外なほど動きます。

その代わり extension は少な目です。

Mobile GPU の比較

float 系テクスチャや圧縮頂点フォーマットが無いようです。
また圧縮テクスチャが ETC1 だけに制限されるのも、他の GPU との
大きな違いとなっています。

今の Mobile GPU はそれぞれ何かしらのトレードオフがあり全部入りはありません。

例えば Adreno 200 は演算ユニットが高精度固定、Unified で頂点機能も豊富、
低帯域対策は TBR と ATITC。その代わり頂点キャッシュなし。
PVR SGX535 は TBDR + PVRTC で全体的なスループットが高いがシェーダーの
演算精度をどこまで落とせるかが最適化の要。
Tegra2 は TBR でない代わりに転送量削減で 16bit depth 固定など。

Mali-400MP はまた違った特徴を持っているようです。


● CPU

Cortex-A9 1.2GHz dual。iPad2 同様 neon ありです。
今まで触ったハードで A9 neon 無しは Tegra2 だけでした。

Processor	: ARMv7 Processor rev 1 (v7l)
processor	: 0
BogoMIPS	: 1592.52

processor	: 1
BogoMIPS	: 1592.52

Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 1

モバイルでの 3D ゲームも現実的なレベルだと思います。
デスクトップ GPU との差はまだまだですが、意外にすぐ追いつかれるかも
しれません。


関連エントリ
iPad2 A5 と浮動小数演算 VFP/NEON
Android OpenGL ES 2.0 の圧縮テクスチャ
Tegra2 Cortex-A9 と浮動小数演算
Snapdragon と浮動小数演算速度


HTC EVO 3D の 3D 描画能力のテスト。
第三世代の Snapdragon で、Adreno 220 を搭載しています。
以前の比較とはシェーダーが多少違います。

Mali-400MP 800×480 : 56fps  (20.5Mpix/sec)  Exynos 4210 S5PC210 1.2GHz
Adreno 220 960×540 : 39fps  (19.4Mpix/sec)  Snapdragon MSM8660 1.2GHz

背景+複数キャラクタ+ライティング+Shadow map あり。
画面サイズが違うので単純には比較できませんが、秒間のピクセル数に
変換しても Mali-400MP には及びませんでした。

ただし Adreno は mobile GPU の中でも描画機能が非常に充実しており
ピクセルの演算精度も高くなっています。
第二世代の Adreno 205 (Snapdragon MSM8255 1GHz) 比では 2倍以上高速
なので十分良い数値と言えます。

以下は分岐を伴う、より複雑なライティングのシェーダーでのテスト。

Mali-400MP 800×480 : 19.6fps  (7.2Mpix/sec)
Adreno 220 960×540 : 13.7fps  (6.8Mpix/sec)

下記ページにも追加しています。
OpenGL ES 2.0 Mobile GPU 比較
Mobile GPU Extension


関連エントリ
OpenGL ES 2.0 shader の演算精度
Android Galaxy S2 ARM Mali-400 MP は速い (2)


テクスチャ負荷が高いケースでのテスト

GPU             fps       display pix/sec
--------------------------------------------------
Adreno 220      28.88fps  960x540  15.0M
Mali-400MP      20.08fps  800x480   7.7M  
ULP GeForce(8)   4.37fps 1280x752   4.2M  (Tegra250)
PVR SGX543MP2   20.65fps 1024x768  16.2M
PVR SGX535       8.70fps  480x320   1.3M

背景データ
 ・170000 ポリゴン
 ・1024x1024 カラーテクスチャ 5枚
 ・2048x2048 非圧縮ノーマルマップ 2枚
 ・ライティングあり(directional x2 + point x1)

キャラクタ
 ・10000ポリゴン前後 x5 (animation あり)
 ・ColorMap + NormalMap + SpecularMap
 ・ライティングあり(directional x2 + point x1)

背景の normal map は非圧縮 mip 無しで 1枚 12MByte もあります。
それでも Adreno 220/PVR SGX543MP2 はよくこの速度で動いています。

Color Texture の一部は alpha が入っており、
ETC1 しか使えない Mali-400MP では圧縮できませんでした。
このあたりが速度に影響しているかもしれません。

                alpha無し      alpha 1bit     alpha
---------------------------------------------------------
Mali-400MP      ETC1  4bpp     非圧縮         非圧縮
Adreno 220      ATC   4bpp     ATCA  8bpp     ATCI  8bpp
ULP GeForce     DXT1  4bpp     DXT1  4bpp     DXT5  8bpp
PVR SGX543MP2   PVRTC 4bpp     PVRTC 4bpp     PVRTC 4bpp

圧縮テクスチャ対応表

高負荷で長時間走らせていると端末も結構熱を持ちます。
Tablet は大丈夫ですが、うっかり雑誌の上においた EVO 3D が熱くなり
LED が点滅してました。


関連エントリ
頂点性能の比較 その2 (OpenGL ES 2.0 Mobile GPU)
OpenGL ES 2.0 Mobile GPU の頂点性能を比較する
A5 PowerVR SGX543MP2 は iOS 5 だと速い
さらに OpenGL ES 2.0 Mobile GPU速度比較
OpenGL ES 2.0 Mobile GPU速度比較 (dual core世代) 更新


Android 版 3DMark を手持ちのデバイスで試してみました。

Ice Storm (1280x720)

   SoC     GPU            Score Graph Physics GT1   GT2  PhysT Demo  OS
---------------------------------------------------------------------------
1: APQ8064 Adreno 320      9922 10061  9463  43.4  44.1  30.0  47.4  A4.1.1
2: MSM8660 Adreno 220      3167  4218  1692  19.2  17.6   5.4  19.0  A4.0.3
3: Tegra3  ULP GeForce(12) 3559  3143  6638  12.3  15.4  21.1  17.1  A4.2.2
4: Tegra2  ULP GeForce(8)  1448  1268  2878   5.5   5.5   9.1   6.4  A3.1

数値が大きい方が高速

スペック的に最新の Snapdragon APQ8064 (HTC J butterfly HTL21) がトップでした。

次に速いのは Tegra3 (Nexus7) ですが、よく見ると総合スコアは高いものの
Graphics score は MSM8660 の Adreno 220 に負けていることがわかります。

MSM8660 の CPU は Dual core 、Tegra3 は Quad core なので
Graphics で負けている分を Physics の CPU 速度で挽回した形になります。
Tegra らしい結果といえるかもしれません。


ここで気になるのは、Physics score で Scorpion 1.2GHz dual core の MSM8660 が
Cortex-A9 1.0GHz dual core の Tegra2 にも負けていることです。

Tegra2 は NEON を搭載していないので、浮動小数点演算のピークパフォーマンスが
1/2 ~ 1/4 と低いはずなのですが、他の CPU と大きな差がついていません。
Tegra2 のスコアを core 数で 2倍、クロック数で 1.2 倍すると
2878 * 2 * 1.2 = 6907

Tegra3 のスコア 6638 に近い数値となります。
演算性能だけ考えると NEON の分だけ差が開いてもよさそうなので、
NEON があまり活用されていないか、またはバス速度や描画など演算速度以外に
ボトルネックが存在している可能性があります。

それでも Scorpion のスコアは少々低すぎる気がします。


APQ8064 の Krait は十分速いですが、世代的にはもう少し数値が伸びても
良いのではないかと思いました。

下記のページでは Nexus 10 のスコアが掲載されています。
興味深いので一部引用させて頂きます。

4gamer: Futuremark,「3DMark」のAndroid版を発表。スマートフォン・タブレット8機種でテストしてみた

        SoC      GPU      Score Graph Physics GT1   GT2  PhysT Demo  OS
---------------------------------------------------------------------------
Nexus10 Exynos5D Mali-T604 5072  4567  8287  18.3  27.4   8.7  20.6  A4.2.2

Graphics 性能自体はあまり高くないですが、Physics のスコアが非常に伸びています。
Cortex-A15 1.7GHz dual core でこの数値なので、同クロックで比べても
Cortex-A9 の倍近くとなり、現行 Krait でも届きません。

Tegra4 や Exynos 5 Octa など、Cortex-A15 の Quad core が出たら
CPU 最速で間違いないでしょう。

もちろん Qualcomm も Krait 400 ではスコアが伸びていると思われます。


以下 Extream の結果

Ice Storm Extream (1920x1080)

   SoC     GPU            Score Graph Physics GT1   GT2  PhysT Demo  OS
---------------------------------------------------------------------------
1: APQ8064 Adreno 320 1.5  6133  5479 10530  26.8  21.4  33.4  23.9  A4.1.1
2: MSM8660 Adreno 220        --    --    --    --    --    --    --  A4.0.3
3: Tegra3  ULP GeForce(12) 1884  1574  6054   7.3   6.4  19.2   7.1  A4.2.2
4: Tegra2  ULP GeForce(8)   722   597  2721   3.1   2.2   8.6   2.6  A3.1

数値が大きい方が高速

HTC EVO 3D ISW12HT (Snapdragon MSM8660) では Ice Storm Extream が動きませんでした。

テストしたデバイスの詳細は下記の通り

   Name                  SoC       CPU       Clock core  GPU
-------------------------------------------------------------------------
1= HTC J butterfly HTL21 APQ8064   Krait     1.5GHz x4   Adreno 320
2= HTC EVO 3D ISW12HT    MSM8660   Scorpion  1.2GHz x2   Adreno 220
3= Nexus 7               Tegra3    Cortex-A9 1.2GHz x4   ULP GeForce(12)
4= OptimusPad L-06C      Tegra2    Cortex-A9 1.0GHz x2   ULP GeForce(8)


関連ページ
Mobile GPU bench mark
CPU benchmark

関連エントリ
Silicon Studio MOBILE GPUMARK のスコア比較


新しい iPod touch 6 は iPhone 4S 相当から 2世代飛んで一気に iPhone 6 世代へ移行しています。最も安価な iOS Device の底上げが行われました。

CPU SoC iPhone iPod iPad iPad mini
Cortex-A9 A5 iPhone 4S iPod touch 5 iPad2/iPad3 mini
Swift A6 iPhone 5/5c -- iPad4 --
Cyclone A7 iPhone 5s -- iPad Air mini2/mini3
Cyclone2 A8 iPhone 6/6p iPod touch 6 iPad Air2 --

GPU も一番新しい PowerVR Series 6XT の世代へ。

GPU PVR iPhone iPod iPad iPad mini
SGX543/554 5XT iPhone 4S/5/5c iPod touch 5 iPad2/iPad3/iPad4 mini
G6430 6 iPhone 5s -- iPad Air mini2/mini3
GX6450/6850 6XT iPhone 6/6p iPod touch 6 iPad Air2 --

RAM 容量も一段上がっています。

RAM iPhone iPod iPad iPad mini
512MB iPhone 4S iPod touch 5 iPad2 mini
1GB iPhone 5/5c/5s/6/6p iPod touch 6 iPad3/iPad4/Air mini2/mini3
2GB -- -- iPad Air2 --

歴代 iOS Device との速度比較は下記の通りです。(vfpbenchmark)

Device SoC CPU Clock S-SP S-DP M-SP M-DP
iPad Air 2 A8X Cyclone2 x3 1.5GHz 23.568 11.751 68.591 33.968
iPhone 5s A7 Cyclone x2 1.3GHz 20.621 10.313 40.871 20.480
iPad mini 2 A7 Cyclone x2 1.3GHz 20.373 10.223 40.616 20.238
iPod touch 6 A8 Cyclone2 x2 1.1GHz 17.964 8.899 35.530 17.775
Mac mini 2009 Core 2 Duo x2 2.0GHz 15.916 6.365 31.662 12.724
iPad 4 A6X Swift x2 1.4GHz 10.855 1.818 21.502 3.573
iPhone 5 A6 Swift x2 1.3GHz 10.094 1.710 20.029 3.398
iPad 2 A5 Cortex-A9 x2 1.0GHz 3.960 0.989 7.830 1.961
iPad mini A5 Cortex-A9 x2 1.0GHz 3.846 0.983 7.800 1.941
iPad 3 A5X Cortex-A9 x2 1.0GHz 3.394 0.983 7.752 1.954
iPod touch 5 A5 Cortex-A9 x2 0.8GHz 3.161 0.790 6.203 1.565
iPod touch 4 A4 Cortex-A8 x1 0.8GHz 3.139 0.112 3.139 0.112

S-SP = Single Thread 単精度  (GFLOPS) いずれも数値が大きいほうが高速
S-DP = Single Thread 倍精度  (GFLOPS)
M-SP = Multi Thread 単精度  (GFLOPS)
M-DP = Multi Thread 倍精度  (GFLOPS)

浮動小数点演算のピーク値だけの比較なので実際のアプリケーションの速度とは異なります。ですが、浮動小数点演算の速度だけでも Apple の公称値である「CPU 速度で 6倍」に近い数値を得ることが出来ました。

M-SP: 35.5 (iPod touch 6) / 6.2 (iPod touch 5) = 5.7倍

また 32bit 世代 (A4~A6) と 64bit 世代 (A7/A8) の間に入る調度良い比較対象だったので Mac mini Early 2009 の結果も載せてみました。もちろん最新の Core i5/i7 には敵いません。Android や Desktop PC 含めた結果を下記に載せています。

VFP Benchmark Log

GPU は ASTC 対応で PowerVR Series6XT (iOS GPUFamily2) を確認。

GL_VERSION: OpenGL ES 3.0 Apple A8 GPU - 53.13
GL_RENDERER: Apple A8 GPU
GL_VENDOR: Apple Inc.
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00

Extension:
GL_OES_standard_derivatives
GL_KHR_texture_compression_astc_ldr
GL_EXT_color_buffer_half_float
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_pvrtc_sRGB
GL_EXT_read_format_bgra
GL_EXT_separate_shader_objects
GL_EXT_shader_framebuffer_fetch
GL_EXT_shader_texture_lod
GL_EXT_shadow_samplers
GL_EXT_texture_filter_anisotropic
GL_APPLE_clip_distance
GL_APPLE_color_buffer_packed_float
GL_APPLE_copy_texture_levels
GL_APPLE_rgb_422
GL_APPLE_texture_format_BGRA8888
GL_IMG_read_format
GL_IMG_texture_compression_pvrtc

RAM は 1GB でした。

HW INFO: Machine = iPod7,1
HW INFO: Model = N102AP
HW INFO: Arch = N102AP
HW INFO: ByteOrder = 1234
HW INFO: NCPU = 2
HW INFO: MemSize = 1039306752
HW INFO: UserMem = 862314496
HW INFO: PageSize = 16384
HW INFO: VectorUnit = 0
HW INFO: Float = 0


関連エントリ
iPad Air 2 (Apple A8X) の浮動小数点演算能力
Android x86 Binary Translator を試してみる
iPhone 5s A7 CPU の浮動小数点演算速度 (2) (arm64/AArch64/64bit)
VFP Benchmark 関連


oga at 13:55
Jetson Nano Developer Kit を入手しました。Jetson Nano は Tegra X1 を搭載した SBC です。各種インターフェースを搭載した I/O ボードがセットになっています。そのため見た目は Raspberry Pi のような印象を受けますが、上に載ってる Compute Module のような小さいカードの方が本体です。

NVIDIA Jetson Nano

Nano は Jetson シリーズの中でも低価格で入手しやすくなっています。その代わり搭載されている Tegra X1 のアーキテクチャは少々古い世代のもので、GPU も GeForce でいえば 900 シリーズの Maxwell に相当します。また同じ X1 を使用している Jetson TX1 や SHILED TV (Android TV) よりも Shader Core 数が半減しています。公式ページに書かれている 472 GFLOPS は fp32 ではなく AI 向け fp16 のものです。

Tegra X1 Device CPU clock Shader GPU clock GPU fp32 GPU fp16
TX1/SHIELD TV A57 1.9GHz 256 sp 1000 MHz 512 GFLOPS 1024 GFLOPS
Jetson Nano A57 1.4GHz 128 sp 922 MHz 236 GFLOPS 472 GFLOPS

Tegra X1 には Cortex-A53 含めて CPU が 8 core 搭載されているのですが、過去の Tegra 同様省電力 core が見えない仕様のようです。8 core 同時稼働ができないため、実質 4 core 相当となっています。

Nano にはパフォーマンス重視の big core A57 が載っているので、同じ Quad core でも Little core のみだった Raspberry Pi 2/3 より CPU 性能は高くなります。ただし最近リリースされた Raspberry Pi 4 では big core (Coretex-A72) に置き換わったため、この点での優位性はなくなりました。

Device CPU core clock IA RAM 価格
Raspberry Pi 2(旧) Cortex-A7 Little 0.9 GHz ARMv7A 1GB $35
Raspberry Pi 2(新) Cortex-A53 Little 0.9 GHz ARMv8.0A 1GB $35
Raspberry Pi 3 Cortex-A53 Little 1.2 GHz ARMv8.0A 1GB $35
Raspberry Pi 3+ Cortex-A53 Little 1.4 GHz ARMv8.0A 1GB $35
Raspberry Pi 4 Cortex-A72 big 1.5 GHz ARMv8.0A 1-4GB $35-55
Jetson Nano DevKit Cortex-A57 big 1.4 GHz ARMv8.0A 4GB $99

似たようなボードのスペックをいくつかまとめてみました。より詳しい表は wiki の方に載せています。メモリ速度に結構違いがあります。

NPU/SBC

Device SoC CPU core clock RAM MEM B/W TPU/GPU
Jetson Nano Tegra X1 A57 x 4 1.4GHz 4GB 25.6GB/s 472 GF@fp16
Coral Dev Board NXPi.MX 8M A53 x 4 1.5GHz 1GB 12.8GB/s 4 TOPS@int
Raspberry Pi 4 BCM2711 A73 x 4 1.5GHz 4GB 9.6GB/s
Raspberry Pi 3+ BCM2837B0 A53 x 4 1.4GHz 1GB 3.6GB/s 28.8 GF@fp32
Dragonboard 410c Snapdragon410 A53 x 4 1.2GHz 1GB 4.2GB/s

OS は Ubuntu Desktop が用意されています。ARM で最初から GPU が有効なものはなかなか触れないので貴重です。OpenGL ES だけでなく OpenGL が使えますし、Vulkan、CUDA にも対応してます。

いつものように ARM 環境でコンパイル速度を調べようとしたのですが、clang の Version によって速度に違いがあることに気が付きました。あらためてデータを取り直してみました。clang の Version が上がるほどビルド速度が遅くなっているようです。

Device v3.5 v3.9 v4.0 v5.0 v6.0 v7.0 v8.0
PC Core i7-4790K -- -- -- -- 30 33 31
Pixel 3 SDM845 -- -- -- -- -- -- 35
Mac i7-3615QM -- -- -- -- -- 42 --
PC A10-7870K -- 64 69 70 74 79 69
Mac i5-3210M -- -- -- -- -- 98 --
ZenFone3 ZC553KL -- -- -- -- -- -- 97
Chromebook C101PA -- 96 95 -- -- -- --
Jetson Nano -- 108 113 113 118 125 121
PC Celeron J1900 -- 174 189 192 202 216 207
Chromebook 2955U -- 191 207 216 225 248 231
PC x7-Z8700 -- -- -- -- 274 304 297
Raspberry Pi 3B 148 194 -- -- 331 351 --
Raspberry Pi 2B 314 395 -- -- 752 820 --

・横軸は clang の Version。数値は秒で値が小さい方が高速。

Windows 上の WSL だと素の Linux より遅くなるため上の表からは除いてあります。wiki の方には WSL 含めたデータを載せています。ストレージ速度など、必ずしも条件が一定ではないので予めご了承ください。

Compile Benchmark

コンパイル時間は core 数や Thread 数が多い方が速くなります。Nano は 8 thread のハイエンドスマートフォンには敵いませんが、RAM も多いし big core なので Raspberry Pi 2/3 より数倍速く、Celeron (Atom) 搭載 PC と比べても半分近い時間でコンパイルが完了しています。

TensorFlow も普通に CUDA で動きます。PC と同じコードがそのまま走るので、メモリ容量の制限はあるものの学習も可能です。TensorFlow をソースからビルドしなおすことで、Python だけでなく C言語 API も使うことができました。


関連ページ
Compile Benchmark
Jetson Nano

関連エントリ
Snapdragon 835 と 845 のコンパイル時間の比較&浮動小数点演算能力
Snapdragon 845 の浮動小数点演算速度
ARM CPU 上の開発環境とコンパイル時間の比較 (2) Pixel 3/UserLAnd
ARM CPU 上の開発環境とコンパイル時間の比較
AMD CPU Ryzen とコンパイル時間の比較 (2)
AMD CPU Ryzen とコンパイル時間の比較
ARM CPU の浮動小数点演算能力まとめ


Direct3D の HLSL コンパイラは Microsoft が用意しており、共通のバイトコードを
生成しています。
実行時はさらにドライバが GPU 毎のネイティブコードに最適化&変換を行っています。

一見二度手間ですが、最初の最適化は共通バイトコードへの変換時に済んでいます。
時間のかかる巨大なシェーダーでも事前に変換しておくことが可能だし、コンパイラ部の
最適化の恩恵はすべての GPU で受けられます。
ドライバも共通コードからの変換だけ行えばよいので、互換性も比較的維持しやすいのでは
ないかと考えられます。

その代わり一度バイナリにしてしまうと、コンパイルした時点のコンパイラの能力である程度
固定されます。あとからコンパイラが強化される可能性もあるし、GPU が ShaderModel 5.0
対応になっても、3.0 向けにコンパイルしたシェーダーで能力を出し切れるとは限りません。


OpenGL の GLSL の場合 API が受け取るのは生のソースコードです。
コンパイルそのものが GPU ドライバの役目となっていて、中間の共通コードがありません。
動的にコンパイルするメリットは常にハードに最適なプロファイルを選べることです。

逆にデメリットとしては、コンパイル時間がかかるのではないかとの懸念もありますが
もっと別の問題もあるようです。
今まで GeForce で組み立ててきたコードを RADEON で走らせてみました。
環境は下記の通り。

GeForce 9800GT 190.62 (GL 3.1 GLSL 1.4) WHQL
GeForce GTX280 190.57 (GL 3.2 GLSL 1.5)
RADEON HD 4760 Catalyst 9.9 (GL 3.1 GLSL 1.4)


● Version 指定

RADEON の GLSL では「#version」はソースコードの先頭にないとエラーになります。

・#version の前にプリプロセッサ命令があるだけでもだめ。
・glShaderSource() に複数のソースコードを渡している場合、最初のコードの先頭でないとだめ。2番目以降のソースコードには記述できない。

この挙動は OpenGLES 2.0 の GLSL と同じです。また GLSLangSpec.Full.1.40.05.pdf
を見ても、#version の前に許されるのはコメントとホワイトスぺースのみと記載されています。
こちらの動作の方が正解でした。

ただプリプロセッサ命令も許されていないので、複数のターゲット間で互換性ととる場合に
version 指定を分岐できないのは不便です。C 言語側の Shader Loader 部分に手を加えて、
独自のプリプロセッサを追加するなどの対策が必要かもしれません。


● precision 指定

OpenGL ES の GLSL から取り入れた仕様として precision 指定があります。
宣言時に変数が必要とする精度のヒントを与えます。
highp, middlep, lowp の 3段階ありますが

・GeForce は in/out 宣言の前に必要
・RADEON は in/out 宣言の後ろ書かないとエラー

RADEON の場合必ず何らかの精度指定が必須で、個別指定かまたはデフォルトの
precision 行が必要です。GeForce は無くても通ります。
とりあえず最初にデフォルト宣言をしておけばどちらでも通ります。
細かく個別に宣言をしている場合は注意。

precision highp float;

ドキュメントを見る限り RADEON の方が正しいようです。
全体的に GeForce の方が判定が緩く RADEON の方が厳密になっています。


GPU のドライバ毎にコンパイラの仕様が異なっている可能性を考えると、
Direct3D + HLSL のように共通化されている方が楽だと思います。
慣れるまではこれらの互換性の維持に苦労しそうです。


●OpenGL 3.1

現段階で OpenGL 3.2/GLSL 1.5 に対応しているのは GeForce 190.57 だけです。
RADEON で試すにあたって OpenGL 3.1/GLSL 1.4 で動作するように修正しました。

GeForce の場合、最初に wglCreateContext() で作った Context がすでに
OpenGL 3.x に対応していました。
wglCreateContextAttribsARB() で作り直さなくても動作します。
RADEON の場合 OpenGL 2.1 だったので、wglCreateContextAttribsARB() が必要です。
でもシェーダーバージョンは同じ。

// GeForce 190.57
// wglCreateContext()
GL VERSION: 3.2.0
GL RENDERER: GeForce GTX 280/PCI/SSE2
GL VENDOR: NVIDIA Corporation
GL SHADING_LANGUAGE_VERSION: 1.50 NVIDIA via Cg compiler
 ↓
// wglCreateContextAttribsARB()
GL VERSION: 3.1.0
GL RENDERER: GeForce GTX 280/PCI/SSE2
GL VENDOR: NVIDIA Corporation
GL SHADING_LANGUAGE_VERSION: 1.40 NVIDIA via Cg compiler

// GeForce 190.62
// wglCreateContext()
GL_VERSION: 3.1.0
GL_RENDERER: GeForce 9800 GT/PCI/SSE2
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: 1.40 NVIDIA via Cg compiler
 ↓
// wglCreateContextAttribsARB()
GL_VERSION: 3.1.0
GL_RENDERER: GeForce 9800 GT/PCI/SSE2
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: 1.40 NVIDIA via Cg compiler


// RADEON 9.9
// wglCreateContext()
GL_VERSION: 2.1.8918
GL_RENDERER: ATI Radeon HD 4600 Series
GL_VENDOR: ATI Technologies Inc.
GL_SHADING_LANGUAGE_VERSION: 1.40
 ↓
// wglCreateContextAttribsARB()
GL_VERSION: 3.1.8918
GL_RENDERER: ATI Radeon HD 4600 Series
GL_VENDOR: ATI Technologies Inc.
GL_SHADING_LANGUAGE_VERSION: 1.40


● Extension の判定

GeForce 190.57 を Version 3.1 で作り直した場合のはまりです。
Extension の判定で glGetString( GL_EXTENSIONS ) を参照していましたが、
Context を作り直すとエラーになります。
ドキュメントをよく見ると glGetString( GL_EXTENSIONS ) は古い仕様で、
OpenGL 3.x の場合は

glGetIntegerv( GL_NUM_EXTENSIONS, .. )
glGetStringi( GL_EXTENSIONS, .. )

を用いるのが正しいやり方のようです。
WGL_CONTEXT_FLAGS_ARB を 0 にしても
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB がセットされてしまうことが
原因のようです。
190.62 では WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB を指定しない限り
大丈夫でした。


互換性周りはまだ慣れてないせいか、または出来るだけ共通で動かそうと欲張っている
せいか苦労しています。
Direct3D の場合問題になる互換性はハードウエア能力の差でした。
その後 Direct3D 10 では完全に足並みが揃って、GeForce も RADEON もほとんど
区別せずに同じシェーダーが動くようになっています。
OpenGL ではハードウエア能力の違いよりも、まだまだドライバの差が表面化している感じです。
API 仕様が決まっても、安定するまでしばらく時間がかかるのかもしれません。


関連エントリ
OpenGL の同期と描画速度の測定
OpenGL のはじめ方 (2) wgl
OpenGL 3.2 GeometryShader をもう少し使ってみる
OpenGL GLSL のバージョン
OpenGL 3.2 の GeometryShader
OpenGL のはじめ方


Cortex-A5 搭載 Android 端末 SXZ-PD10
(SHENZHEN LINK-CREATE TECHNOLOGY PD10 普及版)
を試してみました。
CPU や GPU のデータは下記ページにまとめています

CPU/GPU

以下抜粋です。

Processor       : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 415.33
Features        : swp half thumb fastmult vfp edsp thumbee neon vfpv3 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc05
CPU revision    : 1

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: Mali-400 MP
GL_VENDOR: ARM
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00

Cortex-A5 は vfpv4 ですが cpuinfo の Features では vfpv3。

ARM vfp の種類

上記のように SXZ-PD10 は Cortex-A5 1.2GHz + Mali-400 で
Android 4.0 が搭載されています。
実際にプログラムを走らせた結果は次のページにまとめています。

CPU benchmark

以下は部分的に抜き出したものです。

SoC / CPU                   MB/sec   T/GHz  device
------------------------------------------------------------------
MSM7225 ARM11        600MHz   6.99   11.65  IDEOS
JZ4770 XBurst1       1.0GHz  16.40   16.40  Novo7 Paladin
TCC8923 Cortex-A5    1.2GHz  18.42   15.35  SXZ-PD10
MSM8255 Scorpion     1.0GHz  24.82   24.82  Xperia ray SC-03C  
Tegra2 Cortex-A9     1.0GHz  25.11   25.11  OptimusPad L-06C
Atom Z540            1.86GHz 30.44   16.37  VAIO Type P VGN-P90S
Exynos4210 Cortex-A9 1.2GHz  33.42   27.85  Galaxy S2 SC-02C
Tegra3 Cortex-A9     1.3GHz  36.15   25.82  EeePad TF201
APQ8060 Scorpion     1.5GHz  42.64   28.43  Galaxy Tab SC-01D

MB/sec の数値が大きい方が速い。
整数演算のみ。single thread (single core) のみ。
・MB/sec = 1秒あたりの変換byte数
・T/GHz  = MB/sec を CPU 1GHz あたりの速度に変換したもの

single thread のテストなので Multi core CPU や HT 対応 CPU でも
1 thread 分の速度なので注意してください。

Cortex-A5 は同時に実行できる命令数が半分なので、上位の CPU より
遅くなっています。

ところがこの Cortex-A5 には vfpv4 + neon が搭載されており、
浮動小数点演算ではかなり高速であることがわかりました。

CPU bench FPU

Linpack 1.2.8

Single  Multi
MFLOPS  MFLOPS  Soc/CPU
-------------------------------------------------------------------
18.091          Cortex-A8     1.0GHz  S5PC110    Galaxy S SC-02B
18.684          MIPS XBurst1  1.0GHz  JZ4770     Novo7 Paladin
25.732          Cortex-A5     1.2GHz  TCC8923    SXZ-PD10
35.628          Scorpion      1.0GHz  QSD8250    Desire X06HT
31.142  57.331  Cortex-A9 x2  1.0GHz  Tegra2     OptimusPad L-06C
46.164  74.664  Scorpion  x2  1.2GHz  MSM8660    EVO 3D ISW12HT
56.076  89.860  Scorpion  x2  1.5GHz  APQ8060    Galaxy Tab SC-01D
57.342  92.981  Cortex-A9 x2  1.2GHz  Exynos4210 Galaxy S2 SC-02C
47.071 140.908  Cortex-A9 x4  1.3GHz  Tegra3     EeePad TF201

MFLOPS の数値が大きいほうが速い


                          Render                  NDK    VFP  NEON
CPU                       Script   Java  Java2    C++    asm   asm
--------------------------------------------------------------------
JZ4770   XBurst1 1.0GHz     289     479  11736    158     -      -
TCC8923  Cortex-A5 1.2GHz    67     295   6798     57    35     23
S5PC110  Cortex-A8 1.0GHz     -     698   1012    166   139     20
Tegra 2  Cortex-A9 1.0GHz    50     243   1219     75    46      -
Tegra 3  Cortex-A9 1.3GHz    38     172   3634     42    35     34
APQ8060  Scorpion 1.5GHz      -     279   1758     43    26     26

単位は実行時間(ms)、数値が小さいほうが速い。

Cortex-A8 のように vfp で遅くなることもなく、vfp/neon 共に高速に
実行できています。

GPU の結果は下記ページに追加しています。

Mobile GPU bench mark


関連エントリ
2012/02/15 Android 4.0 MIPS で RenderScript, ainol Novo 7 Paladin の浮動小数点演算速度
2012/01/14 Android 4.0 RenderScript Compute の速度 その2
2011/11/07 Android 3.x RenderScript (7) RenderScript Compute の速度


Emscripten の OpenGL API には 3 つの動作モードがあります。

(1) defaut (WebGL-friendly subset of OpenGL)
(2) -s FULL_ES2=1 (OpenGL ES 2.0 emulation)
(3) -s LEGACY_GL_EMULATION=1 (OpenGL emulation of older desktop and mobile versions)

(1) は WebGL 命令をほぼそのまま OpenGL ES 2.0 API にコンバートしたものです。

(2) は (1) に加えて OpenGL ES 2.0 の足りない機能を補っています。
WebGL は VertexBuffer を経由しない描画をサポートしていないためです。

(3) は WebGL 上で OpenGL 1.x の固定パイプラインをエミュレートしています。
各種レンダーステートにより、動的にシェーダーの生成も行っているようです。

通常は (1) のままで十分ですが、もし正しく描画されない要素がある場合は
(2) を試すことが可能です。
具体的には glVertexAttribPointer() や glDrawElements() の最後の引数に、
直接データのポインタを渡している場合が相当します。
もともと GPU Hardware 的にも望ましくない機能であること、
また Emscripten でのエミュレーションもオーバーヘッドが生じるため
Client Side Arrays は出来る限り使わないことが推奨されています。


GPU/Browser 毎の Extension

前回のデータを Android 端末含めてさらに集めてみました。
詳細は下記ページへ

WebGL Extensions (Emscripten)

テクスチャ

                                   TS RTS CTex Depth ANI Float Half
W8  Intel HD G 4000   Firefox 29   8K  8K  DXT   Y    Y   Y-L   Y
W8  Intel HD G 4000   Chrome 35    8K  8K  DXT   Y    Y   Y-L   Y-L
W8  Intel HD G 4000   IE 11       16K 16K  DXT   N    Y   Y-L   N
W8  RADEON HD 6750M   Firefox 29  16K 16K  DXT   Y    Y   Y-L   Y
W8  RADEON HD 6750M   Chrome 35   16K 16K  DXT   Y    Y   Y-L   Y-L
W8  RADEON HD 6750M   IE 11       16K 16K  DXT   N    N   Y-L   N
W7  GeForce GTX650    Firefox 29  16K 16K  DXT   Y    Y   Y-L   Y
W7  GeForce GTX650    Chrome 35   16K 16K  DXT   Y    Y   Y-L   Y-L
W7  GeForce GTX650    IE 11       16K 16K  DXT   N    N   Y-L   N
OSX RADEON HD 6750M   Firefox 29  16K 16K  DXT   Y    Y   Y-L   Y
OSX RADEON HD 6750M   Chrome 35    4K 16K  DXT   Y    Y   Y-L   Y-L
OSX RADEON HD 6750M   Safari 7    16K 16K  DXT   Y    Y   Y     N
OSX Intel HD G 4000   Firefox 29   4K  4K  DXT   Y    Y   Y-L   Y
OSX Intel HD G 4000   Chrome 35    4K 16K  DXT   Y    Y   Y-L   Y-L
OSX Intel HD G 4000   Safari 7    16K 16K  DXT   Y    Y   Y     N
U14 RADEON HD 6750M   Firefox 29  16K 16K  DXT   Y    Y   Y-L   Y
U14 RADEON HD 6750M   Chrome 35   16K 16K  DXT   Y    Y   Y-L   Y-L
U14 RADEON R3         Firefox 29  16K 16K  DXT   Y    Y   Y-L   Y
U14 RADEON R3         Chrome 35   16K 16K  DXT   Y    Y   Y-L   Y-L
U14 Intel HD G        Firefox 29   8K  8K  DXT   Y    Y   Y-L   Y

                                   TS RTS CTex Depth ANI Float Half
A42 S80 Adreno 330    Firefox 29   4K  4K  ATC   Y    Y   Y     Y
A42 S80 Adreno 330    Chrome 35    4K  4K  ---   N    Y   Y     Y-L
A44 S4P Adreno 320    Firefox 29   4K  4K  ATC   Y    Y   Y     Y
A44 S4P Adreno 320    Chrome 35    4K  4K  ---   N    Y   Y     Y-L
A44 T4  ULP GeForce72 Firefox 29   4K  4K  DXT   N    Y   N     Y
A44 T4  ULP GeForce72 Chrome 35    4K  4K  DXT   N    Y   N     Y-L
A44 E5  Mali-T604     Firefox 29   8K  8K  ---   Y    N   Y-L   Y
A41 K3  VivanteGC4000 Firefox 29   8K  8K  ---   Y    Y   Y     Y
A44 T3  ULP GeForce12 Firefox 29   2K  2K  DXT   N    Y   N     Y
A44 T3  ULP GeForce12 Chrome 35    2K  2K  DXT   N    Y   N     Y
A42 OM4 PVR SGX540    Firefox 29   2K  2K  PVR   Y    N   Y     Y
A41 R66 Mali-400MP4   Firefox 29   4K  4K  ---   Y    N   N     N
A40 S3  Adreno 220    Firefox 29   4K  4K  ATC   Y    Y   Y     Y
A23 S2  Adreno 205    Firefox 29   4K  4K  ATC   Y    Y   Y     Y

TS   = GL_MAX_TEXTURE_SIZE
RTS  = GL_MAX_RENDERBUFFER_SIZE
CTex = 対応している圧縮テクスチャフォーマット
Depth= WEBGL_depth_texture
ANI  = EXT_texture_filter_anisotropic
Float= OES_texture_float (Y-L は OES_texture_float_linear)
Half = OES_texture_half_float (Y-L は OES_texture_half_float_linear)

W8=Windows8.1, W7=Windows7, OSX=10.9, U14=Ubuntu14.04, A44= Android 4.4

圧縮テクスチャは、Desktop では 100% DXT1~DXT5 (S3TC) が利用可能となっています。
Android は通常の OpenGL ES 2.0 と同じく GPU によって DXT/ATC/PVR とばらばら。
Android が共通でサポートしているはずの ETC1 が列挙されていませんが、
本当に使えないのかどうかは未確認。

DXT に対応しているはずの Vivante GC4000 が未対応となっているのは、
ブラウザの WebGL Layer が GL_COMPRESSED_TEXTURE_FORMSTS ではなく、
GL_EXTENSIONS だけチェックしているからではないかと思われます。

テクスチャ以外

                                   Uniform  In/Out EInt VAO Ins DB sRGB
W8  Intel HD G 4000   Firefox 29   254/ 221 16/10   Y    N   N   N   N
W8  Intel HD G 4000   Chrome 35    254/ 221 16/10   Y    Y   Y   N   N
W8  Intel HD G 4000   IE 11        512/ 512 16/14   N    N   N   N   N
W8  RADEON HD 6750M   Firefox 29   254/ 221 16/10   Y    N   N   N   N
W8  RADEON HD 6750M   Chrome 35    254/ 221 16/10   Y    Y   Y   N   N
W8  RADEON HD 6750M   IE 11        512/ 512 16/14   N    N   N   N   N
W7  GeForce GTX650    Firefox 29   254/ 221 16/10   Y    N   N   N   N
W7  GeForce GTX650    Chrome 35    254/ 221 16/10   Y    Y   Y   N   N
W7  GeForce GTX650    IE 11        512/ 512 16/14   N    N   N   N   N
OSX RADEON HD 6750M   Firefox 29   768/ 768 16/16   Y    Y   N   Y   Y
OSX RADEON HD 6750M   Chrome 35    768/ 768 16/32   Y    Y   Y   Y   N
OSX RADEON HD 6750M   Safari 7     768/ 768 16/32   Y    Y   N   N   N
OSX Intel HD G 4000   Firefox 29  1024/1024 16/16   Y    Y   Y   Y   Y
OSX Intel HD G 4000   Chrome 35   1024/1024 16/15   Y    Y   Y   Y   N
OSX Intel HD G 4000   Safari 7    1024/1024 16/15   Y    Y   N   N   N
U14 RADEON HD 6750M   Firefox 29  4096/4096 29/32   Y    Y   Y   Y   Y
U14 RADEON HD 6750M   Chrome 35   4096/4096 29/32   Y    Y   Y   Y   N
U14 RADEON R3         Firefox 29   256/ 256 29/32   Y    Y   Y   Y   Y
U14 RADEON R3         Chrome 35    256/ 256 29/32   Y    Y   Y   Y   N
U14 Intel HD Graphics Firefox 29  4096/4096 16/32   Y    Y   Y   Y   Y

                                   Uniform  In/Out EInt VAO Ins DB sRGB
A42 S80 Adreno 330    Firefox 29   256/ 224 16/16   Y    Y   N   N   N
A42 S80 Adreno 330    Chrome 35    256/ 224 16/16   Y    Y   N   N   N
A44 S4P Adreno 320    Firefox 29   256/ 224 16/16   Y    Y   Y   Y   N
A44 S4P Adreno 320    Chrome 35    256/ 224 16/16   Y    Y   N   N   N
A44 T4  ULP GeForce72 Firefox 29   280/1024 16/15   N    Y   N   N   N
A44 T4  ULP GeForce72 Chrome 35    280/1024 16/15   N    Y   N   N   N
A44 E5  Mali-T604     Firefox 29  1024/1024 16/15   Y    Y   Y   Y   N
A41 K3  VivanteGC4000 Firefox 29   568/ 568 16/12   Y    N   N   N   N
A44 T3  ULP GeForce12 Firefox 29   256/1024 16/15   N    N   N   N   N
A44 T3  ULP GeForce12 Chrome 35    256/1024 16/15   N    Y   N   N   N
A42 OM4 PVR SGX540    Firefox 29   128/  64  8/ 8   Y    Y   N   N   N
A41 R66 Mali-400MP4   Firefox 29   256/ 256 16/12   N    N   N   N   N
A40 S3  Adreno 220    Firefox 29   251/ 221 16/ 8   Y    Y   N   N   N
A23 S2  Adreno 205    Firefox 29   251/ 222 16  8   Y    N   N   N   N

Uniform = Vsh/Fsh
In/Out  = Attribute/Varying
EInt    = OES_element_index_uint (32bit index)
VAO     = OES_vertex_array_object
Ins     = ANGLE_instanced_array
DB      = WEBGL_draw_buffers
sRGB    = EXT_sRGB

基本的には GPU に依存しますが、さらにブラウザごとにフィルタがかかっている印象です。
Desktop Native では対応してるはずの機能もブラウザによっては無効となっています。
Mobile GPU はもともとこんな感じだったので、それほど驚きはないでしょう。

対応度のばらつきが大きく、最適化以外ではあまり積極的に利用しない方が良いことがわかります。
OpenGL ES 2.0 の要求レベルが低いためで、WebGL 2.0 が OpenGL ES 3.x
ベースになるならもう少し統一されるのではないでしょうか。

動作は遅いものの Firefox + WebGL は Android 2.3 時代の端末でも動作しました。


関連エントリ
Emscripten C++/OpenGL ES 2.0 (6) Chrome の速度と IE11/Safari
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (5)
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (4)
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (3)
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (2)
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす (1)
Emscripten C++/OpenGL ES 2.0 のアプリケーションをブラウザで動かす 一覧


追記 2007/11/02: Direct3D 10 ShaderModel4.0 Stencil Routed A-Buffer とお詫び も見てください。


半透明描画時に、ピクセル単位でソートを行うシェーダーを考案しました。

wheelhandle_ss10 per pixel alpha sorting

とりあえずデモプログラムをご覧ください。(ソース付)
実行には DirectX10 環境 (Vista+GPU) と
DirectX SDK November 2007 の Runtime が必要です。

wheelhandle_ss10t.zip

[SPACE]   pause 一時停止
[3]       3 layer mode
[6]       6 layer mode
[S]       sort ありなし切り替え
[U]       + teapot 追加
[D]       - teapot 削除

ピクセル単位でソートしているので、順番が正しく保たれるだけでなく
半透明ポリゴンが交差しても矛盾しません。

こちらがソートありで

wheelhandle_ss10 per pixel alpha blending with sort

ソートなしにするとこうなります。

wheelhandle_ss10 per pixel alpha blending without sort

ソートしないと、teapot のオブジェクト間だけでなく、自分自身の取っ手や
ふたの重なりにも矛盾が生じていることがわかるかと思います。


●特徴

この手法の特徴は本当にソートしてブレンドしていることと、GPU だけで処理が
完結していることです。CPU は何もしていません。

またシーンのレンダリングは一回で済み、レイヤー単位でレンダリングしなおす
必要はありません。


●欠点

ピクセル単位で最大 layer 数(重なり回数)制限があります。
2種類のシェーダーを作成しています。それぞれ pixel 単位で 3枚までのものと、
6枚までです。

MultiRenderTarget かつ 128bit pixel を使っているため、それなりにメモリと
帯域を消費します。速度についてはまだ未評価です。

今の方法では格納できる値に制限があるため、ソート時に参照する Z の精度に
限界があります。14~16bit なので、交差面の境界が荒くなる可能性があります。


●ソートが必要な理由

Direct3D 10 では GeometryShader の導入によって、より自由度が高まりました。
ポリゴンの動的な追加削除が可能で、また StreamOutput を使ってジオメトリ
の更新も GPU だけでできるようになっています。

反面ジオメトリの決定や描画において CPU を介さないということは、CPU に
よる半透明ソートができなくなることも意味しています。

これを解決する手段として、ソートが不要な加算半透明だけ用いる方法があります。

また Direct3D では、MultiSample + AlphaToCoverage を使う方法が有望と
されています。これはアルファブレンドの代わりに高密度の点描を行い平均化
するものです。

今回のデモ ss10 のアルゴリズムは全く異なるアプローチで、本当にピクセルを
ソートしてしまいました。


● 3 layer シェーダー

・8bit のフルカラー画素値を用いることができます。
・半透明描画の重なりはピクセルごとに 3枚までです。
・透明度(Alpha)は各ピクセル単位で独立した値を持つことができます。
・3枚を超える重なりは、最後に描画された 3pixel が用いられます。Z 値を
 考慮した選択ではないので、重なりが多いと不定の色に見えることがあります。
・MRT が 2枚なので 6 layer より効率はよくなっています。
・ソート時の Z 精度が 16bit あるためで 6 layer より実用的です。


● 6 layer シェーダー

・R G B A 各チャンネルは 7bit カラーに制限されます。
・その代わり半透明描画の重なりはピクセルごとに 6枚まで対応可能です。
・透明度(Alpha)は各ピクセル単位で独立した値を持ちます。
・6枚を超える重なりは、最初に描画した 3pixel と最後に描画された 3pixel
 が用いられます。6枚を超えると 3layer 同様に不定の色に見えることがあります。
・MRT が 4枚必要で、それなりにメモリを帯域を消費します。
・ソート時の Z 値が 14bit なので、交差したポリゴンの境界などの精度が
 3layer に劣ります。



●原理とアイデア

MRT (MultiRenderTarget) と Blend 機能だけを使い、レンダリングした
ピクセルの蓄積を行っていることが最大の特徴です。

レンダリング時に、直前の結果を即時反映させることができるのは
RenderTarget か DepthStencil しかありません。これらの機能の組み合わせ
だけで、描画したピクセルの選択と判定、蓄積のためのエンコードを実現する
必要があります。いくら Shader に自由度があっても、同じパスで出力を
受け取ることができないからです。
なお今回は DepthStencil は使用していません。

Direct3D 10.0 (ShaderModel4.0) では、128bit 浮動少数フォーマット
R32G32B32A32_FLOAT による Blend が可能です。これを利用しています。

RTc= RTc + Pc * RTa
RTa= RTa * Pa

RTc = RenderTarget color
RTa = RenderTarget alpha
Pc = Input Pixel color
Pa = Input Pixel alpha (U:2^8, D:2^-8)

下記の表は、CPU で Pixel 値のシミュレーションを行ったものです。
0x10 から順番に 0x11, 0x12 ~ とカラー値を同じピクセルに重ねていきます。
pixel ~ が書き込まれたフレームバッファの画素値、decode ~ がデコード
して取り出したカラーを表しています。

step 0
pixel U: hex=41800000 float=16
pixel D: hex=41800000 float=16
decode U:  10
decode D:  10

step 1
pixel U: hex=45888000 float=4368
pixel D: hex=41808800 float=16.0664
decode U:  11 10
decode D:  11 10

step 2
pixel U: hex=49908880 float=1.18402e+006
pixel D: hex=41808890 float=16.0667
decode U:  12 11 10
decode D:  12 11 10

step 3
pixel U: hex=4d989088 float=3.19951e+008
pixel D: hex=41808891 float=16.0667
decode U:  13 12 11 00
decode D:  20 12 11 10

step 4
pixel U: hex=51a09891 float=8.62193e+010
pixel D: hex=41808891 float=16.0667
decode U:  14 13 12 20 00
decode D:  00 20 12 11 10

step 5
pixel U: hex=55a8a099 float=2.3176e+013
pixel D: hex=41808891 float=16.0667
decode U:  15 14 13 20 00 00
decode D:  00 00 20 12 11 10

step 6
pixel U: hex=59b0a8a1 float=6.21563e+015
pixel D: hex=41808891 float=16.0667
decode U:  16 15 14 20 00 00 00
decode D:  00 00 00 20 12 11 10

step 7
pixel U: hex=5db8b0a9 float=1.66354e+018
pixel D: hex=41808891 float=16.0667
decode U:  17 16 15 20 00 00 00 00
decode D:  00 00 00 00 20 12 11 10

デコード結果を見ると、Blend 機能を使った積和演算のみでも、最初の 3値と
最後の 3値が正しく保持されていることがわかります。

アルゴリズム U と D のどちらかを使えば 3 layer が実現可能で、両方組み
合わせることで 6layer が実現できます。
このように、制限があるのは演算アルゴリズム上の問題なので、MRT 数を
増やしたとしても単純にレイヤー数が増えるわけではありません。

画素の割り当て下記のとおり。

Algorithm-U / MRT0,1

MRT-0      X    Y    Z   W
-----------------------------
Pixel0-2   R    G    B  ExpU
-----------------------------

MRT-1      X    Y    Z   W
-----------------------------
Pixel0-2   ZH   ZL   A  ExpU
-----------------------------

Algorithm-D / MRT2,3

MRT-2      X    Y    Z   W
-----------------------------
Pixel3-5   R    G    B  ExpD
-----------------------------

MRT-3      X    Y    Z   W
-----------------------------
Pixel3-5   ZH   ZL   A  ExpD
-----------------------------


●浮動少数演算の丸め問題

Blend の演算機能と浮動小数値の特性を使って、ピクセルの蓄積と適切な
値の選択を行っています。このとき非常に厄介な問題が、浮動少数演算時の
丸め処理です。

入力 3 値まではこの問題が発生しないため、当初実現できたのは 3 layer
のみでした。3 値を越えると桁あふれによって追い出された bit が丸め込まれ、
上位 bit に影響を与える可能性があります。

例えば

Algorithm-U: C B A

と入力された段階で D を入力すると A が切り捨てられます。このとき A の
値の重さによって上位 D C B に影響が出ます。例えばすべて A B C D が
すべて 0xff だった場合、あふれた 0xff の繰り上がりの 1 によって
上位すべて 0 になってしまいます。影響は無視できません。

この問題を回避するために、失われたピクセル値が何であったのか推測する
必要があります。もし丸め込まれていたら decode 時に減算すればいいわけです。

捨てられたピクセルは情報として保持されていませんが、同時に Algorithm-D
を用いることによって、6 値までなら失われた値を相互に補完することが
できそうです。

step3
Algorithm-U: C B A
Algorithm-D: C B A

step4
Algorithm-U: D C B
Algorithm-D: C B A

step5
Algorithm-U: E D C
Algorithm-D: C B A

step6
Algorithm-U: F E D
Algorithm-D: C B A

この場合、step5 なら U の捨てられた値は D の B で参照でき、step6 なら
D の C で参照することができます。

同じように Algorithm-D でも入力値を捨てたことによるまるめこみが入ります
が、Algorithm-U から求めることができます。

一見うまくいきそうですが、双方同時にまるめこみが発生した場合に残念ながら
適切な値をとることができませんでした。おそらく実現できるのは 5 layer
までと考えられます。U と D で反転した値を入力しておくことで、同値の
ずれを割り出すことができます。

この問題を解決ができなかったので、6 layer シェーダーでは値を 7bit に
小さくすることで、とりあえず桁上がりが発生しないようにしています。
8bit フルに格納できなかったのが残念です。


●今後に向けて

Direct3D 10.1 / ShaderModel4.1 では、Blend 機能が大幅に拡張されます。
特に MRT 単位で独立した Blend パラメータを設定でき、また UNORM/SNORM
フォーマットでの Blend も可能となります。
これにより、今よりも実装も実現もずっと楽になると考えられます。
layer を増やせるかもしれません。

とりあえず実現が目標だったので・・速度最適化などはほとんど行っていません。
特に並べ替えの実装はあまりに手抜きなので、まだまだ改善の余地は多く
残されていると思います。

シミュレーションのあと実際にシェーダーとして実装したところ、予想と異なる
挙動がありました。CPU と GPU による浮動少数演算の違いだと考えられます。
ss10 ではごまかしが入っているので・・改善しないと。

layer オーバー時に、Stencil を使って最前面の pixel だけ選択できないか
も考えていました。Stencil Test の結果と Depth Test の結果の組み合わせ
によって Pixel を捨てるかどうか自由に決められればできそうです。
現状は Stencil Test の結果だけで決まり、Depth Test との組み合わせは
Stencil の更新方法の選択のみなのでうまくいきませんでした。


気がついたら GPU だけでも 1PETA FLOPS 目前

OS Type 	     Current TFLOPS* 	Active CPUs 	Total CPUs
Windows              200                210773          2081016
Mac OS X/PowerPC     7                  8411            117132
Mac OS X/Intel       27                 8860            53468
Linux                74                 43812           316280
GPU                  902                8199            17284
PLAYSTATIONR3        1332               47241           553464
Total                2542               327296          3138644

Last updated at Sat, 05 Jul 2008 06:04:04 


NVIDIA の新しい GeForce ドライバは Folding@Home に対応しています。
GTX280/260、8800GTX、9600GT で実際に走らせてみました。

ダウンロードするクライアントは次のページにある V6 Beta GPU2 です。
Folding@home DownloadWinOther

GTX280/260 (177.41) の場合 Vista x64 でも動作しましたが、
8800/9600 (175.19) の場合は起動するもののうまく進行しませんでした。
XP x86 では大丈夫です。

・GTX280 (177.41 + Vista x64)
・GTX260 (177.41 + Vista x64)
・8800GTX (175.19 + XP x86)
・9600GT (175.19 + XP x86)

速度は非常に速いです。
走らせた PC のスペックがばらばらで、またデータによって異なるので
おおざっぱですが 25000 のデータで
GTX280 2時間かからず、GTX260 2時間10分程度、8800GTX 2時間 40分くらい。
9600 はもっとかかっています。
これらの PC は他の作業しながらのデータなので、
あんまり当てにならないかもしれません。

期待の RADEON 4870 は試せる PC がなかったのでまだ未調査です。

関連エントリ
Folding@Home 1PFLOPS 達成?
Folding@Home PS3で 1PETA FLOPS



DirectX SDK November 2008 Technical Preview 5回目です。
WARP の試し方の補足と、D3D11 の大きな目玉のひとつである
「動的なシェーダーリンク」について。


● Direct3D 11 が Direct3D 10 より多くのハードで動く理由

  (1) Direct3D 9 世代の GPU に対応した
  (2) ソフトレンダラ WARP が追加された

(1) ShaderModel 2.0~3.0 でも API 自体は動きます。
ただし固定パイプライン用機能が存在しないため Shader 必須。
D3D11 になったからといって GPU の能力を超えて出来ることが増える訳じゃないので、
使えない機能多数。逆に使用できないステートなど制限が生じる可能性あり。

(2) GPU に必要な 3D 機能が無くても WARP を使えば CPU だけで動作します。
DirectX SDK November 2008 現在 10.1 相当で、Reference Driver よりずっと高速。


●手っ取り早く WARP を試す方法

install したサンプルの DXUT.cpp 2907行あたりに
pDeviceSettings->d3d11.DriverType= D3D_DRIVER_TYPE_WARP;
を挿入します。下記の赤い行。WARP Driver で起動するようになります。

// DXUT.cpp 2902行~
        if( GetDXUTState().GetOverrideForceREF() )
            pDeviceSettings-
        pDeviceSettings-

起動直後 = WARP
オプション画面から REFERENCE or HARDWARE に切り替え可能。(WARP には戻せない)

WARP device も FeatureLevel 10.1 なので、10.1 で動かないサンプルは動きません。
DirectX SDK November 2008 現在、動くのは MultithreadedRendering11 だけです。

実行速度は CPU 速度に依存します。


● Dynamic Shader Linkage

Direct3D 11 の大きな特徴の一つがこの Dynamic Shader Linkage です。

動的なリンクというと、複数のシェーダーバイナリをリンクし相互参照を解決する
イメージがありますが・・違います。

わかりやすく言えば「シェーダー内で関数ポインタが使えるようになった」ということ。

インスタンス自体は静的に生成されており、単一のシェーダーバイナリにすべての
インスタンス及びエントリポイントが含まれていなければなりません。

一つのシェーダープログラムの中に複数の関数を作成することが出来、その飛び先を
動的に切換えることができるわけです。

これらの仕組みは HLSL 上では class と interface の形で用いられます。

interface Base {
	float4	GetColor();
};

class Red : Base {
	float4	effect;
	float4	GetColor()
	{
		return	float4( 1, 0, 0, 1 );
	}
};

class Green : Base {
	float4	effect;
	float4	GetColor()
	{
		return	float4( 0, 1, 0, 1 );
	}
};

cbuffer ibuf {
	Red	cbRed;
	Green	cbGreen;
};

Base	color;	// この宣言はポインタ相当で実体を持たない

float4 main() : SV_Target
{
	return	color.GetColor();
}

上の例では Green と Red が interface Base を継承して作られています。
実行は Base で宣言された color を経由して行われており、どのメソッドが
呼び出されるのかコンパイル時にはわかりません。

Green 及び Red のインスタンスは cbRed, cbGreen として ConstantBuffer 上に
静的に作られています。外部の C++ 側からは、このインスタンス化された "cbRed"、
"cbGreen" を参照することが出来ます。

実際にどのインスタンスを color に割り当てるのか、レンダリング時に C++ 側で
いつでも切換えられるわけです。


シェーダー内のインスタンス参照には ID3D11ClassLinkage::GetClassInstance()
を使います。

ID3D11ClassLinkage* iClassLinkage;
iDevice-

ID3D11DeviceContext::PSSetShader() で、シェーダーと同時に使用する
インスタンスのリストを渡します。

// Green を呼び出す場合
iContext-


Shader 内には複数の interface が宣言されている可能性があるので、必ずしも
上のように単純になりません。Reflection を参照して、PSSetShader() に渡す
インスタンスリストの何番目がどの interface 呼び出しに対応するのか調べる
必要があります。

class に変数が含まれている場合、ConstantBuffer 内のメモリ配置との対応付けも
必要です。(この場合 Effect ではないのでバッファの作成も必要)

Dynamic Shader Linkage の仕組みは、このようにパフォーマンスに影響が出ないよう
慎重に作られているため扱いは必ずしも簡単ではないようです。
今後 Direct3D11 対応の Effect fx_5_0 が完成したらある程度自動で行ってくれる
ようになるかもしれません。


出力されたコードを見ると fcall 命令が使われています。label の値 (おそらく
オフセット) を用いてサブルーチン呼び出しを行う仕組みだと考えられます。

ps_5_0
dcl_globalFlags refactoringAllowed 
dcl_function_body fb0
dcl_function_body fb1
dcl_function_table ft0 = {fb0}
dcl_function_table ft1 = {fb1}
dcl_interface fp0[1][1] = {ft0, ft1}
dcl_output o0.xyzw
dcl_temps 1

fcall fp0[0][0]
mov o0.xy, r0.xyxx
mov o0.zw, l(0,0,0,1.000000)
ret 

label fb0
mov r0.xy, l(0,1.000000,0,0)
ret 

label fb1
mov r0.xy, l(1.000000,0,0,0)
ret

上記のように飛び先と種類はコンパイル時に決定しており、おそらく外部参照はできません。
このことは次の例を見てもわかります。

interface Base {
	float4	GetColor();
};

class Blue : Base {
	float4	GetColor()
	{
		return	float4( 0, 0, 1, 1 );
	}
};

Base	color;

float4 main() : SV_Target
{
	return	color.GetColor();
}

この場合 interface を利用しつつも、継承されたエントリが Blue しかありません。
驚くことに HLSL コンパイラは Blue 以外が決して呼ばれないことを認識し、
間接呼び出しを取り除きます。
つまり main の中には Blue::GetColor() がインライン展開されてしまいます。


class の宣言自体は ShaderModel 4.1 (FeatureLevel 10.1) 以前でも使えます。
ただし間接呼び出しは出来ないので、interface からの呼び出しはエラーとなります。
上の例だと「Base color;」を「Blue color;」に書き換えればコンパイル可能です。

ちなみに従来の 4.1 以前のシェーダーにもサブルーチン呼び出しの機能自体は存在
していました。しかしながら HLSL コンパイラはすべてをインライン展開し尽くすので
実際に使われることはほとんどありません。
自分が知る限り、実際に関数呼び出しのコードが出力されるのは switch 文の
attribute に [call] を指定した場合だけでした。

Direct3D11 になってようやくシェーダー内のサブルーチン呼び出しが意味を持つ
ようになりました。


関連エントリ
Direct3D11/DirectX11 (4) FeatureLevel と旧 GPU の互換性、テクスチャ形式など
Direct3D11 (DirectX11) シェーダーの書き込み RWBuffer 他
Direct3D11 の遅延描画、スレッド対応機能、シェーダー命令
Direct3D11 Technical Preview D3D11の互換性、WARP Driver


oga at 01:05
Atom Z500 系の CPU を使ったノートが増えてきました。
小型軽量なものも多く魅力的です。
レビュー記事を見ていると Vista や Windows7 の Aero は off になっているとのこと。
気になったので調べてみました。

使われている GPU はチップセット (System Controller Hub) US15W 内蔵の GMA500。
最近携帯デバイスで多く使われている PowerVR core の一種ですが、アーキテクチャが
さらに進化した SGX に属するもののようです。

その特徴は Unified Shader であること。
DirectX10.1 (Direct3D10.1) 世代に対応できるだけの高度な機能を持っており、
VertexShader, PIxelShader や GeomteryShader を実行可能。
32bit float 演算可能でプログラム長の制限もなく分岐等の制御命令も備えています。
GPGPU として汎用処理に用いられることも想定しているようです。

機能だけ見ると GMA950~ 等よりも上に見えます。
実際に D3D10 対応ドライバが出ているのかどうか、Windows で D3D10.1 や
ShaderModel4.1 が使えるのかどうかわかりませんが、かなり興味が出てきました。

ドキュメントはこのあたりから落とすことが出来ます。
IntelR System Controller Hub US15W Technical Documents

詳しい仕様は Datasheet の方で、Specification update でいくつか更新が入っています。
(update の方で 2GB RAM 対応が書かれています)

datasheet 「9 Graphics, Video, and Display」の一番最初、頂点性能なのに
15 clock/triangle と書かれている点がまず気になりました。
これは 3頂点分なのか、直後に書いてあるように
「 Vertex/Triangle Ratio average = 1 vtx/tri 」で 1頂点分なのか、
それとも 「 peak 0.5 vtx/tri 」の方を指している (つまり1頂点の半分の数値)
なのか曖昧です。

ただ 1頂点で 15cycle は少々多すぎような気がします。実際に計算すると
200MHz 動作なので 13.3M triangle/sec 。
wikipedia PowerVR に書かれている SGX535 の 28Mpoly/sec と比べて半分ほどです。

またピークの fill rate は 2pixel/clock と書かれています。
200MHz なので 400Mpixel/sec。
この数値は GPU としてはかなり低く GMA950 の数分の一。ここで重要なのが
PowerVR であるという事実。PVR はバスの効率を 2~3 倍とみなすため、
800M~1Gpix/sec 相当と書かれていることがあるようです。
Z/Stencil を内部メモリだけで処理可能で、3D のシーンなどポリゴンの重なりが
多くても、描画順に依存せずに常に一番上のポリゴンのみ描画可能だからです。

200MHz という記述は datasheet p.46 (CFG による選択で GFX 200MHz) や
Specification update の p.12 に Graphics Frequency 200MHz と書かれています。
112/160MHz はモニタ出力時のドットクロックのことで、core の動作クロックでは
ないようです。

NVIDIA や AMD で sp, spu 等と呼ばれているシェーダーユニットは、PowerVR SGX
だと USSE (Universal Scalable Shader Engine) という名称になっています。
例えば下記 wikipedia の記述を見ると SGX520~540 の性能はちょうど整数倍です。

wikipedia PowerVR

GeForce や RADEON のように、シェーダーユニットの個数でグレードを分けている
のかもしれません。となると問題は GMA500 にはいったい何個載っているのか。

datasheet の説明を読むと、どうやら USSE は 2個ではないか、と思えます。
wikipedia の記述には GMA500 のシェーダーユニットは 4個と書かれています。
(SGX535相当とのこと) でも 4個だといまいち計算が合いません。

wikipedia Intel GMA

datasheet には同時に 4つのシェーダーが実行可能状態になると書かれていますが、
もしかしたら同時実行ではなくインターリーブしている可能性もあります。
(ちなみに待機状態を含めて 16スレッドの状態を同時に保持できるようです。
レジスタは 1スレッドあたりスカラー 128個)
また下記の記事を見ても 535 までは USSE は 2個であるとのこと。

Centrino Atomにも搭載されるIMGのPowerVRビジュアルIPコア

さらに PowerVR の本家サイト下記ページから、Intel CE3100 の pdf を
読むことが出来ます。

Imagination Intel

Intel CE3100 は同じく GMA500 を搭載したメディアプロセッサで、pdf によると
dual USSE、13M triangle/sec、 2pixel/clock と書かれていました。
こちらの数値 13M triangle/sec は 200MHz 動作の 15clock/triangle とも
一致しますし、US15W の GMA500 と同じと思って良さそうです。
結局 SGX530 に近い数値ですが、同じものなのかそれとも計算方法が違うのかは
わかりません。

USSE の演算ユニットの構成は詳しくはわかりませんが ALU は 32bit 幅とのこと。
他の GPU でも D3D10 世代の Unified Shader はスカラー単位で動作しているので
USSE も同じような構造になっているのかもしれません。

もし 1 USSE が 1 ALU だとしたら、unified shader をフルに割り振っても
float4 の計算に 2cycle かかります。2pix/clock に間に合いません。
datasheet によると ALU は float x1 または fixed16 x2 または int8 x4 を
SIMD として一度に演算できるそうです。
レガシーな GDI のように 8bit ×4 の 24/32bit color ならば 1 ALU だけで済みます。
この場合のみ 2pix/clock が実現できるという意味かもしれません。

逆に言えば pixel にも float 演算が必要な ShaderModel2.0 以降は、ピクセル処理
速度が 1/4 になるということ。RGB だけでも 1/3。
ShaderModel1.0 でも符号付き 8bit なので 9bit 必要です。
おそらく fixed16 の演算が必要になると思われます。この場合 1/2。
Unified Shader なので頂点や GeomteryShader など他の処理も割り込みます。

もしこれらの仮定が正しいとするなら、GMA500 は pixel 性能が足りていないのだと
予想できます。3D のように深い重なりが無ければ PowerVR の特性も活かせず、
タイトなバスがそのまま見えてしまうでしょう。

特に Aero が半透明やレンダリング途中のフレームバッファを使った特殊効果を
利用しているなら、PVR の良いところがさっぱり発揮できていないのかもしれません。
よくよく考えると相性悪そうです。タイルをまたぐ大きなポリゴンも多いし。
さらに ShaderModel2.0 以上を必要とする Aero だと、シェーダーためにカラー
演算能力が 1/4 になっている可能性もあります。

Aero が使えなくても D3D10.1 相当のシェーダーが使えればおもしろそうなので、
実物を触る機会があったら試してみたいと思っています。
そういえばテクスチャユニットとかは全く情報がありませんでした。

これらの内容はすべてドキュメントを元にした想像で書いていますので、
実際に検証しながら調べたわけではないです。
いろいろ勘違いしている可能性が高いですのであらかじめご了承ください。
間違いがありましたらごめんなさい。

続き>Intel GMA500 のスペックについて考える。続き (2)


Android には様々な描画手段が用意されています。
GPU を使って高速に描画可能な組み合わせは下記の通り。

View + onDraw (HW)
RSSurfaceView + RenderScript
GLSurfaceView + OpenGL ES 2.0 (Java)
GLSurfaceView + OpenGL ES 2.0 (NDK)
NativeActivity + OpenGL ES 2.0 (NDK)

下に行くほど低レベルな API になります。
実際に使ってみた限り、描画速度もほぼこの順番になるようです。


● RenderScript

マテリアルのセットアップやジオメトリ演算など、描画ループ自体を
Native 実行可能な C言語で記述することが可能です。
リソースの生成や初期化は Java で行い、プロジェクトも開発環境も
Java と非常に親和性が高いのが特徴です。

Compute 用の RenderScript を簡単に呼び出せます。
大量の並列演算を伴う場合も対応できます。

描画 API は OpenGL ES 2.0 の上に構築された Class ライブラリとなります。
理解してしまえば OpenGL ES 2.0 を直接扱うよりも簡単で使いやすいですが、
直接 GL 命令を使えないのでできることに限界があります。
特にぎりぎりまでハード性能を引き出すような用途には向きません。
また描画に GLSL を使う場合は OpenGL ES 2.0 の知識も必要となります。

利点
 ・C言語 + Native による高速実行。
 ・CPU アーキテクチャ非依存でどの環境でも走る。
 ・Java と親和性が高く Java のプロジェクトに組み込みやすい。
 ・描画 API が Class 化されており GL 直接より簡単。リソースも扱いやすい。
 ・rs_cl と併用できる。

欠点
 ・Android 3.0/API Level 11 以上のみ
 ・GL 周りで高速化に限界がある。
 ・描画リソースを一旦 script に渡してから描画する必要あり。


● GLSurfaceView + OpenGL ES 2.0 (Java)

GPU のハードウエアや OpenGL をよく知っていて、普段から GPU の性能を
めいっぱい使うような使い方をしている場合こちらの方が速いです。
CPU 負荷よりも GPU 負荷のほうが高いと考えられるためです。

逆にもし CPU がボトルネックとなっている場合は RenderScript の方が
向いているといえるでしょう。
アーキテクチャ非依存という点では同一で、特に OpenGL に慣れているなら
容易に扱えます。

利点
 ・CPU アーキテクチャ非依存でどの環境でも走る。
 ・Java だけで完結するため開発しやすい。
 ・GL API をそのまま使うため機能制限が無い

欠点
・Android 2.3/API Level 9 以上 (2.2 ではバグあり)
 ・低レベルな GL API をそのまま使うためコード量が増える
 ・Java によるボトルネックが考えられる


● GLSurfaceView + OpenGL ES 2.0 (NDK)

OpenGL ES 2.0 そのままで、かつ普通に C/C++ で開発できるため他の
プラットフォームで経験があるなら一番親和性が良いはずです。
ただし Java 環境への dll によるアドオンとなるため jni による通信が必要。
開発も両環境を行き来する必要が生じます。特にデバッグで。
また Native Code への事前コンパイルなので、ビルド時に実行環境が固定されます。
速度も一番引き出せる可能性がありますが、ハードに近いところまでそれなりの
知識が必要です。

利点
 ・C/C++ / OpenGL ES そのままなのでソース互換性が高い(移植しやすい,理解しやすい)
 ・GL API をそのまま使うため機能制限が無い
 ・Android 2.0/API Level 5 以上対応なので多くのデバイスで実行できる

欠点
 ・CPU アーキテクチャに依存する。ビルド時に実行環境が固定される
 ・低レベルな GL API をそのまま使うためコード量が増える
 ・リソースアクセスやイベント時に Java と通信が必要


● NativeActivity + OpenGL ES 2.0 (NDK)

Java を使わずに開発できます。
描画は EGL + OpenGL ES 2.0 のみで、全て自力で描画する必要があります。
Android の便利な Class ライブラリを使うことができません。
ほぼゲーム用。

利点
 ・C/C++ / OpenGL ES そのままなのでソース互換性が高い(移植しやすい,理解しやすい)
 ・C/C++ だけで完結し Java コードを必要としないためボトルネックがない。
 ・GL API をそのまま使うため機能制限が無い

欠点
・Android 2.3/API Level 9 以上のみ
 ・CPU アーキテクチャに依存する。ビルド時に実行環境が固定される
 ・低レベルな GL API をそのまま使うためコード量が増える
 ・使える API が限られており、Android の豊富なライブラリが使えない


続きます。次は RenderScript Compute の速度 「Android 3.x RenderScript (7) RenderScript Compute の速度


関連エントリ
Android 3.x RenderScript (5) 任意の 3D モデルを描画する
Android 3.x RenderScript (4) script で頂点を書き換える
Android 3.x RenderScript (3) 独自シェーダーの割り当てとメッシュの描画(2D)
Android 3.x RenderScript (2) 描画と Allocation
Android 3.x RenderScript (1)