iOSで物理エンジンの動作をバックグラウンドスレッドを使用して高速化する

English version is ready: 英語

はじめまして、吉村と申します。

今回はスレッドに関するTipsに触れてみようとおもいます。
例として考えてみるのは物理エンジンです。簡単に高度なシミュレーションができて自分のような怠け者には非常にすばらしく神々しい存在です。
しかしiOS環境では少しCPUが非力であと一歩処理が足りない・・・
そんな状態の時、仕方ないとあきらめていませんか?
というのも、iphone4s以降はCPUにコアが2つ以上存在しています。
ということはうまくやれば、重い物理エンジンを並列化できるのではないか?
という考えに至ります。

でも一見大変なようにも見えますが、スレッドをよく理解し、
iOS SDKをうまく使えば簡単にできます。

以下に疑似コードを書いて考えてみます。

まず必要になるのは
並列キュー・物理エンジン・レンダラ
このあたりでしょう
クラスメンバにでも用意します。

並列キューは以下のように初期化すると良いでしょう

次にメインループを考えます。

このような構造で処理をすれば、非常に効率的に物理エンジンをバックグラウンドスレッドで動作させることが可能です。
注意する点としては、

まず、
絶対にwaitUntilAllOperationsAreFinishedと
addOperationWithBlockの間以外では
物理エンジンオブジェクトに触らない
、ということです。

別スレッドで動作している物理エンジンに対して同期コードを挟まずに何かをすることは自殺行為です。
かならず同期を考慮に入れましょう。
dispatch_async等を駆使するプログラミングスタイルでは特に注意が必要でしょう。
フラグをつかって管理しても良いでしょう。

あとは、同期しているときのコードを減らすことくらいでしょうか、
ここを小さくおさめていれば、良いパフォーマンスが得られるはずです。

今回提示した考え方は非常に汎用的で、
重い処理であれば当然物理エンジンに限らず同じ方法で並列化することが可能です。
コアが2つ以上ないと逆に遅くなりますが、
ハードウェアに新しいものを対象とできれば、ワンチャンス最適化の余地が残されている、ということを忘れないでいたいですね