ブログランキング・にほんブログ村へ


iPhone/iPad用潜水艦ゲームアプリ ソナーエコー iTunesにて公開中

2016年06月18日

[iOS]metalいろいろ

今更ながらOpenGLESをMetalに置き換える作業をしている。
Metalは10倍速いとかいう話で頑張ってみたものの、そんなうまい話はなさそうということで力が抜けてきてる。

当たり前といえば当たり前だけど、GPUでの速度を決定しているのはほとんどフラグメントシェーダの速さ。それはフラグメントシェーダの処理回数が圧倒的に多いから当然のこと。
だけどどんな環境を使ってもフラグメントシェーダの処理回数に大した違いはない。
シェーダを記述する見た目の言語を変えてみても、それは結局ハードウエアが直接実行できる機械語(懐かしい)バイナリに変換されることにかわりない。記述内容が同等であれば、結果バイナリも大差なかろう。大差あるとすれば、それはシェーダ言語コンパイラの性能差ということで環境の差ではない。つまりOpenGLESが不利という理由にはならない。
実行するハードウエアGPUが同じものである以上、差はでなくて当然ということになる。

MetalがopenGLに対して優速になるためには、OpenGLESにない何かがなければならないわけだが、現在それを探している。一応パラレルエンコーダーというのがそれだと思って調べてみたが、簡単な実験では計測可能なほどの差はでなかった。それも考えてみれば当然だけども、GPUとはもともと超並列処理なのだから、それの切り分け方を変えたところで遊んでいるパイプラインがない以上意味があるはずない。結局は処理回数なのだ。

あとはよく言われるメモリ共有によるデータ転送の有利さがあるけども、ゲームなどではそれほど毎回生成しなくてはならないデータはない。いや、むしろ生成が必要なケースを極力避けることがコーディングの基礎になってる。なぜなら、それはCPUにしかできない作業だから、最終処理がいかに超並列であっても処理する元データができなくては処理にとりかかれないのは当たり前だ。だから、これをもって10倍の速度差が出るプログラムというのを自分は想像できない。

そういうわけで探してはみるけど、あまり明るい展望は今の所ない。
それどころか、新環境のせいか、不可解な未完成による問題に悩まされるデメリットが多い。

たとえば、パイプラインを生成することでこんなエラー
Error Domain=AGXMetal Code=1 "Compiler encountered an internal error"

直接触ってないシェーダでこんなものが出る。調べてみると、コンパイラのインターナルエラーで、プログラマに責任はないとのこと。
で、何が理由なのかといえば。
discard_fragment();
こいつの扱いで発狂することがあるらしい。実際コメントアウトすると通るようになる。

MetalのリリースはiOS8のときで、もうiOS10がアナウンスされた今、鳴り物入りで煽ったものののこういう不出来さを放置したまま先へいくAppleには不安を感じてならない。
posted by みこあいさ at 10:45| iOS開発