++\section{切断時の処理}+MMORPGでは、試合の最中にサーバーからユーザーが切断された場合、自動的にユーザーが操作するキャラクターをゲーム開始時の位置に戻すという処理が実行される。+同様にTreeVNCでは切断を検知した場合、LostParentというメッセージがトップノードに対して送信される。++以上の例のように、アプリケーションはノードの切断に対する処理を用意したい場合がある。+しかし、Aliceを用いたアプリケーションの場合、アプリケーション側で検知するのは難しい。DSMに対してwriteまたはreadを行った際に出るExceptionにより判断することができる。Segmentを実行するThreadで行われない。Segment内でExceptionを捕まえられず、例外処理を行なうことができない。(ClosedEventManager)を追加した。Segmentを指定できる。\ref{src:CatchClosedEvent})。Segmentを追加記述する事ができる。Segmentは実行されない。++\section{Topologyの再構成}+ノードは永続的にアプリケーションに参加し続ける訳ではない。目的を果たすとアプリケーションから離脱する。+Topology次第では、アプリケーションに支障をきたす。+例えば、AliceVNCは木構造であるため、子ノードを持つノードがアプリケーションから離脱した場合、その子ノードに対してデータを送信することができなくなる。++この問題を解決するには、アプリケーションからノードが切断するたびにTopologyの再構成を行なう必要がある。Managerに、Topologyの再構成を行う機能を追加した。\ref{fig:TopologyFIx2}、\ref{fig:TopologyFIx3}はTopologyの再構成をコラボレーションダイアグラムで表したものである。Managerに対して切断したノードの情報がputされる。Managerに対してNode1の情報をputする。Managerは最後にアプリケーションに参加したNode6とその親Node2に対して互いを切断するための準備を行わせる、CLOSEMESSAGEをputする。切断する準備ができるとお互いに準備完了を知らせるCLOSEREADYをputする。DSMが使用不可能になる。Node1、Node3、Node4に対してNode6の情報を送り、接続を行わせる。Node6に対して、Node1、Node3、Node4の情報を送り、接続を行わせる。DSMが利用可能になる。+\end{enumerate}++\section{再接続の処理}+MMORPGでは、試合の最中に障害などによりサーバーから離脱したユーザーが、試合が終わるまでに再びサーバーに接続してきた場合に、再びその試合に参加できるような再接続の処理が用意されている。++分散にアプリケーションでは、MMORPGの例のように再接続してきたノードに対して通常の処理とは別の処理を行わせたい場合がある。Segmentを実行できる機能を追加した。Segmentを指定することができる。Nodeの情報の一覧にして表示する接続先自動検索システムという機能がある。この機能によりTreeVNCの起動の際にIPアドレスを入力する手間を省くことができる。+その機能を実現するためにはMulticastに対応する必要がある。Segmentを追加した。Segmentを図で表したものである。Dの3つのnodeに対してデータがputされる。同様にTakeを行うと3つのnodeからTakeに対する応答が来る。SegmentはUDPを用いて実装されている。1つのUDPのパケットで運ぶことのできるデータが、65507bytes(65535bytesからIPヘッダの最低サイズ20bytesとUDPのヘッダのサイズ8bytesを引いた大きさ)である。Segmentが持たない。Segmentを利用する際には、データのサイズを65507bytes以下にしなければならない。DSM同様Managerを経由して操作を行う。Segmentに対する送受信用のスレッドが作成される。DSMへのアクセスするためのkeyを指定できる。第2引数はマルチキャストアドレスを、第3引数はポート番号を、第4引数はネットワークインターフェイスを指定する。第5引数はSocketTypeを指定する。Both}が存在する。Sender}を指定した場合は、第2引数で指定したマルチキャストアドレスに対して送信処理を行うスレッドを作成する。Receiver}を指定した場合は、第2引数で指定したマルチキャストアドレスに対して送信されたデータを受信するスレッドを作成する。Both}は、送受信両方のスレッドを作成する。Segmentは自動では作成されないため、ユーザー自身で作成する必要がある。Segmentを利用した例題である。DSMを作成し、それに対して数字データを10回putしている。{src:Receivemessage})。\label{chapter:chapter4}+分散フレームワークAliceは、並列環境にも対応したフレームワークである。Segmentの更新のオーバーヘッドにより、期待した効果を得ることができなかった。AliceVNCを開発する際にAliceの送受信部分に無駄なコピーが発見された。+これらを解決するためにAliceに改善を行った。seda}とはマルチコアスレッドを用いて大量の接続を管理し、受け取ったデータを処理ごとに分けられたステージと呼ばれるスレッドに投げ、処理が終わると次のステージにデータを伝搬させていく処理方式である。+スループット重視のでありレスポンスは多段のパイプラインのせいで遅れてしまう。+Aliceに置いてSEDAを実装するにあたり、データを次のステージにへ伝搬する際、LinkedBlockingQueueを使用している。LinkedBlockingQueueは片方向の連結リストをベースとしたQueue実装である。dequeueの操作時の排他制御にはそれぞれ別々のロックオブジェクトが使用されている。そのため、enqueueとdequeueが重なってもロック解除待ちは発生しないが、そのかわりに連結リストのNodeオブジェクトの生成操作などが発生してしまうため、enqueue操作の処理コストが高い。+さらに、非力なマシーンではSEDAの効果を得られず、スレッドを切り替えが頻繁に起こりオーバーヘッドになってしまう。Segmentに対して操作をする際はSEDAを使用せず処理を行なうように変更した。Segmentをセットするステージ(peekとtakeの場合)の2段または3段のパイプラインで構成されていた。これらを1つのステージにまとめて処理することで、並列環境における性能を向上させた。Segmentが毎回新しく作成される。出力するデータのコピーが行われる。Segmentとして出力する場合、コピーを行なうのは無駄である。そこで、このコピーを減らすことで速度改善を行った。yutaka:2011b}でも良好な結果を得ているflipを用いた。SegmentをswapさせるAPIである。SegmentはTaskが実行された段階ですでに用意されている。Segmentに書き込む前にflipを呼ぶ。SegmentであるReceiverをflipメソッドに引数として渡すことで、無駄なコピーを減らす。JaveのValueオブジェクトのみを用いて表現していた。Packのバイナリにシリアライズできる型のみで構成されたJavaのオブジェクトであり、自己記述形式のデータ形式となっている。そのため、ArrayValueを用いることにより、ユーザーはデータを後からつなげたりすることも可能である。++このValueオブジェクトの特徴の1つに、通信に関わる際のシリアライズ・デシリアライズを高速に行えることがある。Segmentに対する通信の高速化を狙っていた。Segmentに対する通信においては逆効果である。Segmentに対してputするたびにValue型に変換するコストがかかる。データをpeekする際にもValue型から元の型に変換するというコストがかかる。++この問題を解決するために、一般的なJavaのクラスオブジェクトでもデータ表現を可能にした。Segmentに対してputする場合にのみValueに変換する。これにより、無駄な変換コストを抑えられるようになった。{section:AliceVNC}で説明したように、当研究室で開発しているTreeVNCを分散フレームワークAliceを用いて実装した画面共有システムである。Segmentに送信する。PackによりValue型に変換し、その後シリアライズ化(byteArrayで表現されたバイナリに変換)される。Nodeは受信するとデシリアライズしValue型に変換した後putされる。++このValue型への変換が問題である。受け取ったデータを自分の子ノードに対して送信する際には、デシリアライズしValue型に変換する必要はない。シリアライズ状態のまま子ノードに送信すれば、Value型に変換するオーバーヘッドとValue型をシリアライズするオーバーヘッドを無くすことができる。そこで、Remoteからputされたデータ表現をValue型からbyteArrayで表現されたbinaryに変更した。Remoteにputする際にもValue型に変換せずに直接byteArrayに変換するように変換した。+++しかし、この変更で新しい問題が発生した。Remoteからputされたデータは必ずbyteArrayで表現される。putされたbyteArrayが全てシリアライズ化された状態であるとはいえない。一般的なJavaのクラスオブジェクトとしてbyteArrayが使用されている場合が存在する。AliceVNCで使われる画像データはbyteArrayで表現されているが、これはLocalからputされている。asClass()}というメソッドがある。Packを使い適切な型に変換するものである。byteArray型に変更したため、変換可否を判断することができなくなってしまった。++ここからわかることは、データを表現するにはデータ単体をやりとりするだけでは不十分ということである。変更以前はValue型であるということが状態を表していた。一般的なJavaのクラスオブジェクトとbyteArrayで表現されたbinaryが混在する現在では、データと一緒にデータの状態を表すメタデータもやりとりする必要がある。そこで、データとデータの状態を1つのオブジェクトにまとめ扱うように変更した。val}がデータ本体が保存格納される。byteArray}がデータの状態を表すメタデータである。serialized}+は、データ本体がシリアライズ化されているかを示す。byteArray}がデータ本体がbyteArrayであるかを示す。asClass()}を使い、適切に変換することができる。byteArray}のみtrueの場合)は、目的のClassにcastする。Packを使い変換する。PackのUnpackerを用いる事により、ストリームを次から次へとデシリアライズすることができる。+しかし、提供されているAPIは全てデシリアライズを行うものであり、シリアライズ状態のオブジェクトを取得することができない。そこでUnpackerにシリアライズ状態のオブジェクトを取得するメソッドを追加した。Segmentに追加する処理である。+getSerializedByteArrayメソッドでシリアライズ状態のオブジェクトを取得している。++このメソッドの実装をもって、受け取ったデータをデシリアライズせずに、子ノードに渡すことが可能となった。Packによりシリアライズ化したものが送信される。+つまり、CommandMessage.classがパケットの構造を表すものといえる。{src:CommandMessageBefore}が変更前のCommandMessageの内容である。表\ref{tb:variable}はCommandMessageの各変数が何を表しているかを示したものである。\hline+\end{tabular}+\end{center}+\end{table}++このパケット構造に問題が存在する。DS本体はCommandMessageがシリアライズ化されるときにはすでに、シリアライズされている。このままCommandMessageをシリアライズ化を行うと、DS本体をもう1度シリアライズ化を行ってしまう。caption=変更後のCommandMessage]{source/CommandMessage.java}+\end{table}++そこで、CommandMessageをソースコード\ref{src:CommandMessage}のように変更した。データ本体をCommandMessageのフィールドから外し、後からByteBufferにまとめることにより2度のシリアライズを防ぐ。caption=ByteBuffer作成部分]{source/CreateByteBuffer.java}+\end{table}++この実装ではCommandMessage部をヘッダーとして扱っている。UPDATE、PUT、REPLY}の時のみ後から付加される。以前の実装ではbyte[]の値としてnullを示すNilValueがあるものとしてシリアライズ化されており、これもオーバーヘッドである。UPDATE、PUT、REPLY}以外はの時は、データ部をシリアライズ化しないため、nullをシリアライズ化するオーバーヘッドはなくなっている。Lindaとの性能比較を行い、評価を行う。TreeVNCとAliceVNCの比較をコードの観点からも評価を行う。++\section{機能の確認}+水族館の例題でノードを意図的に切断した結果トポロジーの再構成が行わることを確認した。+そして、切断したノードが再接続を行えることを確認した。+また、再接続の挙動を変更するAPIによりMMORPGにあるような、前回の魚の位置から再開させることに成功した。sortによる実験によって測定を行なう。Segmentが少ないことから、メニコア環境で実験を行った。\hline+\end{tabular}+\end{center}+\end{table}+\subsubsection{実験結果}+100万の要素をもつ配列のSortにかかる時間を計測する。Segmentが物理コア数と同じになるように、分割数は4個で行った。分散環境における改善効果をリングトポロジーによる実験によって測定を行なう。Lindaとの比較も行う。周する時間を計り、1周あたりの平均時間を求める実験である。\label{fig:topologyring}+\end{figure}++実験では、トポロジーの構築時間は実験に含めてはいない。++\subsubsection{実験環境}+学科にある共用のブレードサーバ上の仮想マシンによる仮想クラスタ環境を用いて実験を行った。他の利用者とリソースが競合しないためにTORQUEジョブスケジューラを利用している。\ref{tb:virtual}である。Lindaとの比較}+データのサイズは10Bと100KBで実験を行った。10Bの結果は図\ref{fig:compare_10B}、100KBの結果は図\ref{fig:compare_100KB}である。\label{fig:compare_100KB}+\end{figure}++10Bと100KBの両方の結果でAliceに行った改善の効果を確認することができる。+45台を使用した実験では10Bの小さいパットの場合では17%、100KBの大きいパケットの場合では12%程度高速化することができた。Lindaと改善後の比較では、10Bの場合でAliceのほうが20%程遅い。100KBの場合ほとんど差がないことがわかる。++\subsubsection{TCP\_NODELAY有無の比較}+TCPはデフォルトで、Nagleアルゴリズムを使用している。Nagleアルゴリズムは、小さいパケットを集めてまとめて送信することで、送信するパケット数を減らし効率性をあげるアルゴリズムである。このアルゴリズムの有無により実験結果に影響はないことを確認した。Lindaと同等の性能を持つことが確認できた。+また、並列性能の改善と分散性能の改善の両方に効果があることを確認できた。+両方に共通して行った改善として、複数のSEDAのステージをまとめて1つのステージにしたことがあげられる。+SEDAが実行結果に大きく影響を与えていることが分かる。Lindaに及ばない理由としてもSEDAが原因と考えられる。+リングの実験は並列処理を行なう部分がないシーケンシャルな実験であるため、全ての処理は直列的に実行される。SEDAによるThreadの切り替えが発生する分Aliceの実行速度は遅くなる。Lindaと同じグラフとなる。Lindaに対して優位な点は、マルチコアによる並列実行である。Lindaに勝つことができると予想される。++\section{TreeVNCとのCodeの比較}+ここでは授業向け画面共有システムであるTreeVNCとそれをAlice上で実装したAliceVNCをソースコードの面から比較した。+TreeVNCとAliceVNCのソースコードに対してwcを行い、TightVNCからどの程度コードが増加しているかを調べた。\hline+\end{tabular}+\end{center}+\caption{コードの増加量}+\label{tb:diffwordCount}+\end{table}++AliceVNCはTreeVNCの20\%の行数で記述できることがわかる。コード量が少なければ管理する手間が少ないためプログラマー負担を減らすことができる。Aliceを使うことでプログラマーの負担を80\%減らすことができる。\label{chapter:conclusion}++\section{まとめ}+本研究では、まずはじめにAliceの計算モデルと実装について説明を行い、Aliceにおけるプログラミング手法を述べた。Computationについて説明を行った。+そして、追加した機能を用いて実際に例題を記述することで、その有効性を示した。+改善点では例題を記述する際に発見された問題点について並列と分散両方の観点から説明し、その改善を示した。++最後に、今回行った改善点の効果を測るためリングトポロジー上での実験を行った。Lindaとの性能比較を行い、同程度の性能を持つことを確認した。TreeVNCとAliceVNCをコードの量という観点から評価を行った。Segmentは全て失われてしまう。Store等のシステムに保存し、永続性を確保する昼用がある。JungleのようにLogファイルとして出力することでも解決ができる。Queueで管理されている。Segmentを変更することができてしまう。SegmentにAliceの状態を表すものがあるため、ユーザーによる変更は望ましくない。Keyに対して、putすることも考えられる。Segmentがactiveになりエラーを起こす。Segmentでエラーが起こった場合、ソースコードを見ることができないため解決しづらい。Segmentの領域を分ける必要がある。Segmentを分けることによりKeyの重複によるエラーをアプリケーションレベルにすることができる。領域を分けるだけでは足りない。領域をわけることで解決することができるのはputまたはupdateの場合だけである。SegmentがQueueから取り除かれてしまう。Segmentに対して設定する必要がある。その権限により、takeと記述しても実際にはpeekを行うようにすることができる。シンタックス問題}+setKeyメソッドをコンストラクタで呼ぶ際、setKeyメソッドを必ず最後に呼ばなければならない。Segmentを数えている。Segmentが全て揃ったことと判断される。poolへと送られNullPointerExceptionを引き起こす。Segmentの取得数を決めようとしている。Segmentの取得に成功すると実行可能と判断されてしまう。runの中でinfoの配列の要素だけ中身を表示させようとしてるが、2回目のasClassでNullPointExceptionを引き起こす。今回の場合、コンストラクタ内をソースコード\ref{src:success}のように記述する必要がある。Segmentのインスタンスを扱うことができないことを意味する。SegmentはClassで指定しなければならない。setKeyをどのタイミングで呼ぶべきか考えなおす必要がある。Segment}+Javaには、クラスのインスタンスを1つに限定するSingletonパターンがある。SegmentにSingletonパターンを使用したい場合があり得る。ids.init()}を行なう必要がある。Segmentを示す値がある。Segmentが実行されない。ids.init()}を呼び内部の値を初期化する必要がある。(ソースコード\ref{src:Singleton})+++\begin{table}[html]+\lstinputlisting[label=src:Singleton,caption=setKeyを呼ぶ前にinitを呼ぶ必要がある。コンピューティング向けの総合開発環境でコンパイラ、ライブラリ、デバッガなどから構成される。言語ベースに拡張を加えたものである。比べてプログラマが管理すべきリソースが多い。柔軟な処理を行うことができる。