2017-12-18

オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ

オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ

LINE Engineering
Blog

Cocos2d-xにおけるマルチスレッドを利用した並列処理技法―物理演算パフォーマンスの最適化に向けて―

Kim Suntae 2016.01.27

LINEでモバイルゲームの開発を担当しています。

こんにちは。LINEでモバイルゲームの開発を担当しているSTです。今回は、オープンソースのモバイル向けゲームエンジンの世界シェア1位(25%)を誇るCocos2d-xにおいて クスコ SAFETY21 ロールケージ J項改 7点式 品番:322 270 F20 ホンダ インテグラ タイプR DC5 サンルーフ無、マルチスレッドを利用して並列処理を行う方法をご紹介します。シングルスレッドで動作していた既存の物理演算をマルチスレッド化して並列処理するように構造を改善し クスコ SAFETY21 ロールケージ J項改 7点式 品番:381 270 L20 ホンダ S2000 AP1・AP2 ソフトトップ車、パフォーマンスを向上させる方法について説明します。

オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ 24×10.5J レガシィ BG6Z

マルチスレッドを利用した物理演算の並列処理構造を説明する前に、まず既存のシングルスレッドを利用したCocos2d-xのアップデートのループを説明しましょう。

【図1】既存のCocos2d-x

【図1】は、Cocos2d-xにおける既存のアップデートのループです。ユーザーの入力内容を取得してゲームロジックを実行した後、物理演算を行い、最後にレンダリングするという流れです。ここで重要なポイントは、シングルスレッドなので、物理演算が終わった後にレンダリングが実施されるという点です。つまり、物理演算が終わるまでレンダリングができない構造なのです。そのため、物理シミュレーションに多くの演算が必要な場合はレンダリングに遅延が発生し、結局はFPSが低下して、カクカクとした不自然な動きの画面になってしまいます。

その逆の場合も同じです。レンダリングの演算量が多くなると、次のユーザー入力で待機が発生し、物理演算結果の更新が遅延します。これは、すべての処理が一つのループで行われるからです。演算量が少なく、処理数が多くない状況ならシングルスレッドでも問題ありませんが、過負荷の状況ではこのような問題が生じやすくなります。

【図2】新たに設計したCocos2d-x

【図2】は、Cocos2d-xでマルチスレッドで動作する物理演算の並列処理の設計図です。【図1】との違いは、物理演算が別スレッドで実行されるという点です。メインスレッドでは、最新の物理演算結果のみ読み込んでレンダリングします。既存のシングルスレッドでは、物理演算が終わるのを待ってからレンダリングを行っていました。

一方、新たに設計したこの構造において最も重要なポイントは、物理演算は別スレッドで並列処理されており、メインスレッドではその物理演算が終わるのを待つことなく、最新の計算結果のみ読み込んでレンダリングするという点です。また、レンダリングに過負荷がかかって遅延が発生している状況でも、物理演算は別スレッドで一定のtick※注1を保持しながら独立して並列処理できます。

アップデート方法としては、メインスレッドではゲームのプレイ時間によって結果を表示する必要があるためDelta Timeアップデート※注2を使い 、Simulatorスレッドでは物理演算の精度を高めるために一定時間ごとにアップデートするFixed Timeアップデート※注3を使います。こうすると、Unityのように物理演算が並列処理されるので、開発者はFixed Time値を変えながら、つまりゲームに適した物理演算の精度を調整しながらシミュレーションできるようになります。

【図3】 システムアーキテクチャ

【図3】は クスコ D1 ロールバー J項改 8点式 品番:606 261 G スズキ カプチーノ EA11R、Cocos2d-xでマルチスレッドを利用して物理演算の並列処理ができるシステムアーキテクチャです。このシステムには、次の4つのモジュールがあります。

  • Cocos2d-x
  • Chipmunk Physics Library
  • Game
  • Simulator

