view paper/chapter3.tex @ 4:3b3b014765a2

minor change
author sugi
date Wed, 13 Feb 2013 17:33:02 +0900
parents 236628ffc497
children 52dff3fd4f40
line wrap: on
line source

\chapter{Aliceを用いた例題}
\label{chap:poordirection}
AliceのAPIを見直すためには実際にAliceを用いて例題を作成するのが、適切である。この章では実際にAliceを用いて作成された例題を示す。
\section{水族館ゲーム}
Aliceは分散ネットフレームワークである。従って例題を作成するにあたってネットワークを介した例題が適切であると思われる。そこで過去にFedarated Lindaでも作成された水族館ゲームをAliceで実装した。また、Java3D版(図\ref{fig:Java3D})とは別に、新しくJava7に組み込まれたJavaFx(図\ref{fig:JavaFx})を使い水族館ゲームのJavaFx版を作成した。

水族館ゲームとは複数のclientのディスプレイを並べて使用する。アプリケーションを実行するとウインドウが表示され、複数の魚がウインドウの中を泳ぎ始める。魚は画面の端まで移動すると自分の画面上からは消え、隣のプレイヤーの画面の端から出てくる。魚のうち1匹はプレイヤーが操作することができる。トポロジーはAliceのTopologyManagerによってツリー状に構成されている。
\begin{figure}[htbp]
\begin{center}
\includegraphics[width=160mm]{fig/for_3D.pdf}
\end{center}
\caption{java3D版 水族館ゲーム}
\label{fig:Java3D}
\end{figure}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=160mm]{fig/for_FX.pdf}
\end{center}
\caption{javaFX版 水族館ゲーム}
\label{fig:JavaFx}
\end{figure}


\subsection{処理の流れ}
図\ref{fig:NodeToClient}はデータの流れをコラボレーションダイアグラムで示したものである。
\begin{enumerate}
\item ユーザーが魚を操作する。または、PositionController(Code Segment)により魚の座標のData SegmentであるfishPositionが更新される。
\item fishPositionが魚のオブジェクトに座標をセットするためのCode Segment であるSetLocationにreplyされる。SetLocationが実行され画面に反映される。
\item 他のノードに更新されたfishPositionを送信するためのCode SegmentであるUpdateにfishPositionがreplyされる。
\item Updateに自分と接続されているノード一覧のData Segmentであるlistがreplyされる。

\item Updateはlistを参照して、fishPositionを送信する。また、fishPositionには送信元の情報が付加されているので、送信元に対してfishPositionを送り返すことはない。

\item 各clientで2 - 4 が実行され、fishPositionが全体で共有される。 
\end{enumerate}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=150mm]{fig/NodeToClient.pdf}
\end{center}
\caption{データの伝搬の様子}
\label{fig:NodeToClient}
\end{figure}


\section{バイトニックソート}
Aliceはマルチコアが現在に主流になっているという背景を踏まえて設計されている。従って並列処理に対するテストを行った。並列処理に対する例題としてバイトニックソートを実装した。


\subsection{処理の流れ}
指定された数の乱数を生成し、Sortを行う例題である。
また、図\ref{fig:bitonicSort}はSortされるまでの流れをコラボレーションダイアグラムで示したものである。
\begin{enumerate}
\item SetTask (Code Segment)が乱数列を分割してarray1にputする。
\item replyされたDataSegmentをSort (Code Segment)で昇順に整列させる。
\item Sortで整列された数列を更に分割する。上半分をarray1-Fにputする。
\item 下半分をarray1-Bにputする。
\item SetTaskが分割した各数列(array2)に対して2 - 4を行う。
\item replyされた2つのData Segment(array1-B、array2-F)を合体させ、整列させる。
\item 整列の結果を結果の上半分をarray1-B、下半分をarray2-Fにputする。
\item replyされた2つのData Segment(array1-F、array1-B)を合体させ、整列させる。
\item 整列の結果を結果の上半分をarray1-F、下半分をarray1-Bにputする。
\item array2に対しても操作 8 - 9 を行う。
\item 6 - 10 を繰り返し行うことで全体がSortされる。
\end{enumerate}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=150mm]{fig/bitonicSort.pdf}
\end{center}
\caption{Sortの様子}
\label{fig:bitonicSort}
\end{figure}

\section{Aliceのバグ}
データを静的な型に変換する際にMessagePackの使い方が誤っていたため、PermGen Errorを引き起こしていた。


peekまたはtakeで取得したData SegmentはValueオブジェクトであるため、そのままでは使うことができない。
そのため Data Segmentの型を変換する必要がある。それを提供するAPIにasClass()というものがある。
このAPIはユーザーが一般的なクラスを IDLのように用いてデータを表現した場合に使用し、引数として変換したいClassを指定する。(ソースコード \ref{fig:use_asClass})


asClass内部のconvert(ソースコード \ref{fig:PermGenError})で実際に目的の型に変換するが、この際Message Pack のオブジェクトは渡されたClassに対してClass定義を行う。
Class定義の情報はPermanent領域に保存される。
同一オブジェクトであれば、一度定義を行えば次回以降変換する際に再び定義することはない。
しかし、型変換を行うたびにMessagePackのオブジェクトをnewしていた。そのため型変換を行うたびにClassを定義を行なっていたため
Parmanent領域が減っていき、枯渇した際にエラーを引き起こしていた。現在はMessagePackのオブジェクトをSingletonパターンで記述しているためこのエラーは起きない。

\begin{table}[htbp]
\lstinputlisting[label=fig:use_asClass, caption=asClassの使用例]{source/AsClass.java}
\lstinputlisting[label=fig:PermGenError, caption=PermGen Errorを引き起こす]{source/PermGenError.java}
\end{table}

\subsection{注意すべき記述}
Aliceを記述する際に注意すべき記述がある。(ソースコード \ref{fig:NullPointerException})

Code Segmentを作成する際、コンストラクタ内でData Segmentを指定するsetKeyメソッドを呼ぶ。
この際、setKey以降に処理を記述すると、その記述した処理が実行されない可能性がある。

Code Segmentは内部で必要なData Segmentの数の数えている。
Data Segmentが取得されるたびにこの値がデクリメントされていき、0になった時にThread Poolへ送られる仕組みとなっている。
値が0であるかを確認するのは別スレッドであるため、setKey以降に処理を記述すると、その処理が途中であってもThread Poolへ送られてしまい、nullpointerexception等のエラーが起こる可能性がある。記述自体は一般的なjavaの記述であるため一見してわかるものではない。また、データの取得にかかる時間次第で、エラーが出たり、出なかったりするので非常に厄介である。
\begin{table}[htbp]
\lstinputlisting[label=fig:NullPointerException, caption=実行するとNullPointerExceptionを起こす]{source/NullPointerException.java}
\end{table}