# HG changeset patch # User koba # Date 1297061221 -32400 # Node ID 2dcc784d62e0a0b4002affea10505adb7ea4f059 # Parent f59edc38c858ecb37941dab0eb90f6633a010eed add new image; diff -r f59edc38c858 -r 2dcc784d62e0 paper/dandy.tex --- a/paper/dandy.tex Sun Feb 06 01:58:33 2011 +0900 +++ b/paper/dandy.tex Mon Feb 07 15:47:01 2011 +0900 @@ -49,8 +49,33 @@ 敵に当たるか、画面外に消えるまで存在フラグが立つ。 \end{itemize} +これらのデータは オブジェクトの情報として管理されるだけでなく、 +その他のオブジェクトの移動や衝突判定時にも使用される。 + \subsection{Task Dandy の Task} -Task Dandy では + +Task Dandy では オブジェクトの動きや衝突判定をそれぞれ Move Task、Collision +Task として並列に処理させることが出来るように分割している。それぞれの Task は +Super Dandy の Move や Collision が実行されるタイミングで生成され、 +その後処理に必要なデータをセットして各 CPU に送られる。処理を終えた Task は +post\_func により、計算結果をメインメモリ内のデータ領域に反映させ、全ての +Task が終了した時点でゲームの 1 フレームが終了する。 + +\subsection{Property}\label{sec:property} +Task Dandy の Task は処理のために、複数のデータを set\_inData する +必要がある。特に Collision Task に使用するデータはオブジェクト自身の情報の +他にプレイヤーの機体、プレイヤーの出した弾など、種類が多く、全てを set\_in +Data するとコードが無駄に長く、煩雑になってしまう。そこで必要なパラメータを +Property という構造体にコピーする。こうすることで多くのパラメータを 1回の +set\_inData で送ることが出来る。(図\ref{fig:property}) + +\begin{figure}[h] +\begin{center} +\includegraphics[scale=0.7]{images/property.pdf} +\end{center} +\caption{Property のデータ構造} +\label{fig:property} +\end{figure} \subsection{SPE における状態遷移} SPE では各々に固有の LS を持つ\ref{sec:spe}為、Super Dandy で使用していた @@ -160,13 +185,12 @@ 実装した。index にはサイズを変更したいバッファの番号を入れ、size には新たに 設定するバッファサイズを入れる。 -write buffer は Task 実行前に allocate されるが(図\ref{fig:set_w1})、 +write buffer は Task 実行前に allocate されるが、 Task 内で set\_outputSize をすることで set\_outData で設定されたサイズを書き 換える。そして事前に allocate された write buffer を free し、新たに設定 されたサイズで write buffer を allocate することで可変長な output Data を -定義している。 -(図\ref{fig:set_w2}) - +定義している。(図\ref{fig:set_w2}) +\if0 \begin{figure}[h] \begin{center} \includegraphics[scale=0.7]{images/set_wbuf1.pdf} @@ -174,6 +198,7 @@ \caption{Task 実行前の allocate} \label{fig:set_w1} \end{figure} +\fi \begin{figure}[h] \begin{center} diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/collision_double.bb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/images/collision_double.bb Mon Feb 07 15:47:01 2011 +0900 @@ -0,0 +1,5 @@ +%%Title: ./images/collision_double.pdf +%%Creator: extractbb 20100328 +%%BoundingBox: 0 0 579 577 +%%CreationDate: Mon Feb 7 15:09:47 2011 + diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/collision_double.pdf Binary file paper/images/collision_double.pdf has changed diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/collision_reflect.bb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/images/collision_reflect.bb Mon Feb 07 15:47:01 2011 +0900 @@ -0,0 +1,5 @@ +%%Title: ./images/collision_reflect.pdf +%%Creator: extractbb 20100328 +%%BoundingBox: 0 0 559 628 +%%CreationDate: Mon Feb 7 15:34:48 2011 + diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/collision_reflect.pdf Binary file paper/images/collision_reflect.pdf has changed diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/property.bb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/images/property.bb Mon Feb 07 15:47:01 2011 +0900 @@ -0,0 +1,5 @@ +%%Title: ./images/property.pdf +%%Creator: extractbb 20100328 +%%BoundingBox: 0 0 580 326 +%%CreationDate: Mon Feb 7 14:42:46 2011 + diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/property.pdf Binary file paper/images/property.pdf has changed diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/set_wbuf2.bb --- a/paper/images/set_wbuf2.bb Sun Feb 06 01:58:33 2011 +0900 +++ b/paper/images/set_wbuf2.bb Mon Feb 07 15:47:01 2011 +0900 @@ -1,5 +1,5 @@ %%Title: ./images/set_wbuf2.pdf %%Creator: extractbb 20100328 %%BoundingBox: 0 0 555 677 -%%CreationDate: Sat Feb 5 15:13:35 2011 +%%CreationDate: Mon Feb 7 12:55:25 2011 diff -r f59edc38c858 -r 2dcc784d62e0 paper/images/set_wbuf2.pdf Binary file paper/images/set_wbuf2.pdf has changed diff -r f59edc38c858 -r 2dcc784d62e0 paper/result.tex --- a/paper/result.tex Sun Feb 06 01:58:33 2011 +0900 +++ b/paper/result.tex Mon Feb 07 15:47:01 2011 +0900 @@ -1,8 +1,283 @@ -\chapter{検出実験} \label{chapter:result} +\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 -\section{実行環境} +<< 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{カバレッジ数} -\section{検出されたバグ} -\section{評価} diff -r f59edc38c858 -r 2dcc784d62e0 paper/test.tex --- a/paper/test.tex Sun Feb 06 01:58:33 2011 +0900 +++ b/paper/test.tex Mon Feb 07 15:47:01 2011 +0900 @@ -1,9 +1,9 @@ \chapter{テスト環境の構築} \label{chapter:test} 本研究では、逐次型プログラムとして Super Dandy の OpenGL バージョン、Cerium の Rendering Engine のみを使用したバージョンを用意した。これらと Task Dandy -を用いてその挙動をテストし、全てのバージョンにおいて全く同じ動作となる事を -目指した。ここではテストを進める過程で追加した機能とテスト環境について -説明する。 +を用いてその挙動をテストし、全てのバージョンにおいて同じ挙動をしている事を +確認できるテスト環境を構築する。ここではテスト環境のために追加した機能に +ついて説明する。 \section{Capture モードと Trace モード} ゲームにおいてプレイヤーからの入力は制御不能なランダム要素であり、 @@ -32,7 +32,7 @@ \begin{figure}[h] \begin{center} -\includegraphics[scale=0.8]{images/pad_buff.pdf} +\includegraphics[scale=0.6]{images/pad_buff.pdf} \end{center} \caption{TraceBuff} \label{fig:pad_buff} @@ -43,7 +43,7 @@ 読み込むことも可能である。これにより、両バージョンで異なる動きが見られた 場合、そこにバグが潜んでいると仮定することができる。 -\section{乱数生成} +\section{乱数生成}\label{sec:create_random} 乱数のランダム性はバグの再現性を落とすが、乱数生成器を無効にするか、定数で シードすることによって再現性を下げることなく、テストすることが出来る (\ref{sec:random}節)。 @@ -64,21 +64,21 @@ 依存関係を持たせない限り、Task の実行順序が保証されないのでこれも受け取る 乱数が不定となる原因となる。(図\ref{fig:spe_random}) +\begin{figure}[h] +\begin{center} +\includegraphics[scale=0.4]{images/spe_random.pdf} +\end{center} +\caption{SPE 内での乱数の生成} +\label{fig:spe_random} +\end{figure} + +\newpage + そこで予め PPE 内で乱数列を生成し、inData として Task に渡しておく。 Task Dandy では Task の生成、定義がされるタイミングは Super Dandy における Move 関数や Collision 関数が実行されるタイミングと同じである為、渡される乱数 は Super Dandy と同じ乱数となる。(図\ref{fig:ppe_random}) -\newpage - -\begin{figure}[h] -\begin{center} -\includegraphics[scale=0.5]{images/spe_random.pdf} -\end{center} -\caption{SPE 内での乱数の生成} -\label{fig:spe_random} -\end{figure} - \begin{figure}[h] \begin{center} \includegraphics[scale=0.5]{images/ppe_random.pdf} @@ -87,6 +87,21 @@ \label{fig:ppe_random} \end{figure} +\section{テストログとそのタイミング} +シーケンシャルなプログラムを Task に分割して並列実行する際に、新たに発生する +バグとして、本研究では以下の項目に焦点を当てた。 + +\begin{itemize} +\item Task 間のデータの同期 +\item Task の実行順序 +\item Task の定義 +\end{itemize} + +このうち、Task の定義については、定義される内容が非常に小さい為、Task の +inData や outData を調べるといった従来の単体テストでも十分にテストが可能で +ある。その他の 2 つについては、いずれも衝突判定の際に生じるバグである。 +(図\ref{fig:test_log}) + \newpage \begin{figure}[h] @@ -97,20 +112,6 @@ \label{fig:test_log} \end{figure} -\section{テストログとそのタイミング} -シーケンシャルなプログラムを Task に分割して並列実行する際に、新たに発生する -バグとして、本研究では以下の項目に焦点を当てた。(図\ref{fig:test_log}) - -\begin{itemize} -\item Task 間のデータの同期 -\item Task の実行順序 -\item Task の定義 -\end{itemize} - -このうち、Task の定義については、定義される内容が非常に小さい為、Task の -inData や outData を調べるといった従来の単体テストでも十分にテストが可能で -ある。その他の 2 つについては、いずれも衝突判定の際に生じるバグである。 - そこで、オブジェクトが被弾した時、そしてオブジェクトが生成された時にテスト ログを取ることで効率的にバグを発見することができると考えた。以下に実際に 収集したテストログの例を示す。 @@ -120,11 +121,13 @@ 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 - [TAMA]lv1 = 2, lv2 = 0 [LASER]lv1 = 0 + [BULLET]tlv1 = 2, tlv2 = 0 llv1 = 0 \end{verbatim} それぞれのパラメータの詳細は次のとおりである。 +\newpage + \begin{itemize} \item F64,F85\\ 生成、もしくは被弾した時の経過フレーム。 @@ -136,7 +139,7 @@ るのでどのオブジェクトの情報なのかを特定できる。 \item COORD\\ オブジェクトのxy座標とxy方向の速度。 -\item TAMA,LASER +\item BULLET その瞬間に画面内に存在した弾の数。差異があれば同期が取れていないことを 示す。 \end{itemize} @@ -158,7 +161,7 @@ そこでテスト用に画面の描画処理を行わないモードを Cerium に実装した。 これは、Cerium 内で画面のバッファを確保する処理をしている箇所と、描画用の Task を生成する処理をしている箇所をスルーすることで描画処理と無駄なメモリ -確保を行わないビデオモードである。(図\ref{fig:video_none}) +確保を行わないビデオモードである。\ref{fig:video_none} \begin{figure}[h] \begin{center} @@ -173,5 +176,5 @@ \includegraphics[scale=0.8]{images/video_none.pdf} \end{center} \caption{描画処理を行わないビデオモード} -\label{fig:vodeo_none} +\label{fig:video_none} \end{figure}