Cocos2d-xにはChipmunk Physics Libraryという2D物理エンジンが標準で搭載されています。Gameは、Cocos2d-xを使ってゲームに必要なSceneを作成し、各種コンテンツを開発します。ここで、Scene情報を別スレッドであるSimulatorに渡すと、SimulatorはCocos2d-xにアクセスできるようになり、最終的にはCocos2d-xでChipmunkライブラリの物理演算を動的にコントロールできるようになります。ここでCocos2d-x、Chipmunk、Gameはメインスレッドで動作し、Simulatorは別スレッドで動作します。つまり、Gameと物理演算が並列に処理される構造なのです。

マルチスレッドを利用した物理Simulatorの設計

物理演算をマルチスレッドで処理するためには、物理Simulatorの設計がとても重要です。 【図4】 既存のシングルスレッドによるCocos2d-xの物理構造

【図4】は、既存のCocos2d-xの物理構造を示した図です。ノードとPhysicsBody、SceneとPhysicsWorldはそれぞれ1対1の関係にあります。Sceneは複数の子ノードを持つことができ、PhysicsWorldも複数のPhysicsBodyを持つことができます。このように、ゲームの画面を格納する最上位オブジェクトであるSceneと複数の物理オブジェクトを格納する最上位オブジェクトであるPhysicsWorldが1対1の構造になっています。また、イベントハンドリングのための一つのEventDispatcher変数をグローバルに使用しています。

【図5】 新たに設計したマルチスレッドが可能なCocos2d-xの物理構造

では、既存の構造をマルチスレッド化するには、どうすればいいでしょうか。【図5】には、Simulatorが追加されています。Simulatorは、SceneオブジェクトとEventDispatcherオブジェクトを持っています。SimulatorはSceneオブジェクトを使用してPhysicsWorldにアクセスし、最終的にはPhysicsBodyにアクセスして物理データにアクセスできるようになります。ここでPhysicsBodyは、Chipmunk Physics Libraryが提供する実際のRigidbodyオブジェクトであるcpBodyをラップしたクラスです。Cocos2d-xでは、PhysicsBodyオブジェクトが Chipmunk Physics Libraryの値にアクセスしています。つまり、Cosos2d-xで物理演算を並列処理するには、Cocos2d-xのソースコードのみならず、Chipmunk Physics Libraryのソースコードにも同期化ロジックを追加しなければなりません。

