Unity Gemsでマルチスレッドに関する記事があったので今回はそれを紹介したい:
http://unitygems.com/threads/
November 2, 2012
はじめに
ゲームでマルチスレッドを活用することに興味がある場合、この記事が役立つようにしたい。スレッドは比較的複雑なトピックだがマスターすることでマルチプロセッサのあるハードウェアや、プロセッシングを管理可能な単位に分割するのが大変な場合に大きなメリットが生じるものだ。
スレッドが実際に役立つケースをあげると:
- A* のようにレベルマップの多くのデータを処理する必要があるアルゴリズム
- メッシュ変形など大量の点データを扱う処理
- サーバへの長時間のアップロード
- QRコード認識のような画像処理
大量の処理があり処理完了までUnity オブジェクトとの相互作用が少ない場合はスレッドを使用し、それ以外ではコルーチンを使用すると良い。
スレッド
スレッドとはプログラムの他のスレッドと同時に実行されるプロセスだ。マルチプロセッサ搭載のマシンでは完全に同時実行の場合があるが、そうなるかはスレッドの数がプロセッシングコアの数より多いかによって決まる。
Unity でプログラミングするとき、メインのゲームスレッドが常に存在し、スクリプトで全てのコードを実行させることが出来るが、もうひとつの手段として、メインゲームと同時に実行する追加のスレッドを作成することが出来る。
Unity では メイン スレッドからコンポーネント、オブジェクト、Unity システム コールのみアクセス出来る。これらのアイテムは、二つ目のスレッドからアクセスを試みると失敗し、エラーが生じる。これはかなり致命的な制約だが、この記事ではどのようにしてこれを回避するか取り上げる。
いつも継続するわけじゃない
コードを記述するとき、別の関数に実行を移すよう明示的さえしなければ関数を開始した後は、 「return のところまで継続してくれるんだよね」と、勝手に想定している人が多い。だけど実際にはいつも継続するわけじゃない。どんな時であってもコードはプロセッサによってスリープさせられるかもしれないし、別のコードが実行されてOSの判断で再び自身のコードに処理を割り当てるべきと判断すれば、ウェイクアップして何事もなかったように続きが行われる。
マシンコードの全てのステートメントでスレッドはサスペンドされることがあり、一つの高レベルのコードのステートメントは多くのマシンコードに変換されるため、自身のプログラムは自身が記述した指示の途中でサスペンドされるかもしれない。
これらはごく普通のことであり、一般的に気にすべきことではない。いや、スレッドのことを考えるとき以外は気にしなくて良いと言うべきだろう。複数スレッドがあるとき、同じ変数やクラスを同時にアクセスするかもしれず、あるいはコードがサスペンドされてそしてステートメントよ残りが実行される前に変数の値を変えられてしまうかもしれない。
このサンプルでは最初のスレッドがCPUレジスタに 1 を追加する準備が出来た後、値 A をロードした後に中断される。[二つめのスレッドもまた値 A を読み込み、50のままであり、1000を減算し値をA に格納し、この時点で A は -950 だ。この時 スレッド 1 が再開レジスタに入っている 50 に 1 を加えて値をA に格納する。この時点で A は 51 となり、-950 は完全に失わられる。
根本的に、これによりスレッドを使用することは難しく、またこういった現象を回避するため一つ以上のスレッドが同時にアクセスするかもしれない変数やメモリのアクセスは大変慎重に行なう必要がある。
Unityではこの問題を回避するため、全てのシステムおよびフレームワークのオブジェクトで他のスレッドからのアクセスは無効とみなすことにしている。
------
次回に続くぜ!
こんにちは、アドルといいます。
返信削除下部の「関連記事」の「Unityでマルチスレッド(後半)」を選択してもリンク先がこのページになっているために、リンク選択では後半に行けませんでした。
この部分は変更されると使いやすくなると思われます。
ご指摘有難う御座います!!修正しました!
削除