view paper/result.tex @ 8:f953f01c58bf

expand
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 07 Feb 2011 16:00:55 +0900
parents 2dcc784d62e0
children d711f469cdb7
line wrap: on
line source

\chapter{バグ検出実験} \label{chapter:result}
\ref{chapter:test} 章で説明したテスト環境を用いて実際に Super Dandy
の OpenGL バージョン、Cerium バージョン、そして Task Dandy の動作が同じに
なるようにデバッグを行った。ここでは、ビデオモードによる実行速度の違いや
カバーしたカバレッジ数、実際に検出されたバグを紹介しながら本研究の評価を
述べる。

\section{検出方法とデバッグ}
まずはじめに OpenGL バージョンの Super Dandy を Capture モードでプレイし、
プレイヤーの入力を保存する。これは OpenGL バージョンが Cerium バージョンと 
Task Dandy の目標とする動作であるからである。
次に Cerium バージョン、Task Dandy を Trace モードで実行し、入力データを
読み込ませる。そして各バージョンそれぞれから得られたテストログを考察すること
でバグの原因を特定し、デバッグを行っていく。

\subsection{OpenGL バージョンと Cerium バージョンの比較}
OpenGL バージョンと Cerium バージョンのテストから生成されたテストログの
比較を行い、違いがあるかどうか検証した。各テストログのデータは unix コマンド
の wc(word count) コマンドで取り、表 \ref{tb:test_log} にまとめた。

\begin{table}[h]
\caption{Super Dandy のテストログの比較}
\begin{tabular}{c|c|c|c} 
\hline
\hline
  & 大きさ & 行数 & 単語数 \\ \hline \hline
Super Dandy(OpenGL) & 349486 byte & 3411 & 37194\\ \hline
Super Dandy(Cerium) & 349471 byte & 3411 & 37195\\ \hline
\end{tabular}
\label{tb:test_log}
\end{table}

2 つのテストログに大きな差異は無いことがわかる。また Super Dandy を 1 回
エンディングまでプレイしたときに作られるテストログの大きさは 約 350 KB と
いうことが分かった。また、以下にこの 2 つのテストログに対して diff を取った
結果を示す。

\newpage

\begin{verbatim}
% diff log/demo_log log/dandy_log
1a2
> Use Joystick
3410,3411c3411,3412
< 83.308451 FPS
< move: average:49usec, peak:1091usec
---
> 0.000000 FPS
> game end
\end{verbatim}

表示されている各パラメータとメッセージは OpenGL や Cerium 依存のメッセージ
である。0.000000 FPS と表示されるのは Cerium 側のメッセージであるが、これは
描画を行わないビデオモードで実行したことにより、正しく FPS が計算
できなかった為と思われる。この結果より Super Dandy の OpenGL バージョンと 
Cerium バージョンの動作は同じであると言える。

\subsection{データの同期問題の検出}
前述の方法でテストを行い、しばらく実行させていると以下のようなテストログが
取れた。

\begin{verbatim}
super dandy >>
F64: CREATE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -128.000000 ...
F85: DELETE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -44.000000 ...
             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
F96: CREATE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -128.000000 ...
F96: CREATE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= -128.000000 ...
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
F64: CREATE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -128.000000 ...
F85: DELETE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -44.000000 ...
             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
F96: CREATE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -128.000000 ...
F96: CREATE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= -128.000000 ...
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
\end{verbatim}

ここで Super Dandy と Task Dandy の 2 つのログを比較したときの特徴を
洗いだすと以下のようになる。

\begin{itemize}
\item Super Dandy では別フレームで被弾した敵オブジェクトが Task Dandy では
  同フレーム内で被弾している
\item 同フレーム内で被弾したときの弾丸の数が一致している
\item それ以外のログは Super Dandy と Task Dandy 共に一緒である
\end{itemize}

こうした結果から 2 つのオブジェクト間で弾丸データの同期が取れていない、と
いう仮説を立てた。Task Dandy では create\_task 時に弾丸データを Property 
として他のオブジェクトデータと共にまとめて set\_inData するようにしているが、
このデータは create\_task 時のデータであり、先に実行された Collision Task 
内でそのデータに変更があったとしても 別の Collision Task で使用するデータに
反映されることはない。

Collision Task 間でデータを同期させるには、Collision Task を同じ CPU に送り、
\ref{sec:global} 節にある global\_alloc で予め衝突判定に必要なパラメータの
領域を LS に確保し、その領域のパラメータで衝突判定を行うと良い。
その後、共用領域のパラメータの変更をメインメモリ側に反映させることで、
弾丸の描画などの処理も正しく行うことが出来る。
(図\ref{fig:collision_reflect})

\begin{figure}[h]
\begin{center}
\includegraphics[scale=0.6]{images/collision_reflect.pdf}
\end{center}
\caption{共用領域による Collision Task の同期}
\label{fig:collision_reflect}
\end{figure}

実際に

\begin{verbatim}
super dandy>>
F64: CREATE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -128.000000 ...
F85: DELETE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -44.000000 ...
             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
