# HG changeset patch # User koba # Date 1299579466 -32400 # Node ID b7b8c63078955360a717449905bf724ffcb82a1f # Parent 7e707cabd73a52643cf8f690bda4864fd5ab8325 finish. diff -r 7e707cabd73a -r b7b8c6307895 presen/graffle/collision_uml.graffle Binary file presen/graffle/collision_uml.graffle has changed diff -r 7e707cabd73a -r b7b8c6307895 presen/images/collision_uml.png Binary file presen/images/collision_uml.png has changed diff -r 7e707cabd73a -r b7b8c6307895 presen/sigss-presen.html --- a/presen/sigss-presen.html Mon Mar 07 00:38:23 2011 +0900 +++ b/presen/sigss-presen.html Tue Mar 08 19:17:46 2011 +0900 @@ -30,7 +30,7 @@ @@ -66,19 +66,15 @@

研究要旨

    -
  • 我々は PlayStation3(以下 PS3) のマルチコアアーキテクチャ Cell B.E を用いて - 並列処理を行うゲームフレームワーク Cerium を開発した。Cerium では - プログラムを Task という単位に分け、Cell B.E に渡して並列処理を行う。
  • -
  • シーケンシャルなプログラムを Task に分割して並列実行させても、 - データの同期や実行順序の違いなどにより逐次実行させた時と同じ動作をするとは - 限らない。また、ゲームプログラムにはプレイヤーの入力や乱数などの非決定的な - 要素が多く、バグの再現性が低い。
  • +
  • 当研究室のPlayStation3用マルチコア並列ゲームフレームワーク Cerium ではプログラムをTaskという単位に分割して並列処理を行う。 +
  • Ceriumに既存の逐次型のゲームを移植すると、Taskの並列実行による非決定的な実行により、同じ動作にならない場合がある。 +
  • ゲームプログラムにはプレイヤーの入力や乱数などの非決定的要素が元々入っており、単純な動作比較ではうまくいかない。
    -
  • 本研究ではシーケンシャルなゲームプログラムを逐次実行した時と Task に分割 - した時の動作が同一である事を確認できるテスト環境を構築する。 - ゲームプログラムにおける非決定的な要素を固定化し、ゲームの状態遷移時に - おいてバグの検出を行うことで並列実行時のバグを発見する。
  • -
  • ゲームの状態数を数え上げ
  • +
  • 本研究ではプログラムの実行ログを取得し移植時の動作の比較を行う。 +
  • そのために入力と乱数による非決定的な要素の固定化を行った。 +
  • 並列実行はCeriumのFifo実行機能を用いて決定的な動作を実現した。 +
    +
  • Super Dandyというシューティングゲームに本方法を適用し実用的な時間内での動作比較を行うことができた。
@@ -96,22 +92,19 @@ 繋がっている --->

Game Framework Cerium

-

オブジェクトの管理や描画、Task の管理を行う

-
-
SceneGraph
-
オブジェクトのパラメータやポリゴン情報を tree 構造のノードで管理
-
Rendering Engine
-
3 種類の Task によって並列に描画処理を行う
-
TaskManager
-
Task を動的に SPE へ割り振るカーネルとして振舞う
-
+

プログラムを Task と呼ばれる分割された単位で管理する

+ +
+

独自の RenderingEngine により、Task を用いた描画処理を行うことが出来る

- - -
+

シューティングゲーム Super Dandy

+ + +
+
    +
  • PS2上の全5 ステージのボリュームのあるシューティングゲーム +
  • PS3上に移植する際にTask分割して並列実行を行うようにする +
  • ゲームオブジェクトはSceneGraph上に以下のState Patternを用いて構築されている +
  • State Pattern一つ一つをTaskとして実装する +
      +
    • オブジェクトの移動(Move) +
    • 衝突判定(Collision) +
    • ステージ毎のオブジェクト生成(Schedule) +
    +
+
+ +
+
+ +

ゲームプログラムの特徴

- +
    -
  • オブジェクトの生成、衝突などにより状態が遷移
  • -
  • プレイヤー入力、乱数などの非決定的な要素が多い
  • -
    -
  • テストプログラムとして我々が開発したシューティングゲーム - SuperDandy を用意
  • -
  • 全 5 ステージという、ある程度のボリュームのあるゲーム
  • -
