スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[考察]マスコットカプセル

前回記事はまだ調べが足りませんでした。かなり誤解なんかも含まれていて怪しげなまとめになってしまったのでもう一回整理してみる。(前回のは計測結果以外なかったことにしてください…)

まずは
エイチアイ公式サイト(http://www.hicorp.co.jp/product/index.html)
マスコットカプセル公式サイト(http://www.mascotcapsule.com/ja/index.php)

第一にマスコットカプセル自体は各端末のネイティブコードで書かれたソフトウェアであること。
次にマスコットカプセルV4では仕様ですでにV3のサポートが上げられています。
なのでV4搭載のケータイではV3も使用することがほぼ100%できるということだと思われます。
また、V3とV4の動作環境をみると浮動小数不要と書かれているので内部では完全に固定小数で演算が行われていることもわかります。(=浮動小数を使っているのはインターフェースのみ)
さらにエイチアイ公式サイトではV4はOpenGLESに対応した3Dアクセレータチップとの連携が可能であるということが書かれ、またマスコットカプセルFAQなどではソフトウェアレンダリングかハードウェアレンダリングは機種により異なると書かれていることから、OpenGLサポート機種においてはハードウェアを使用し、非サポート機種においてはソフトウェアレンダリングを自動判別して行うことがわかります。

以上のことからマスコットカプセルは、どんな機種であろうと搭載でき、また互換性というものを非常に大事にして作られていることもなんとなく読み取れます。機種を作る側にとっては専用ハードをつもうがつまないが同じマスコットカプセルを搭載するだけすみ、コンテンツを作成する側にとってもハードの有無を気にする必要がないに加え、V3互換がサポートされているため幅広い機種向けに容易に作ることが可能、ということになります。

ここまでがマスコットカプセルの概要です。なんか結構優秀なものに見えてくるから不思議。
GraphicsOGLを使用できずとも、一般ユーザーはOpenGLの恩恵を得られるのです。

次にDoJaの実装の仕方。

ドコモ公式サイトiアプリのページ(http://www.nttdocomo.co.jp/service/imode/make/content/iappli/)

ここの機種依存情報を見ると、OpenGLのサポート開始はPは903iからですが、基本的に904iからの対応であることがわかります。また非互換性の項目にはOpenGLフルセットをサポートできていない機種、振る舞いの差異、ハードウェアやドライバの差異などに触れていることから、実装状況は実際はかなりまちまちであることがわかります。
こんな差異があることからOpenGL(GraphicsOGL)使用はトラステッドに限定されているのだと思われます。使用できないメソッドなりが機種毎でかなり存在し、同一のプログラムが全機種で動くことはほとんどないんでしょう。
それに対してマスコットカプセル(Graphics3D)はOpenGLで使える機能は使い、使えない機能はソフトウェアで埋め合わせているので、速度差はかなりでるものの、全機種サポートできるので一般で公開可能であると考えられます。
OpenGLが全機種で完全に使用可能ならばマスコットカプセル(Graphics3D)の存在意義はほぼありません。それが存在しているのだからOpenGLが完全には使用可能ではないともとれます。
マスコットカプセルV4の搭載はDoJa4.0(=901i)からですから、901iから903iまでは完全にソフトウェアで処理していることもわかります。904iや905iから急激に速度が上昇したのもうなずけますね。またV4はV3の機能の使用を完全にサポートしているわけですからV3が搭載されはじめた505i世代からのアプリもそのまま動かすことができる。

DoJaにとってはOpenGLはハードウェア実装を全機種に義務付けることがいろいろな諸問題から難しく、全面サポートをすることができず非常に扱いにくいものとなっているのではないでしょうか。なのでそれらの不足機能・機種による差をソフトウェア演算で埋めてくれるマスコットカプセルの存在は非常に便利で重要なものなのでしょう。


以上が調べて考えた考察です。


まぁこう考えると機種によるハードの差でどんなに速度差がでて扱いにくかったとしても、動くだけマシってことなんでしょうか。性能・仕様を機種によりそろえないドコモが悪いともなんともいえないし(そろえたら今以上の価格になりそう)、マスコットカプセルだってあらゆる機器に搭載できるようにするのは難しいことだったでしょう(ハードの差を埋めるべく存在するわけだし)。


っていってもマスコットカプセルV4はビューポート変換くらい搭載してほしかったなぁ…


■追記
では前回の記事でV3の方がV4よりも高速であったのはなぜか。
V4が浮動小数のインターフェースもっているからといっても、機種は904iであるので仕様通りならOpenGL機能が使えるはずである。いくらインターフェースが浮動小数であろうともハードウェアを使うOpenGLに固定小数完全ソフト処理のV3が速いわけがない。
…ひょっとしてN904iではOpenGLがあまり実装されていないとかでしょうか。確かにNはNでも904iと905iでレンダリング結果がかなり異なっているし、905iでは2D描画と同等にまで高速化されている。さらにN904iは他の904iよりも3Dが低速であることもわかっている。
つまりN904iはほとんどソフトで、N905iではかなりOpenGLをサポートした、ということでしょうか。
どの程度OpenGLがサポートされているか。これがかなり重要かも。
もしこれが本当ならばN905iではV3の方が低速である可能性がある。

■現時点でのまとめ
・ハードウェア実装状況の差異からOpenGL機能は一般に公開できない(使用できない機能が機種により存在)。
・マスコットカプセルはどんなハードでも動くように作られている。機能的な機種依存が少ない。
・V3は完全にソフトウェアで処理されている。
・V3はV4が使える機種なら全機種使用可能。
・V4ではOpenGLを間接使用できる。よってハードウェアを使用できる機種では高速に動く。
・ハードの機能を使えない環境下ではインターフェースに浮動小数を用いるV4の方が低速。
・最新機種はOpenGLの大部分をサポートしておりV4ではその恩恵をしっかり受けることができる。
・レンダリングに差異がでるのはハードウェアを使用している証拠と思っていい。
・OpenGLを直接使った方が高速であるので公式アプリに速度面で勝つのは基本的に不可能。

<注意>相変わらずここに書かれていることは個人の勝手な考察であり確かな情報ではないのであしからず。
スポンサーサイト

[検証]マスコットカプセル3.0と4.0

あけましておめでとうございます!
皆さん初夢見ましたかね。ワタシは見ていません(覚えてません)。

去年の今頃は確かiアプリの3Dに初挑戦で悪戦苦闘した末、最終的には1プリミティブにポリゴンを可能な限り詰め込み、擬似的な2Dとして使用するクラスを作りました。
しかし、久々にマスコットカプセルまわりを調べていたところ、ちょろちょと気になる記述が見つかりました。


■マスコットカプセルの現状
・マスコットカプセルはソフトウェアで実装。
・トラステッド限定だがOpenGLはハードウェアアクセレータが使えてる模様。
・標準API側の3D機能はマスコットカプセル4.0、オプションAPI側のはマスコットカプセル3.0で実装。
・4.0は浮動小数(内部は固定小数処理らしい)が扱えるが低速。
・3.0は固定小数のみが扱え、その分高速。ただし機能不足。
・3.0は高速であるがゆえか旧バージョンであるに関わらず最新機種でも残されている模様。



こんな感じですね。マスコットカプセルだってちょっとはハードの3Dアクセレータ使ってんだろうと勝手おもってましたが、そんなに甘くない模様。遅いわけですよ。あぁOpenGL使えたらなぁ。
3.0なんてもうすでに抹消されてるのかと思ってたらまだ使える模様。むしろ現役。
4.0だって内部処理が全部固定小数だって書かれているにも関わらず、いろんなところで3.0の方が高速であると書かれているのに非常に興味がわくところ。

(追記:4.0ではハードを使えてるらしい。ただしDoJaではどうかは不明。)

ここで3.0と4.0のゲームに関わるような機能の差を。



■3.0と4.0
・3.0ではPrimitiveの透過属性に通常、特定色透過、加算(100%のみ)、減算(100%のみ)、アルファブレンド(50%のみ)が使用できるが、4.0では通常、加算(指定化)、アルファブレンド(指定化)が使用でき、特定色の透過もアルファブレンドモードで実現可能。
・4.0では距離よって特定色をブレンドする擬似フォグが使用できる。
・3.0では画面中心を指定することができる。
・3.0では照明は平行光源、環境光で白色のみだが、4.0ではさまざまな色を指定でき、そのほかのライトも使用できる。



らしきものをつくってる上で直接的な関係があるのは、アルファブレンドの段階指定とフォグの存在、そして画面中心の指定。アルファブレンドの段階は暗転に使えるし(ボムを使用するときも3Dの段階で暗転を実現できるのは大きい)、フォグは背景の奥行きをごまかせるのでつらい。また画面中心の指定では今はcopyRectやイメージに一旦描くことで無理やりやっていることなので、これは相当の高速化が期待できる。

といってもフォグはあらかじめ効果範囲を示したような画像を用意し、減算、加算を駆使してそれっぽくみせることは可能かもしれませんので、要は高速であれば余裕があるので他の手段でなんとかすることもできる。めんどくさいけど。

とにかく実際に測って比べてみました。

■実験方法概要
64x64のテクスチャを使って1プリミティブに7x7の49ポリゴンを入れ加算合成属性100%にし、レンダリング、フラッシュを行いこれを100回繰り返すまでの時間を測定する。

テクスチャにはらしきもので使用予定の大玉を使用。30x30で表示。2D描画は一切使用せず、また画面反映を毎回行うと画面更新周期以下での反映と以上の反映では大幅な処理時間差がでるので、g.lockをしてから測定。測定終了後にg.unlockをしています。
またflushのみの測定も行いましたが、これはflush開始から終了までの時間を100回分加算して測定しています。
また起動直後は誤差がでやすいので、2回目以降の測定結果数回分の平均程度をみています。

■結果(N904i)
マスコットカプセル4.0 全体:1350ms(1回:13.5ms) フラッシュ:1173ms(1回:11.73ms)
マスコットカプセル3.0 全体:953ms(1回:9.53ms) フラッシュ:770ms(1回:7.70ms)

どういうわけか、メモリ転送のみのはずのフラッシュでのみ差がでるという結果になりました。
総じて3.0のが高速なのですがレンダリングコストが同じっていうのが腑に落ちない。
やはり4.0も内部は固定小数で実際はやってることがいっしょなんだろうか。小数の分のオーバーヘッダで4ms?うーん。4.0も3.0と同じ固定小数限定にすりゃいいのに。

画面の中心移動も省略できるとしてもざっと6msの高速化ですが、ここに擬似fogを強引に実装するにくわえて、暗転系でも2Dでやるしかなくなるのでそれでやるとしたら、あっというまに6msくらいは飛びます。

なので、3.0はシンプルな3Dのみを使うっていうアプリ限定の機能な気がします。
ちなみに1度でもどちらかのメソッドを呼び出した場合はもう片方はアプリ終了時まで使用できないという謎の制約がつきます。ふーむ・・・

結局4.0でいくしかないのだろうか。

■マスコットカプセル4.0って
馬鹿です。はっきりいって馬鹿です。
去年、にふさんとTrasformクラスを固定小数のみで書いてみましたが、その時点ではマスコットカプセルのものよりも比較的高速でしたが、浮動小数なインターフェースを載せた自体で性能はがたっと落ちるというのを体験しました。浮動小数→固定小数→浮動小数のコストが結構馬鹿にならないのです。
マスコットカプセル4.0でOpenGLにインターフェースをそろえらしいんですが、内部固定小数でやってるっていうくらいなら従来通りの固定小数を直接設定できるメソッド類も容易してほしかった。どうせ12bitシフトしてるだけなんだし…3.0と4.0の低速化は実際このインターフェース変化によるところが大きいと思う。3.0にはコマンド実行できるメソッドがあってメソッド呼び出しコストすら省略できるような配慮があったのに4.0ではなんもない。規格そろえればいいってもんじゃない。しかも、この低速化のせいかわざわざ各機種は3.0の機能をまるまる持ち続け、3.0と4.0の両方のAPIが用意されてれという奇妙な状況に。4.0から浮動小数抹消して4.0の機能を持ちつつ3.0並の速度を持つものがほしいです・・・
ケータイ用なんだしどうせOpenGLとちがってソフトでやってんだから固定小数で・・・

■追記
マスコットカプセルV4はハードを使ってる?
http://www.hicorp.co.jp/product/obj/mascotcapsule.pdf
の図ではOpenGLよりもネイティブにちかい側にマスコットカプセルがるところをみると、DoJaAPIのGraphicsOGLは3Dアクセレータを使えるマスコットカプセルV4なのかな…マスコットカプセルがV4はOpenGLが使えてアクセレータが使えるぜ!っていっているに加えてGraphics3Dの他にOpenGLが使えるものとしてGraphicsOGLが用意されたところをみるとなんかそんな気がする。ではGraphics3Dってなによw わざわざ機能制限してるマスコットカプセルV4ってことでしょうか…
OpenGLもケータイではマスコットカプセル。


<注意>ここに書かれていることは個人の勝手な考察であり確かな情報ではないのであしからず。

[検証]switch文の動作速度

スクリプト周りを点検しているときにふとswitch文の速度について気になったので検証してみることにした。

ずいぶん前だったかに「(iアプリでは)if-else文の方が速い~、サイズを小さくできる~」などを見たことがあり、それがプログラミングをはじめたばかりのときだったものですっかり鵜呑みにし、ろくに検証もせずやれるところはif-elseで~っとやってきました。これを気にちゃんと使い分けとかできるようになりたいものです。一般に気にする程度の速度差ではない、最適化時にほぼ等価になるだった言われていたりもしますし、その辺をはっきりさせたいです。


《検証1》if-elseとswitch、本当にif-elseは速いのか
[プログラム内容]
if(a==0){
..............
}else if(a==1){
..............
}else if ...........


switch(a){
case 0:
...........
break;
case 1:
............
break;

を分岐数(?)40個のものを作る。これらを関数化し、これを100万回処理するのにかかる時間を測定する。尚aは呼び出し時ランダムで決定される。

[結果]
if-else ⇒ 2590ms
switch ⇒ 2324ms

1.11倍程度の違い。かなり微小な差ではあるが確実にswitchの方が高速のようである。しかしあまりに数字が近いのでifとswitchでそれぞれどういう特性なのかいまいちつかめない。(N904i。PCのエミュレータではswitchの方が倍程度高速である。)

そこで分岐数を増やしてその差の開き方を見てみることにした。


《検証2》分岐数が多い場合に強いのはどちらか
プログラム内容は前とほぼ同じで変更箇所は分岐の数のみ。分岐の数を両方とも150まで増やしてみた。

[結果]
if-else 4082ms
switch 2360ms

1.73倍程度まで差が開いた。差が開くことはなんとく予想できていたので驚かなかったが、ここで驚いたのがswitch文。なんと分岐数40のものと30ms程度しか増加していない。(エミュでは差は4倍にもなる。)


if-elseはif文を順次解決していくためこのようになったはずで、処理時間は比例的にのびていくと思われる。対してswitch文は数値を比較するのではなくラベルにむけて直接ジャンプしているというか、要素の順番、数に関係なくほぼ一定の時間で分岐をすますことができるようだ。ただif-elseが遅いというわけでないのもこの検証でわかる。今回は分岐の数がかなりの量あったためこのようになっただけで、分岐が少ない場合はif-elseの方が速いはず。switchは多分この数値からほとんど変化しないだろうし。すくなくとも完全に等価のものではない模様。定数のみっていう縛りは伊達じゃない!


[まとめ]
分岐が多い場合はswitchを。少ない場合はifを使うべし。
ただ大した差ではないしJAVAの実装やらが絡んでくるので一概にこうとはいえないので好みや、見易さを考慮して使い分けても問題ない。



なかなか奥が深い。。。

[検証]2DCG描画速度

ちょっと気になったのでいろいろな方法での画像描画時間をはかってみた。

■内容
テストの画像には11x11の弾の画像を用いる。

A.縁を透過色指定してある透過gifをそのまま描画。
B.透過指定なしでそのまま描画。
C.createImageにより作成したImageに焼き直しsetTransparentColorにより透過を有効にし描画。
D.createImageにより作成したImageに焼き直し透過指定せず描画。

これらを20x20の計400個を重ならないように並べて描画、これを10回するのにかかる時間を測定する。


■結果
N904iによる結果
A ⇒ 139ms (透過gif)
B ⇒ 156ms (通常gif)
C ⇒ 129ms (createImage+透過)
D ⇒ 127ms (createImage)

D < C < A < Bという結果。
gifそのままよりもcreateImageにより作成したImageの方が速いのは一目瞭然。
createImageの方が内部の描画しやすい形になっているから?
AとBと透過色の分画素を設定しなくてすむのでその分Aの方が速いのだろうか。
CとDでは透過させた方が若干遅い。

gifそのままとcreateImageのものでは透過の仕組みそのものが違う模様。

createImageで作成したものの方が速いと聞いてちょっとやってみたわけですがそこまでずば抜けて早いわけでない模様。createImageのが10%程度速いようですね。

それにしてもN904iで弾400個を描画するのみなら14msだったのか;
ゲーム中では14msで200個くらいだったような気がするので、半分以上は数値演算の方だったんですなぁ。
もしcreateImageのものに切り替えたなら描画のみ10%速くなるので、ゲーム中の弾なら14ms間に+10前後多く出せるということかな?どうなんだこれ;
そもそもcreateImageを使ったものの透過色使用は903iから。
これだけのために903i専用オプションをつくるか、どうか。

903i以降専用機能を使っていても、条件分岐しっかりやっとけばそれ以前の機種でもDL→起動は可能なんだったか。うろ覚え。
⇒SH900iでは可能。903i以降専用の使用不可の命令が呼ばれた時点で落ちる。含まれているだけなら問題ないようです。全機種これならオプションに設定項目おいても問題なし。903i以降はもれなく高速化決定~。

[検証]メンバへのアクセスは重いのか

クラスを使うことが多くなった今日この頃。
JAVAの最大の特性でとても便利なものなのだが、メンバ変数、メソッドへのアクセスが重そうだったので、真実を知るために実際にいろいろ図ってみた。
尚測定機種はN904iであり、多機種ではかなり異なると思うので参考までに。

[実験その1]オブジェクトのメンバ変数へのアクセス速度
final class test{
public int hensuu=0;
}
というクラスを作り、他のクラスでhensuuという名前の変数を作り、Testクラスのインスタンスを作り
以下A、Bにかかる時間を計ってみた。(100万回アクセスにかかる時間を計測)

A⇒for ( int i = 0; i < 1000000; i++ )hensuu++;
B⇒for ( int i = 0; i < 1000000; i++ )test.hensuu++;

■結果
A⇒152ms
B⇒162ms

差は10msつまり一回あたりのメンバ変数アクセス時ロスは100nsということのようだ。100万回で10ms、10万回で1msを遅いというのかはよくわからないw


[実験その2]getメソッドは遅いのか?速いのか?
よくprivate変数をとりだすためにget○○というメソッドをよく使う。これってどうなのってことで、計ってみた。使用するクラスは下のようで前回と同様A、Bにかかる時間を測定。

final class Test{
public int hensuuA=100;
private int hensuuB=100;
public int getHensuuB(){
return hensuuB;
}
}

A⇒for ( int i = 0; i < 1000000; i++ )n=test.hensuuA;
B⇒for ( int i = 0; i < 1000000; i++ )n=test.getHensuuB();

■結果
A⇒156ms
B⇒149ms
なんとメソッド呼んでアクセスする方が速いとの結果。ちなみにエミュではAの方が倍速い。これは機種により変わりそう;とりあえず、メソッドをつかうことの不利はほとんどないようだ。


[実験その3]staticメソッドってどうなの?
クラスにstaticなメソッドをおいてアクセスするときって、あるようなないような感じだが、それってどうなのか、実際に計ってみた。使用するクラスは下のようで前回と同様A、Bにかかる時間を測定。Aがstaticのメソッドにアクセス。

final class Test{
private static int hensuuA=100;
private int hensuuB=100;

public static int getHensuuA(){
return hensuuA;
}
public int getHensuuB(){
return hensuuB;
}
}

A⇒for ( int i = 0; i < 1000000; i++ )n=Test.getHensuuA();
B⇒for ( int i = 0; i < 1000000; i++ )n=test.getHensuuB();

■結果
A⇒562ms
B⇒152ms

すごい差がww
staticのメソッドがこれだけ遅いとは…ひょっとしたらstaticな変数へのアクセスに時間がかかっている可能性もなきにしもあらずなので、これも計ってみた。ただエミュではAの方がはやい。なんなんだこの差は…


[実験その4]staticな変数ってどうなの?
staticの変数にそのままアクセスするのと、Newしてその中の変数にアクセスするのにどれだけの差があるのか計ってみた。説明文は同じなので略。

final class Test{
public static int hensuuA=100;
public int hensuuB=100;
}
A⇒for ( int i = 0; i < 1000000; i++ )n=Test.hensuuA;
B⇒for ( int i = 0; i < 1000000; i++ )n=test.hensuuB;

■結果
A⇒170ms
B⇒161ms

大した差ではないが、staticはやはり遅いようだ。これもふまえると、staticなメソッドへのアクセスはやはりとてつもなく遅い、ということになる。


[実験その5]定数ってどうなのよ。
定数はよく使うもの。必然的に他クラスの定数にアクセスする頻度も多い。
では定数ってどういう扱いなのか、実際に計ってみた。Bが定数。

final class Test{
public static int hensuuA=100;
public static final int hensuuB=100;
}
A⇒for ( int i = 0; i < 1000000; i++ )n=Test.hensuuA;
B⇒for ( int i = 0; i < 1000000; i++ )n=Test.hensuuB;

■結果
A=170ms
B=141ms
どうやらホントに最適化されている模様。
多分コンパイルの時点で置き換えが行われているのだろう。
定数は使いまくってよさげ。



■結論
クラスは気になるほど遅くない!バンバン使ってもさして問題はない。
ただしstaticなものは全般的に遅いので注意。以上で実験終了。
エミュでは結果が逆、というのが結構あるので、多機種ではどうなってるのかわからないので、参考まで、ということでよろしくお願いします~。
Go To 物置。
プロフィール

書いてる人:つん

まったりのんびり。書いてる人の息抜きブログです。

多分連絡先↓
metal_tsun@yahoo.co.jp

カテゴリー
リンク
月別アーカイブ
バロメーター
Java歴:2005年2月から今まで。
3DCG歴:2005年8月から数年。
C歴:2006年4月から今まで。
VB歴:2007年3月からちょっと。
Delphi歴:2007年3月からちょっと。
PIC歴:2007年5月から数年。
イラスト歴:2007年12月から今まで。
DTM歴2008年2月からちょっと。
PHP歴2008年4月からちょっと。
C++歴2008年4月から今まで。
C#歴2009年1月から今まで。
Objective-C歴2009年4月から今まで。
CSS歴2012年5月から今まで。

ブログ開始日2005/10/11


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。