F96: CREATE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -128.000000 ...
F96: CREATE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= -128.000000 ...
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
F64: CREATE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -128.000000 ...
F85: DELETE  [NAME]enemy_greenclab_0  [COORD]x= 120.000000  y= -44.000000 ...
             [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0
F96: CREATE  [NAME]enemy_greenclab_1  [COORD]x= 56.000000  y= -128.000000 ...
F96: CREATE  [NAME]enemy_greenclab_2  [COORD]x= 184.000000  y= -128.000000 ...
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
\end{verbatim}

\subsection{Task の依存関係によるバグの検出}

\section{乱数生成の検証}
\ref{sec:create_random} 節で述べた Task への乱数受け渡しの手法が期待通りの
動きをするかどうか、多数の隕石オブジェクトが生成されるステージで全ての隕石
オブジェクトが生成されるのを観察し、検証した。Super Dandy におけるこの
隕石オブジェクトは以下のような実装となっている。

\begin{verbatim}
CHARACTER * chara_state22(CHARACTER *p)
{
  int sf;

  sf = random() % 4;
  if((sf == 0) || (sf == 1))
    {
      p->x = -35;
      p->y = random() % (120 - 35);
      p->vx = (random() % 4 + 1);
      p->vy = random() % 3 + 1;
      p->state = chara_state23;
    }
  if((sf == 2))
    {
      p->x = random() % 290;
      p->y = -30;
      p->vx = random() % 3 - 1;
      p->vy = (random() % 4 + 1);
      p->state = chara_state23;
    }
  if(sf == 3)
    {
      p->x = 320;
      p->y = random() % (120 - 35);
      p->vx = (random() % 4 + 1) * -1;
      p->vy = random() % 3 -1;
      p->state = chara_state23;
    }
  return p;
}
\end{verbatim}

このオブジェクトは乱数によって 3 種類の処理に分かれる。処理の中では xy 座標
、xy 方向の速度が決定し、次の状態へ遷移する、という動作になっている。
そこで、この処理が行われた直後のオブジェクトの座標を記録し、Super Dandy、
Task Dandy 双方のデータに違いがあるかどうか調べた。Task Dandy 側の隕石
オブジェクトの実装は以下のようになっている。

\begin{verbatim}
static int
state22(SchedTask *smanager, void *rbuf, void *wbuf)
{
    int rand1 = (int)smanager->get_param(0);
    int rand2 = (int)smanager->get_param(1);
    int rand3 = (int)smanager->get_param(2);
    int rand4 = (int)smanager->get_param(3);

    CHARACTER *p = (CHARACTER*)smanager->get_input(rbuf, 0);

      int sf = rand1 % 4;
      if((sf == 0) || (sf == 1))
      {
          p->x = -35;
          p->y = rand2 % (120 - 35);
          p->vx = (rand3 % 4 + 1);
          p->vy = rand4 % 3 + 1;
          p->state_task = STATE23;
      }
      if((sf == 2))
      {
          p->x = rand2 % 290;
          p->y = -30;
          p->vx = rand3 % 3 - 1;
          p->vy = (rand4 % 4 + 1);
          p->state_task = STATE23;
      }
      if(sf == 3)
      {
          p->x = 320;
          p->y = rand2 % (120 - 35);
          p->vx = (rand3 % 4 + 1) * -1;
          p->vy = rand4 % 3 -1;
          p->state_task = STATE23;
      }

      smanager->swap();
      return 0;
}
\end{verbatim}

この 2 つを実行したログは以下のようになった。

\begin{verbatim}
demolog >>
[COORD]x= 320.000000  y= 66.000000  vx= -2.000000  vy= 0.000000
[COORD]x= -35.000000  y= 20.000000  vx= 3.000000  vy= 1.000000
[COORD]x= -35.000000  y= 36.000000  vx= 3.000000  vy= 2.000000
[COORD]x= 89.000000  y= -30.000000  vx= 1.000000  vy= 3.000000
[COORD]x= -35.000000  y= 81.000000  vx= 1.000000  vy= 2.000000
[COORD]x= 320.000000  y= 8.000000  vx= -4.000000  vy= -1.000000
[COORD]x= 220.000000  y= -30.000000  vx= 1.000000  vy= 4.000000
....

<< tdandylog
[COORD]x= 320.000000  y= 66.000000  vx= -2.000000  vy= 0.000000
[COORD]x= -35.000000  y= 20.000000  vx= 3.000000  vy= 1.000000
[COORD]x= -35.000000  y= 36.000000  vx= 3.000000  vy= 2.000000
[COORD]x= 89.000000  y= -30.000000  vx= 1.000000  vy= 3.000000
[COORD]x= -35.000000  y= 81.000000  vx= 1.000000  vy= 2.000000
[COORD]x= 320.000000  y= 8.000000  vx= -4.000000  vy= -1.000000
[COORD]x= 220.000000  y= -30.000000  vx= 1.000000  vy= 4.000000
....

% diff demolog tdandylog
%
\end{verbatim}

上記のように、隕石オブジェクトの座標と速度が一致している。

\section{ビデオモードによる実行時間の比較}
\ref{sec:video_none} 節で説明した描画を行わないビデオモードと通常の
ビデオモードで実行時間を計測し、その差がどの程度あるのかを比較した。
実行時間の計測には Unix 環境で使用できる time コマンドを使用し、計測モデル
として Cerium バージョンの Super Dandy と Task Dandy を使用した。
以下が計測結果である。

\begin{table}
\caption{ビデオモードによる実行時間の比較}
\begin{tabular}{c|c|c} 
\hline
\hline
  & Super Dandy(Cerium) & Task Dandy \\ \hline \hline
SDL video mode & 1 & 3\\ \hline
NO video mode & 2 & 4\\ \hline
\end{tabular}
\label{tb:time_table}
\end{table}

\section{カバレッジ数}