- +
    +
  • 自機や敵機、弾丸などの様々な種類のオブジェクトがある
  • +
  • プレイヤーの入力により、自機が移動したり弾丸オブジェクトが生成されるなど、ゲームに影響を与える
  • +
  • オブジェクト同士が衝突したり、生成されることでゲームの状態が変化する
  • +
  • プレイヤー入力、乱数などの非決定的な要素により、テストの再現性が低下する
  • +
+
+
+

Task Dandy(Super Dandy Task version)

@@ -246,7 +256,7 @@ @@ -254,14 +264,109 @@
+--> + +
+

目標とするテスト環境

+ +
+ + + +
+

プレイヤー入力の固定化の実装

+
+ +
+
    +
  • プレイヤーからの入力を 1 フレーム毎に記録する
  • +
  • 書き出したファイルを読み込むことで過去のプレイヤー入力を再現できる
  • +
  • 旧バージョンの入力を記録し、新バージョンで読み出すことができる
  • +
  • 入力が同じでも動作が違えばそこにバグが潜んでいると考えられる
  • +
+
+ + + + @@ -295,33 +400,10 @@ - -

並列処理のバグを検出するタイミング

    -
  • ゲームの並列処理によるバグは主に衝突判定時に検出される
  • +
  • ゲームの並列処理によるバグは主に衝突判定時に検出できる
  • ゲームプログラムの状態が遷移する時、バグが検出される
  • ゲームの状態が遷移する時(オブジェクトの削除・生成)、テストログを書き出すことにより、 並列処理のバグを洗い出す
  • @@ -333,147 +415,45 @@ F64: CREATE [NAME]enemy_greenclab_0 [COORD]x= 120.000000 y= -128.000000 vx= 0.000000 vy= 4.000000 F85: DELETE [NAME]enemy_greenclab_0 [COORD]x= 120.000000 y= -44.000000 vx= 0.000000 vy= 4.000000 - [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0 + [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
- - -
-

プレイヤー入力の固定の実装

-
- -
-
    -
  • プレイヤーからの入力を 1 フレーム毎に記録する
  • -
  • 書き出したファイルを読み込むことで過去のプレイヤー入力を再現できる
  • -
  • 旧バージョンの入力を記録し、新バージョンで読み出すことができる
  • -
  • 入力が同じでも動作が違えばそこにバグが潜んでいると考えられる
  • -
-
+

SuperDandyの逐次実行と並列実行の比較

+
+super dandy >>
+F109: DELETE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -24.000000 ...
+              [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
+F117: DELETE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= 40.000000 ...
+              [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
 
-
-

SPE 内での予測可能な乱数の使用

- - - - - -
    -
  • シーケンシャルプログラムでは 1 つの乱数列から順番に乱数を取得
  • -
  • Cell における並列プログラムでは各 SPE 内で 独自の乱数列を生成
  • -
  • シーケンシャルと並列で異なる結果が出る
  • -
- -
-
- -
-

SPE 内での予測可能な乱数の使用

- - - - - -
    -
  • あらかじめ PPE 内で乱数列を生成しておく
  • -
  • 入力データとして Task に渡す
  • -
  • Task の生成タイミングは Super Dandy の Move や Collision と同じ
  • -
  • Super Dandy と同じ乱数が使用できる
  • -
- -
-
- - - -
-

バグの検出方法

+<< task dandy +F109: DELETE [NAME]enemy_greenclab_1 [COORD]x= 56.000000 y= -24.000000 ... + [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0 +F109: DELETE [NAME]enemy_greenclab_2 [COORD]x= 184.000000 y= -24.000000 ... + [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0 +
-

SuperDandy と TaskDandy の比較

-
-super dandy >>
-F109: DELETE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -24.000000 ...
-             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
-F117: DELETE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= 40.000000 ...
-             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
-
-<< task dandy
-F109: DELETE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -24.000000 ...
-             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
-F109: DELETE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= -24.000000 ...
-             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
-
- -
- -
-

Collision Task 間でのデータの同期

+

Collision Task間でのデータの同期

    -
  • Collision Task を同じ CPU に送る
  • -
  • 予め衝突判定に必要なパラメータの領域を確保する
  • -
  • その領域のパラメータで衝突判定を行う
  • -
  • SPE 内で変更されたパラメータをメインメモリ側に反映させる
  • +
  • 予め衝突判定に必要なデータをCPUに送っておく
  • +
  • Collision Taskを同じCPUに送る
  • +
  • Taskで送られたデータを用いて衝突判定を行う
  • +
  • 同じCPU上なのでCollision Task間でパラメータの共有ができる
- +
@@ -495,13 +475,14 @@ [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
-

隕石オブジェクトによる乱数の検証

+

ゲーム内の乱数のテストへの影響

   int sf = random() % 4;
 
@@ -522,17 +503,49 @@
       .....
 
+

PS3での予測可能な乱数の使用

+ + + + + +
    +
  • シーケンシャルなゲームプログラムでは 1 つの乱数列から順番に乱数を取得
  • +
  • PS3におけるTaskによる並列実行では各CPU内で独自の乱数列を生成
  • +
  • 逐次実行と並列実行で異なる乱数を使用するので、実行した結果が異なる
  • +
+ +
+
+ +
+

PS3での予測可能な乱数の使用

+ + + + + +
    +
  • あらかじめメインのCPU内で乱数列を生成しておく
  • +
  • Taskを生成した際に列から乱数を取得し、渡しておく
  • +
  • Taskの生成タイミングはSuper DandyのMoveやCollisionと同じ
  • +
  • Super Dandyと同じ乱数が使用できる
  • +
+ +
+
+ +

実行結果

-demolog >>
+super dandy >>
 [ID]1  [COORD]x= -35.000000  y= 20.000000  vx= 3.000000  vy= 1.000000
 ...
 [ID]6  [COORD]x= 220.000000  y= -30.000000  vx= 1.000000  vy= 4.000000
@@ -540,15 +553,16 @@
 [ID]11  [COORD]x= -35.000000  y= 57.000000  vx= 3.000000  vy= 3.000000
 ...
 
-<< tdandylog
+<< task dandy
+[ID]1  [COORD]x= -35.000000  y= 20.000000  vx= 3.000000  vy= 1.000000
 [ID]6  [COORD]x= 220.000000  y= -30.000000  vx= 1.000000  vy= 4.000000
 [ID]11  [COORD]x= -35.000000  y= 57.000000  vx= 3.000000  vy= 3.000000
-[ID]1  [COORD]x= -35.000000  y= 20.000000  vx= 3.000000  vy= 1.000000
 ...
 
@@ -565,7 +579,7 @@

描画の有無による実行時間の比較

-

プレイヤー入力の固定化により描画処理を省略することができる

+

プレイヤー入力の固定化により描画処理を省略し、テストを高速に行うことができる

@@ -585,18 +599,20 @@

まとめ

- +

本研究では並列環境におけるゲームプログラムのテスト手法を提案した

    -
  • ゲームにおけるランダム要素であるプレイヤー入力、乱数生成を固定化した
  • -
  • ゲームの状態遷移時におけるバグの検出を行った
  • -
  • 描画の除去によるテストの高速化を行った
  • -
    -
  • ゲームの状態遷移数を数えることにより、ゲーム内の全ての状態をテストできる
  • -
  • 並列環境上における、ゲームプログラムのテストを自動化する事が可能
  • -
  • 今後はゲームの状態遷移数の数え上げを行う
  • +
  • ゲームにおける非決定的な要素であるプレイヤー入力、乱数生成を固定化し、 + Single Trace の再現性を保証した
  • +
  • ゲームの状態遷移時においてテストログを出力することにより、 + シーケンシャルなプログラムを Task に分割し、並列実行した時に + 発生するバグを検出、修正した
+
+

今後の課題

+
    +
  • プログラムのカバレッジのカバー、およびカバー率の測定を行う +
  • ゲームの状態遷移を数え上げることにより、ゲームの動作全体の比較を可能にする
  • +
- -