同期化のために、Chipmunk Physics Libraryのソースコードをダウンロードして、cpBody値の変更箇所にMutex同期化ロジックを追加しました。なお、Cocos2d-xでもcpBodyを使用するPhysicsBodyに同期化ロジックを追加しました。特にReadの場合は

  • クスコ D1 ロールバー J項改 8点式 品番:666 261 G スバル インプレッサ GDA・GDB アプライドA〜G スペックC共通 サンルーフ無
  • GHEFS/GH5AS/GH5FS アテンザスポーツ (リア) ACRE 800C アクレ (686-F800C フォーミュラ 08/1〜12/11 715 3ドア ロールバー

  • クスコ D1 ロールバー J項改 8点式 品番:666 265 G スバル インプレッサ GDA・GDB アプライドA〜G スペックC共通 サンルーフ無
  • 純正形状フロアマット/ECOモデル/全座席分 (H14/10〜20/11) キューブ/日産 ACR50W/ACR55W クラッツィオ立体フロアマット ET-0290

  • クスコ D1 ロールバー J項改 8点式 品番:692 261 G スバル インプレッサ GH8/GRB
  • BMW カーゴトレイ 1992-1995年 カーゴライナー ブラック ウェザーテック正規品 325i コンバーチブル MINI

  • クスコ D1 ロールバー J項改 8点式 品番:692 261 G スバル インプレッサ GVB
  • ACRE ブレーキパッド 677 (アクレ) 左右セット クラウン フロント GRS184/GRS204/GWS204 トヨタ レーシングプロ 05.10〜12.12 (HYBRID) TY31 Projectμ QJY31

  • クスコ D1 ロールバー J項改 8点式 品番:671 261 G スバル インプレッサ GC8 アプライドモデルE〜G 2ドア・サンルーフ無
  • DEMIO フロアバー DE ACE 【オートクラフト京都】 本革調 送料無料 内装

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:309 270 F20 ホンダ CR-Z ZF1
  • フットレスト:有 SGL5 カロ/KARO ボンゴフレンディ FLAXY 4WD 品番:672 1995年06月〜2001年05月 マツダ フロアマット ZN6 -

  • クスコ D1 ロールバー J項改 8点式 品番:654 265 G スバル ヴィヴィオ KK4 2ドア・サンルーフ無
  • 輸入車用ディスクパッド RAICAM AUDI RA.0429.5 フロントブレーキパッド アウディ 4BAGA 用 A6 ALLROAD RA.0428.0

  • クスコ D1 ロールバー J項改 8点式 品番:658 261 G スバル レガシィ ツーリングワゴン BG5 サンルーフ無
  • H14/4-H18/1 FM/AMドルフィンアンテナ ビートソニック インペリアルアンバー [CAS] FDX4N-CAS モコ TYPE4 ユーロウィンター ブラック/リムポリッシュ オールシーズンタイヤ

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:311 270 F20 ホンダ シビック EK9・EK4 サンルーフ無
  • 車種専用品 品番:ET-0248 トヨタ ノア シートカバー 8人乗 ECT H19/7〜H22/4 クラッツィオ 天野 [カラー:ブラック×イエロー] ダイヤモンド

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:381 290 L20 ホンダ S2000 AP1・AP2 ソフトトップ車
  • プラッツ 1SZ-FE * SCP11 トヨタ U5027 平成11年8月〜 NGK 90919-02240 イグニッションコイル 1000cc 型式 アドヴィックス

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:311 290 F20 ホンダ シビック EK9・EK4 サンルーフ無
  • アルト 98.10〜00.12 (KOYORAD) 17700-76G00 相当品 GF-HA22S * K6A スズキ (M/T車) 純正番号: 江洋ラジエーター 4WD MM42S 【エスペリア/ESPELIR】

  • クスコ D1 ロールバー J項改 8点式 品番:692 265 G スバル インプレッサ GH8/GRB
  • 2名 2ドア サンルーフ アルミ S13 2 シルビア No.2 (P) 111 5P オクヤマ ロールバー ニッサン 803 メッキ カーパーツ M900A/M910A

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:315 290 F20 ホンダ シビック EG6 サンルーフ無
  • NZT260 T302DF 19/6〜 フロントセット アールエスアール アリオン DOWN RS-R ダウンサス 前側 RSR ドアモール 送料無料 メッキ

  • クスコ D1 ロールバー J項改 8点式 品番:654 261 G スバル ヴィヴィオ KK4 2ドア・サンルーフ無
  • インスパイア スーパーダウンサス H1/10〜7/1 フロント用 エスペリア ESPELIR CB5 9CBFS NA

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:313 270 F20 ホンダ CR-X EF7・8 サンルーフ無
  • アルファード RS-R車高調 (年式H20/5〜) 3500cc (型式GGH20W) ベストi 2WD 全長式車高調 Black-i 車高調

  • クスコ SAFETY21 ロールケージ J項改 6点式 品番:428 270 E20M マツダ ロードスター NCEC ソフトトップ車
  • SF5000 7.50-19■SAFFIRO クライメイト 235/35R19■CLIMATE SUW (限定) サフィーロ サマータイヤ ヴィダーラ ホイールセット インセット:38 PCD:114.3 穴数:5

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:420 290 FS20 マツダ RX-7 FC3S サンルーフ付
  • S15 (単品装着不可) フロントバンパー BN 【ボールペンプレゼント!!】 ブリスターキット シルビア Sports パナソニックバッテリー (標準搭載 アルテッツァジータ

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:540 270 F20 ミツビシ FTO DE3A サンルーフ無
  • ガイア 6本スリット アクレブレーキローター (96.05〜01.05) フロント左右セット■適合詳細要確認 SXM15G [4WD] -LUXベージュ フロアマット プロボックス

  • クスコ D1 ロールバー J項改 8点式 品番:608 265 G スズキ アルトワークス HB21S サンルーフ無
  • LS460 VELOCE 06/8〜】 【型式USF45/USF46 ドリルドスリットローター [リア] ブレーキパッド DIXCEL (ディクセル)

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:404 270 FHT マツダ ロードスター NA6/NA8 ハードトップ車
  • グラムライツ VM4 用 トーヨー サマータイヤ ホイールセット4本 アズール LEVORG 57XMA 1770 215/50R17 (KF) 8本セット M40i RACING

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:404 290 FHT マツダ ロードスター NA6/NA8 ハードトップ車
  • S1 ホイールセット 225/50R18■WORK (限定) ワーク 7.50-18■DELINTE DH2 3P マイスター デリンテ サマータイヤ レオニス LEONIS サマータイヤホイール4本セット

  • クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:310 270 L20 ホンダ シビック フェリオ EG8・9 サンルーフ無
  • 送料無料 235/35R19 サマータイヤホイールセット スレイヴ ロジャム グロスカット 純 UZZ40 ◆色番号塗装サービス付◆

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:315 270 F20 ホンダ シビック EG6 サンルーフ無
  • 89.9-93.9 フロント用 Type-MZ クスコ 標準デフ:オープン ST182 1&1.5WAY 3S-FE/3S-GE セリカ MT LSD (1WAY) W01 (4本セット) WAREN

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:302 270 F20 ホンダ シティ GA1/2 サンルーフ無
  • (2016〜) DK系 ウェザーテック WTTS0989 用 Tech (サンシェード) 専用設計テックシェード マツダ CX-3 Weather デミオ 2点 リフレクター

  • クスコ D1 ロールバー J項改 8点式 品番:692 265 G スバル インプレッサ GVB
  • Hardtop ミニクーパー ダブルスポーク Cooper ミニ純正品 MINI ※センターキャップ付き 17インチホイール4本 (シルバー) トラック/バス用 1ペア価格 タイヤチェーン

  • クスコ SAFETY21 ロールケージ J項改 7点式 品番:329 270 F20 ホンダ シビック タイプR FD2
  • コンプリート 51510A リヤ スバル純正部品 「複数種類あり」 のみ BRZ クオータ 51519CA0309P インナレフト の ■略番 XL タイヤ4本 110W

  • オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ 24×10.5J レガシィ BG6Z

    、TryLockを使用してロックがかかっているかをチェックしました。ロックがかかっていれば、リリースされるまで待たずに最新の計算結果を読み込んですぐにレンダリングを行い、別のタスクを処理できるようにしました。また、Cocos2d-xでは、EventDispatcher変数一つでイベントハンドリングを処理します。そのため、メインスレッドでEventDispatcherが発生した際にSimulatorスレッドからアクセスすると、プログラムにエラーが発生する可能性があります。

    この問題の解決には2つの方法があります。一つ目は、Mutexを使用してクリティカルセクションを設定する方法です。二つ目は、Simulatorスレッドに独立したEventDispatcher変数をもう一つ生成する方法です。この設計では、パフォーマンス向上を図るためにMutexを極力使用していません。その代わり、Simulatorスレッドで物理衝突イベントを直接ハンドリングできるように、SimulatorでEventDispatcher変数を宣言し、メインスレッドとコンフリクトせずに独立してハンドリングできるようにしました。つまり、Chipmunkのソースコードに同期化ロジックを追加してビルドし クスコ D1 ロールバー J項改 8点式 品番:670 261 G スバル インプレッサ GC8 アプライドモデルD 2ドア・サンルーフ無、libchipmunk.aライブラリファイルを作成しました。このライブラリを修正されたCocos2d-xのソースコードとともにビルドしてリンクし、最終的にlibgame.soファイルを作成しました。こうすれば、libgame.soファイルを使ってゲームを駆動できるようになります。

    テスト環境

    新たに設計したマルチスレッド構造で物理シミュレーションを行い クスコ SAFETY21 ロールケージ J項改 7点式 品番:420 290 F20 マツダ RX-7 FC3S サンルーフ無、シングルスレッドのときに比べてパフォーマンスがどれほど向上したかをテストしてみました。テスト環境は下表のとおりです。テスト端末はiPhone 5sを使用し、Cocos2d-xのバージョンは3.6、Chipmunk Physics Libraryのバージョンは2.2.2を使いました。

    【表1】 テスト環境

    同期化およびイベントハンドリングのテスト

    物理演算をマルチスレッドで並列処理した場合、同期化およびイベントハンドリングが正常に動作するかを確認するためにテストプログラムを開発しました。テストプログラムは、Cocos2d-xに用意されているContact testの例題を活用しました。

    【図6】 テストプログラム

    【図6】は、テストプログラムで三角形と四角形のオブジェクトを大量に生成したものです。ここで クスコ D1 ロールバー J項改 8点式 品番:671 265 G スバル インプレッサ GC8 アプライドモデルE〜G 2ドア・サンルーフ無、オブジェクト同士が衝突すると跳ね返り クスコ D1 ロールバー J項改 8点式 品番:680 261 G スバル レガシィ ツーリングワゴン BH5 サンルーフ無、画面の上下左右の端にある透明な壁に当たるとまた跳ね返ります。同期化およびイベントハンドリングをテストするために、各オブジェクトが衝突する度にコールバック関数でオブジェクトの色を緑色に変化させました。

    【図7】 物理シミュレーションの結果

    シングルスレッドとマルチスレッドを同じ条件下でシミュレーションしました。その結果、【図7】の(a)と(b)のように両方とも緑色に変化していることを確認できました。オブジェクト同士が衝突して跳ね返るのは、同期化処理が行われたことを意味します。また、衝突したオブジェクトが緑色に変わったのは クスコ D1 ロールバー J項改 8点式 品番:770 261 G ダイハツ ストーリア X4 M112S サンルーフ無 〜2001年11月、イベントハンドリングが正常に動作し、コールバック関数でオブジェクトの色を緑色に変化させたことを意味します。こうして、同期化およびイベントハンドリングが正常に動作することを確認しました。では クスコ SAFETY21 ロールケージ J項改 7点式 品番:322 290 F20 ホンダ インテグラ タイプR DC5 サンルーフ無、次にパフォーマンス測定結果についてご紹介します。

    パフォーマンス測定結果

    既存のシングルスレッドに比べて、新たに開発したマルチスレッドによる物理演算がパフォーマンスをどこまで改善させたのかを測定してみました。

    オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ 24×10.5J レガシィ BG6Z

    ゲームを開発していると、ゲーム自体が遅くなったり、過負荷がかかったりすることがあります。過負荷状態になりゲームのレンダリングの遅延が発生することがあります。その際、マルチスレッドの物理演算がどのような影響を与えるのかをテストしてみました。ゲームに負荷がかかるとCPUの演算量が多くなるので、次のとおりMatrixを複数回乗じた値を過負荷の度合いとして定義しました。

    MAX_UPDATE_COUNT = 300000
     updateForOverhead()
     for i ← 1 to MAX_UPDATE_COUNT
     do dstMatrix ← dstMatrix * srcMatrix
    

    こうすることで、MAX_UPDATE_COUNTという変数を使ってゲームの負荷の度合いを定量的に数値化することができます。

    【表2】 ゲームの負荷によるパフォーマンス測定結果

    シミュレーションされるオブジェクトの数は360個に固定し、ゲームの負荷の度合いを最低30万から最大300万まで上げながらテストしました。【表2】のように、ゲームの負荷の度合いが30万のときは、シングルスレッドとマルチスレッド[Multi(Main) Thread、Simulator Thread]両方ともFPSの最大値として設定した60FPSに達していました。なお、300万のときは、シングルスレッドは9.1FPS、マルチスレッドのメインスレッドは9.7FPSと、ほぼ同等の数値を示していました。しかし、マルチスレッドのSimulatorスレッドでは60FPSとなっていました。

    ゲームの負荷は物理演算と関係なくメインスレッドにかかるので、シングルスレッドもマルチスレッドのメインスレッドもともにパフォーマンスの低下が発生しました。一方、物理演算は、別スレッド(Simulatorスレッド)で動作するのでゲームの負荷による影響は受けず、30万のとき、300万のときいずれも60FPSとなっています。

    【図8】 ゲームの負荷によるパフォーマンス測定結果

    【図8】は、ゲームの負荷の度合いによるパフォーマンス測定結果をグラフにしたものです。シングルスレッドとマルチスレッドのメインスレッドの勾配(赤線・青線)を比較してみると、マルチスレッドのメインスレッドの方がパフォーマンスの低下が緩やかであることが分かります。これは クスコ SAFETY21 ロールケージ J項改 7点式 品番:422 270 F20 マツダ RX-7 FD3S サンルーフ無、シングルスレッドでは物理演算とレンダリングを一つのループで処理するのに対し、マルチスレッドではSimulatorスレッドで物理演算を行うからです。このため、シングルスレッドのようなパフォーマンスの急激な低下は発生しません。

    上記の測定結果はストレステストから得た数値ですが、実際に適用できる有意味な数値が得られるのはどの区間でしょうか。実際に適用できる数値は30FPSであり、ゲームの負荷が90万のときの区間です(【図 8】の青い四角で囲んだ部分)。この区間の数値は、シングルスレッドでは25.3FPS、マルチスレッドのメインスレッドでは31.7FPS、そしてSimulatorスレッドでは60FPSとなっています。

    物理演算をDelta Timeでアップデートするケースを分析してみると、シングルスレッドでは約0.0395秒(25.3FPS)ごとに物理演算を行い、レンダリングします。それに対し クスコ D1 ロールバー J項改 8点式 品番:660 261 G スバル インプレッサ GC8 4ドア・サンルーフ無、マルチスレッドでは、0.0167秒(60FPS)ごとに物理演算を行い、0.0315秒(31.7FPS)ごとにレンダリングします。つまり、マルチスレッドの方が約2.4倍小さい値で細かく物理演算を行うので当たり判定がより正確になる上、より高いFPSでのレンダリングもなめらかになり、クオリティの面で格段の差が出ます。また、Fixed Time値を0.0167秒に設定してFixed Timeでアップデートするケースを分析してみると、シングルスレッドでは約0.0395秒(25.3FPS)ごとに0.0167の値でstep※注4しながら当たり判定の処理およびシミュレーションを行います。

    一方、マルチスレッドでは、約0.0167秒(60FPS)ごとに0.0167の値でstepしながら当たり判定の処理およびシミュレーションを行います。この場合、シミュレーションするstep値が同じなので精度も同じと思われますが、マルチスレッドの方でtickが約2.4倍多く発生するので クスコ D1 ロールバー J項改 8点式 品番:770 265 G ダイハツ ストーリア X4 M112S サンルーフ無 〜2001年11月、シングルスレッドよりシミュレーションが高速化することが分かります。

    過負荷状態での物理演算のパフォーマンス測定結果

    ゲームを開発していると、ゲームロジックまたはグラフィックの問題ではなく、物理演算自体が遅くなることがあります。このように物理演算に負荷がかかった場合、どのような変化があるかをテストしてみました。

    【表3】 物理演算の負荷によるパフォーマンス測定結果

    ゲームの負荷の度合いは30万に固定し、シミュレーションされるオブジェクトの数は最低360個から最大1080個まで増やしながらテストしました。【表3】から分かるように クスコ D1 ロールバー J項改 8点式 品番:670 265 G スバル インプレッサ GC8 アプライドモデルD 2ドア・サンルーフ無、オブジェクトの数が360個のときは、シングルスレッドとマルチスレッド[Multi(Main) Thread、Simulator Thread]両方ともFPSの最大値として設定した60FPSに達していました。一方、1080個のときは、シングルスレッドは12.3FPS、マルチスレッドのメインスレッドは60FPSでした。しかし、マルチスレッドのSimulatorスレッドでは12.5FPSと、シングルスレッドに近い数値を示しています。

    物理演算に負荷をかけたため、シングルスレッドもマルチスレッドのSimulatorスレッドもともにパフォーマンスの低下が発生したのです。それに対し、マルチスレッドのメインスレッドでは、ゲームロジックとレンダリングがSimulatorスレッドとは別に動作するので、物理演算のコストが発生せず、360個のときと1080個のときいずれも60FPSとなっています。

    【図9】 物理演算の負荷によるパフォーマンス測定結果

    【図9】は、物理演算の負荷の度合いによるパフォーマンス測定結果をグラフにしたものです。シングルスレッドとマルチスレッドのメインスレッドの勾配(赤線・青線)を比較してみると、シングルスレッドではパフォーマンスが急激に低下しているのに対し、マルチスレッドのメインスレッドではFPSの最大値である60FPSを維持していることが分かります。なお、Simulatorスレッドではパフォーマンスの低下はあるものの、シングルスレッドほど急激な低下ではありません。シングルスレッドでは物理演算とレンダリングを一つのスレッドで行うのでパフォーマンスが急激に低下しますが、Simulatorスレッドでは物理演算のみ行うので、シングルスレッドよりはパフォーマンスの低下が緩やかになっていることが分かります。

    上記の測定結果はストレステストから得た数値ですが、、実際に適用できる有意味な数値が得られるのはどの区間でしょうか。実際に適用できる数値は30FPSであり、オブジェクトの数が760個のときの区間です(【図9】の青い四角で囲んだ部分)。この区間の数値は、シングルスレッドでは23.6FPS、マルチスレッドのメインスレッドでは60FPS、そしてSimulatorスレッドでは32.2FPSとなっています。物理演算をDelta Timeでアップデートするケースを分析してみると、シングルスレッドでは約0.0424秒(23.6FPS)ごとに物理演算を行い、レンダリングします。それに対し、マルチスレッドでは、0.0311秒(32.2FPS)ごとに物理演算を行い、0.0167秒(60FPS)ごとにレンダリングします。

    つまり、マルチスレッドのときは、別スレッドで0.0311秒ごとに物理演算を並列処理し、メインスレッドで0.0167秒ごとにすでに計算された物理シミュレーション値でレンダリングのみ実行します。そのため、パフォーマンスの面では当たり判定が正確になり、動きがよりなめらかになることを確認できます。また、Fixed Time値を0.0167秒に設定し クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:525 270 L20 ミツビシ コルト バージョンR Z27AG、Fixed Timeでアップデートするケースを分析してみると、シングルスレッドでは約0.0424秒(23.6FPS)ごとに0.0167のstepで当たり判定の処理およびシミュレーションをしてからレンダリングします。一方、マルチスレッドでは、約0.0311秒(32.2FPS)ごとに0.0167のstepで当たり判定の処理およびシミュレーションを行い、0.0167秒(60FPS)ごとにすでに計算された値でレンダリングします。この場合、マルチスレッドの方がシングルスレッドより正確で速いだけでなく、レンダリングFPSが約2.5倍高いため、動きが遥かになめらかになります。

    当たり判定の正確性テスト

    上述の通り、シングルスレッドのときに物理演算をDelta Timeで行う場合、ゲームに負荷がかかるとtickが不安定になって衝突チェックが正確にできない可能性があります。マルチスレッドで物理演算を行った際、当たり判定の正確性がどれほど向上したかをテストしてみました。テストの条件は、実際に適用できる数値、つまりマルチスレッドのメインスレッドとSimulatorスレッドがいずれも30FPSになる状況としました。アップデート方法としては、シングルスレッドではDelta Time方法を使い、マルチスレッドではメインスレッドはDelta Time、SimulatorスレッドはFixed Timeをそれぞれ使用するように設定しました。オブジェクトが壁(Bound Box)にぶつかると跳ね返らないといけないのに、すり抜けてしまうケースがあるかをチェックし、シミュレーションが開始してから経過時間ごとにオブジェクトの数を観察しました。

    【表4】 当たり判定の正確性テスト

    【表4】は、マルチスレッドで物理演算したとき、当たり判定の正確性がどれほど向上したかを測定した結果です。最初はシングルスレッドとマルチスレッド両方ともVertex(頂点)の数が5022個でしたが クスコ SAFETY21 ロールケージ J項改 7点式 品番:460 270 F20 マツダ RX-8 SE3P、15秒後にはシングルスレッドでVertexの数が6個減りました。三角形1個にはVertexが3個あるので、三角形2個が消えたことになります。さらに30秒後には4986個になり、36個が減少しました。これは、三角形12個が消えたと推定できます。一方、マルチスレッドでは、時間が経ってもずっと5022個であり、壁をすり抜けて消えたオブジェクトはなく、正確に当たり判定が行われていることが分かります。

    結論および今後の課題

    以上のとおり、シングルスレッドで動作する物理演算をマルチスレッド化して並列処理する方法について説明しました。結論としては、物理演算をマルチスレッドで並列処理することで、構造とパフォーマンスが改善されたと言えます。構造の面では、既存の物理演算の処理を別スレッドに分離することで、メインスレッドとは独立してFixed Time値、つまり精度を調整しながらシミュレーションできるようになりました。パフォーマンスの面では、マルチスレッドの方で当たり判定がさらに正確化・高速化し、動きがなめらかになることを確認できました。通常ゲームを開発していると、物理演算が遅いため機能をスペックアウトしたり、邪道な方法で実装することもあります。しかし、このように物理演算を並列処理することで、これまでは技術的な限界のため開発できなかったジャンル、新しいコンテンツを開発できる可能性が示されたのではないでしょうか。

    現在、Simulatorはクライアントでのみ動作しますが、これをサーバで分散処理できるようにすれば、大規模なシミュレーションが可能になると思います。また、物理演算のみならず、、ゲームロジックをも並列処理して、大規模な分散ゲームSimulatorを開発してみるのも面白い課題になるかもしれません。それが実現すれば、レンダリングとは別に、、

    、データを中心にゲームをシミュレーションできるゲームバランス調整ツールの開発にも活用できるようになるでしょう。

    Kim Suntae 2016.01.27

    LINEでモバイルゲームの開発を担当しています。

    クスコ D1 ロールバー J項改 8点式 品番:681 261 G スバル レガシィ B4 BE5 サンルーフ無

    オクヤマ ロールバー 715 231 1 スチール ダッシュボード貫通 7P No.7 2名 ホンダ フィット GE8 5ドア ノーマルルーフ 24×10.5J レガシィ BG6Z

    クスコ SAFETY21 ロールケージ J項改 7点式 品番:404 270 F20 マツダ ロードスター N B6/N B8 ソフトトップ車
    クスコ SAFETY21 ロールケージ J項改 7点式 品番:508 290 F20 ミツビシ ランサー CD5A サンルーフ無 クスコ SAFETY21 ロールケージ J項改 7点式 品番:550 270 F20 ミツビシ ミラージュ CJ4A 3ドア・サンルーフ無 クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:560 270 L20 ミツビシ ランサーエボリューション Evo.IV,V,VI CN9A・CP9A サンルーフ無 クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:564 290 L20 ミツビシ ランサーエボリューション Evo.VII,VIII,VIII MR,IX,IX MR CT9A サンルーフ無 クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:566 290 L20 ミツビシ ランサーエボリューション Evo.X CZ4A クスコ SAFETY21 ロールケージ J項改 7点式 品番:608 270 F20 スズキ アルトワークス HB21S サンルーフ無 クスコ SAFETY21 ロールケージ 定員ルーフ 7点式 品番:608 270 L20 スズキ アルトワークス HB21S サンルーフ無 クスコ SAFETY21 ロールケージ J項改 7点式 品番:605 290 F20 スズキ アルトワークス CL・CM11V/CP21S サンルーフ無

    リストへ戻る

    {yahoojp}xt02-myp10-tu2-799 1