view paper/sigos.tex @ 10:7fdd8fe79a65

add sourse
author Nozomi Teruya <e125769@ie.u-ryukyu.ac.jp>
date Wed, 06 May 2015 23:03:46 +0900
parents a5958e372cee
children 7a517d4b20f3
line wrap: on
line source

\documentclass[techrep, ,dvipdfmx]{ipsjpapers}
\usepackage[dvipdfmx]{graphicx}
\usepackage[dvipdfmx]{color}
\usepackage{url}
\usepackage{listings}
\lstset{%
  language={C++},%使用言語
  basicstyle={\small},%書体
  commentstyle={\small\itshape},%コメントの書体
  keywordstyle={\small\bfseries},%キーワードの書体
  %identifierstyle={\small},%
  %ndkeywordstyle={\small},%
  stringstyle={\small},%文字列の書体
  frame={trlb},%外枠
  breaklines=true,%改行
  columns=[l]{fullflexible},%
  xrightmargin=0zw,%
  xleftmargin=3zw,%
  %numbers=none,%行番号の表示
  %numberstyle={\scriptsize},%行番号の書体
  %numbersep=1zw,%
  %stepnumber=1,
  lineskip=-0.5ex,%
  captionpos=b,%キャプションの位置
}
\renewcommand{\lstlistingname}{Code}
\input{dummy.tex} %% Font 

% ユーザが定義したマクロなど.
\makeatletter

\begin{document}

% 和文表題
\title{分散フレームワークAliceの圧縮機能}
% 英文表題
\etitle{}

% 所属ラベルの定義
\affilabel{1}{琉球大学工学部情報工学科\\Information Engineering, University of the Ryukyus.}
\affilabel{2}{琉球大学大学院理工学研究科情報工学専攻 \\Interdisciplinary Information Engineering, Graduate School of Engineering and Science, University of the Ryukyus.}
\affilabel{3}{琉球大学工学部情報工学科\\Information Engineering, University of the Ryukyus.}

% 和文著者名
\author{
  照屋 のぞみ\affiref{1}\and
  杉本 優\affiref{2}\and
  河野 真治\affiref{3}
}

% 英文著者名
\eauthor{
  Nozomi TERUYA\affiref{1}\and
  Yu SUGIMOTO\affiref{2}\and
  Shinji KONO\affiref{3}
}

% 連絡先(投稿時に必要.製版用では無視される.)
\contact{照屋 のぞみ\\
        〒903-0213 沖縄県西原町千原1番地\\
	琉球大学工学部情報工学科\\
        TEL: (098)895-2221\qquad FAX: (098)895-8727\\
        email: kokubo@cr.ie.u-ryukyu.ac.jp}

% 和文概要
\begin{abstract}
  当研究室ではデータをData Segment、タスクをCode Segmentという単位で分割して記述する手法を提唱しており、それに基づく並列分散フレームワークAliceを開発している。Aliceが分散プログラムを記述する能力を有することは、Aliceを用いた水族館の例題、分散データベースJungle、木構造画面共有システムAliceVNCによって確認された。しかし、AliceVNCを作成するには、通信時にData Segmentを圧縮形式で扱える機能が必要である。本研究では、Data SegmentにObject型、MessagePackを使ったByteArray型、圧縮されたByteArray型の3つの表現を同時に持つメタ計算の設計と実装を行うことで、Data Segmentの多態性を用いた圧縮機能を実現した。


\end{abstract}

% 英文概要 仮
\begin{eabstract}
  Alice is a framework for distributed programming, which uses Data Segment and Code Segment as programming units. We checked Alice has an ability to write distributed program using aquarium example, distributed database Jungle and screen sharing system AliceVNC.

In this paper, we add Data Segment computation of compress for achieving Data Segment polymerism. Data Segment has 3 type representation(Object type, ByteArray type using MessagePack, and compressed ByteArray type).
\end{eabstract}

% 表題などの出力
\maketitle

% 本文はここから始まる

\section{研究背景と目的}
並列指向プログラミング言語Erlangでは、プロセスと呼ばれる独立性を備えたスレッドにPidという識別子
が対応しており、Pidを指定してメッセージを送受信する手法を用いて並列分散環境を実現している。
また、当研究室の先行研究であるFederated Lindaは、タプルというIDで番号付けられたデータの集合を相互接続された複数のタプルスペース(LindaServer)に出し入れするプログラミングモデルである。
一方、AliceではString型のkeyに対応するQueueにデータが入っており、タスクはkeyを指定して必要なデータのみを出し入れするモデルを採用している。そのためタスクとデータの依存関係を分かりやすく記述でき、依存しない部分の並列実行が行える。また、Aliceでは分散環境の構築に必要な処理をMeta Computationとして提供することで、スケーラブルな分散プログラムを信頼性高く記述できる環境を実現している。

先行研究の水族館の例題等において、Alice が分散プログラムを記述する能力を有することは確認された。
だが、実用的な分散プログラムを作成するためには、受け取ったデータをそのまま転送したい場合や圧縮されたデータ形式で通信を行いたい場合がある。

本研究では、 実用的なアプリケーションである画面共有システムTreeVNCをAliceで実装するにあたり必要となった圧縮機能を Meta Computation として実装した。
プログラムに Alice の制御を行うメタプログラムを記述することにより、
扱うデータの形式を元のコードを大きく変更することなく指定することができる。
そして、データの多態性を実現し、扱いたいデータの状態に合わせてDataSegmentManagerを切り替えることで、ノード間通信における自由度の向上を図った。   


\section{分散フレームワーク Alice の概要}
\subsection*{[Data SegmentとCode Segment]}
AliceはデータをData Segment、(以下DS)タスクをとCode Segment(以下CS)という単位に分割してプログラミングを行う。
DSはAliceが内部にもつデータベースによって管理されている。DSに対応する一意のkeyが設定されており、そのkeyを用いてデータベースを操作する。

CSは実行に必要なDSが揃うと実行されるという性質を持ち、入力されたDSに応じた結果が出力される。
CSを実行するために必要な入力DSはInputDS、CSが計算を行った後に出力されるDSはOutput DSと呼ばれる。データの依存関係にないCSは並列実行が可能であるため、並列度を上げるためにはCSの処理内容を細かく分割して依存するデータを少なくするのが望ましい。

\subsection*{[Data Segment]}
Aliceはデータを分割して記述する。その分割されたデータをDSと呼ぶ。
Javaの実装ではMessagePackで特定のオブジェクトにマッピングされ、マッピングされたクラスを通してアクセスされる。

CSの実行においてDSは占有されるため、Aliceではデータが他から変更され整合性がとれなくなることはない。


\subsection*{[Data Segment Manager]}
DSは実際にはqueueに保存される。queueには対になるkeyが存在し、keyの数だけqueueが存在する。
このkeyを指定してDSの保存、取得を行う。queueの集合体はデータベースとして捉えられる。このデータベースをAliceではDS Manager(以下DSM)と呼ぶ。DSMにはLocal DSMとRemote DSMが存在する。Local DSMは各ノード固有のデータベースである。Remote DSMは他のノードのLocal DSMのproxyであり、接続しているノードの数だけ存在する。(図\ref{fig:RemoteDSM})Remote DSMに対して書き込むと対応するノードのLocal DSMに書き込まれる。

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=70mm]{images/remote_datasegment.pdf}
\end{center}
\caption{Remote DSMは他のノードのLocal DSMのproxy }
\label{fig:RemoteDSM}
\end{figure}

\subsection*{[Data Segment API]}
以下のData Segment APIを用いてデータベースにアクセスする。
putとupdateはDSを追加する際に、peekとtakeはDSを取得する際に使用する。

\begin{itemize}
\item {\ttfamily void put(String managerKey, String key, \\ Object val)}
\end{itemize}
DSをqueueに追加するためのAPIである。第一引数で指定したDSMの中の、第二引数に対応するqueueに対してDSを追加している。
\begin{itemize}
\item {\ttfamily void update(String managerKey, String key, \\ Object val)}
\end{itemize}
updateもqueueに追加するためのAPIである。putとの違いは、先頭のDSを削除してからDSを追加することである。そのためAPI実行前後でqueueの中にあるDSの個数は変わらない。

\begin{itemize}
\item {\ttfamily void take(String managerKey, String key)}
\end{itemize}
takeはDSを読み込むためのAPIである。読み込まれたDSは削除される。要求したDSが存在しなければ、CSの待ち合わせ (Blocking)が起こる。putやupdateによりDSに更新があった場合、takeが直ちに実行される。

\begin{itemize}
\item {\ttfamily void peek(String managerKey, String key)}
\end{itemize}
peekもDSを読み込むAPIである。takeとの違いは読み込まれたDSが削除されないことである。


\subsection*{[Data Segmentの表現]}
DSの表現にはMessagePack for Javaを利用している。
\begin{itemize}
\item {\ttfamily DSは一般的なJavaのクラスオブジェクト}
\item {\ttfamily MessagePackを用いて変換したbyte[]で表現されたバイナリオブジェクト}
\end{itemize}
の2種類があり、LocalDSMにputされた場合は一般的なJavaのクラスオブジェクトとしてenQueueされる。
RemoteDSMにputされた場合は通信時にbyteArrayに変換されたバイナリオブジェクトがenQueueされる。

\subsection*{[Code Segment]}
Alice上で実行されるタスクの単位がCSである。ユーザーはCSを組み合わせることでプログラミングを行う。CSをユーザーが記述する際に、内部で使用するDSの作成を記述する。

Input DS と Output DSはCSに用意されているAPIを用いて作成する。
Input DSは、LocalかRemoteか、またkeyを指定する必要がある。CSは、記述したInput DSが全て揃うとThread poolに送られ、実行される。

Output DSもLocalかRemoteか、またkeyを指定する必要がある。
Inputの場合はsetKeyを呼ぶ際、Outputの場合はput(またはupdate)の際にノードとkeyの指定を行っている。
しかし、どの時点でノードとkeyの指定を行えばよいか、どのようなAPIを用意するべきかは、議論の余地がある。

\subsection*{[Code Segmentの記述方法]}
CSをユーザーが記述する際にはCSを継承して記述する(ソースコード \ref{src:StartCodeSegment} ,\ref{src:CodeSegment})。
継承することによりCode Segmentで使用するAPIを利用する事ができる。

\begin{table}[html]
\lstinputlisting[label=src:StartCodeSegment, caption=StartCodeSegmentの例]{source/StartCodeSegment.java}
\lstinputlisting[label=src:CodeSegment, caption=CodeSegmentの例]{source/TestCodeSegment.java}
\end{table}

Alice には、Start CS (ソースコード \ref{src:StartCodeSegment})というC の main に相当するような最初に実行される CS がある。
Start CSはどのDSにも依存しない。つまりInput DSを持たない。
このCSをmainメソッド内でnewし、executeメソッドを呼ぶことで実行を開始させることができる。

ソースコード \ref{src:StartCodeSegment}は、5行目で次に実行させたいCS(ソースコード \ref{src:CodeSegment})を作成している。8行目でOutput DSMを通してLocal DSMに対してDSをputしている。
Output DSMはCSの{\tt ods}というフィールドを用いてアクセスする。
Output DSMは{\tt put}と{\tt update}を実行することができる。
TestCodeSegmentはこの"cnt"というkeyに対して依存関係があり、8行目でupdateが行われるとTestCodeSegmentは実行される。

ソースコード\ref{src:CodeSegment}は、0から10までインクリメントする例題である。
2行目で取得されたDSが格納される受け皿を作る。Input DSMがもつcreateメソッド使うことで作成できる。
\begin{itemize}
\item {\ttfamily Receiver create(CommandType type)}
\end{itemize}

引数にはCommandTypeが取られ、指定できるCommandTypeは{\tt PEEK}または{\tt TAKE}である。
Input DSM はCSの{\tt ids}というフィールドを用いてアクセスする。

4行目から6行目はコンストラクタである。コンストラクタはオブジェクト指向のプログラミング言語で新たなオブジェクトを生成する際に呼び出されて内容の初期化を行う関数である。

TestCodeSegmentのコンストラクタが呼ばれた際には、
\begin{enumerate}
\item TestCodeSegmentが持つフィールド変数Receiver input1の定義が行われる。
\item 次にCSのコンストラクタが呼ばれ、CSが持つフィールド変数の定義と初期化が行われる。
\item {\tt ids.create(CommandType.TAKE)}が行われ、input1の初期化が行われる。
\item 最後にTestCodeSegmentのコンストラクタの5行目が実行される。
\end{enumerate}

5行目はInput DSMがもつsetKeyメソッドによりLocal DSMからDSを取得している。
\begin{itemize}
\item \verb+void setKey(String managerKey, String key)+
\end{itemize}
setKeyメソッドにより、どのDSMのあるkeyに対してpeekまたはtakeコマンドを実行させるかを指定できる。コマンドの結果がレスポンスとして届き次第CSは実行される。

runメソッドの内容としては10行目で取得されたDSをInteger型に変換してcountに代入している。
16行目で もう一度TestCodeSegmentのCSが作られる。
17行目でcountの値をインクリメントしてLocal DSMに値を追加する。
13行目が終了条件であり、countの値が10になれば終了する。

\subsection*{[ComputationとMeta Computation]}
AliceのComputationは、keyで指し示されるDSを待ち合わせてCSを実行させると定義できる。
それに対して、AliceのMeta Computationは、AliceのComputationを支えているComputationのプログラミングと定義できる。

例えば、トポロジーを指定するAPIはMeta Computationである。Aliceが動作するためにはトポロジーを決める必要がある。つまりトポロジーの構成はAliceのComputationを支えているComputationとみなすことができる。トポロジーが決定するとそのトポロジーを構成する計算が行われる。トポロジーを指定するAPIはその構成の計算をプログラミングして変更するものである。
他にも再接続の動作を決めるAPIや切断時の動作を決めるAPIはMeta Computationである。

プログラマーはCSを記述する際にトポロジーや切断、再接続という状況を予め想定した処理にする必要はない。プログラマーは目的の処理だけ記述する。そして、切断や再接続が起こった場合の処理を記述しMeta Computationで指定する。
このようにプログラムすることで、通常処理と例外処理を分離することができるため、シンプルなプログラムを記述できる。


\subsection*{[Meta Data Segment]}
DSは、アプリケーションに管理されているデータのことである。アプリケーションを構成するCSによってその値は変更される。
それに対してMeta DSは、分散フレームワークAliceが管理しているデータである。Aliceを構成するCSによってのみ、その値は変更される。一部のMeta DSはアプリケーションに利用することができる。

例えば、"start"というkeyをもつMeta DSは、ノードがStart CSを実行可能かどうかの状態を表す。他にも"\_CLIST"というkeyでは、利用可能なRemote DSの一覧が管理されている。ユーザーはこの一覧にある名前を指定することで、動的にDSの伝搬などを行うことができる。

また、Input DSに付随しているものもある。Input DSはCS内部でReceiverという入れ物に格納される。ユーザーは、Receiverに対して操作することでDSを入手できる。
このReceiverには、fromというフィールドがあり、このDSを誰がputしたという情報が入っている。この情報をデータの伝搬する際に利用することで、DSをputしたノードに送り返すことを防ぐことができる。

Meta DSはDS同様にDS APIを用いて取得できる。

\subsection*{[Meta Code Segment]}
CSはアプリケーションを動作させるために必要なタスクであり、ユーザーによって定義される。
それに対してMeta CSはAliceを構成するタスクである。つまりMeta CSの群はAliceのComputationと言い換えることができる。一部のみユーザーが定義をすることができ、Aliceの挙動を変更することができる。




\section{AliceVNC}
当研究室では授業向け画面共有システムTreeVNCの開発を行っている。
授業でVNCを使う場合、1つのコンピュータに多人数が同時につながるため、性能が大幅に落ちてしまう(図\ref{fig:vnc})。
この問題をノード同士を接続させ、木構造を構成することで負荷分散を行い解決したものがTreeVNCである(図\ref{fig:treestructure})。

 Aliceが実用的なアプリケーションを記述する能力をもつことを確認するために、TreeVNCをAliceを用いて実装したAliceVNCの作成を行った。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[width=60mm]{images/vnc.pdf}
    \end{center}
    \caption{VNCの構造 }
    \label{fig:vnc}
\end{figure}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[height=50mm]{images/treestructure.pdf}
    \end{center}
    \caption{TreeVNC, AliceVNCの構造 }
    \label{fig:treestructure}
\end{figure}




\section{Aliceの新機能}
実用的なアプリケーションであるTreeVNCをAlice上で実装することで、Aliceに必要な機能を洗い出した。
\subsection*{[flip機能]}
Data Segment APIのput、updateを呼ぶとOutput Data Segmentが毎回新しく作成され、出力するデータのコピーが行われる。しかし、Input Data Segmentとして取得したデータをそのまま子ノードにOutput Data Segmentとして出力する場合、コピーを行なうのは無駄である。

そこで、Input Data SegmentとOutput Data Segmentを交換する機能をflip機能として実装した。
ソースコード\ref{src:exampleFlip}のようにInput Data SegmentであるReceiverをコピーせずにflipメソッドに引数として渡すことで、コピーのオーバーヘッドをなくしている。
TreeVNCでは親ノードから受け取った画面データをそのまま子ノードに配信するため、Meta Computationとしてflip機能が有用である。
\begin{table}[html]
\lstinputlisting[label=src:flipAlice, caption=Aliceにおけるflip]{source/flip.java}
\end{table}

\begin{table}[html]
\lstinputlisting[label=src:exampleFlip,caption=flipの使用例]{source/Sort.java}
\end{table}

\subsection*{[Data Segmentの表現の追加(圧縮機能)]}
TreeVNCでは画面配信の際、データを圧縮してノード間通信を行っている。
そのため、AliceVNCにも圧縮されたデータ形式を扱える機能が必要だと考えた。
しかし、ただデータを圧縮する機構を追加すればいいわけではない。

AliceVNCでは、ノードは受け取った画面データを描画すると同時に、子ノードのRemote DS Managerに送信する。
ノードはDSを受信するとそれを一度解凍して画面を表示し、再圧縮して子ノードに送信する。
しかし、受け取ったデータを自分の子ノードに対して送信する際には、解凍する必要はない。
圧縮状態のまま子ノードに送信ができれば、解凍・再圧縮するオーバーヘッドを無くすことができる。

そこで、1つのData Segmentに対し複数の表現を持たせることで、必要に応じた形式でDSを扱うことを可能にした。
DSを扱うReceiveData.classに、次の3種類の表現を同時に持つことができる。

\begin{enumerate}
  \item 一般的なJavaのクラスオブジェクト
  \item MessagePack for Javaでシリアライズ化されたバイナリオブジェクト
  \item 2を圧縮したバイナリオブジェクト
\end{enumerate}

ソースコード\ref {src:ReceiveData}はReceiveData.classが持つ表現であり、{\tt val}に(1) 一般的なJavaのクラスオブジェクト の表現でデータ本体が保存される。{\tt messagePack}には(2) シリアライズ化されたバイナリオブジェクトが保存され、通常のRemoteDSMへの通信にこの表現が扱われる。そして、{\tt zMessagePack}には(3) 圧縮されたバイナリオブジェクトが保存される。
\begin{table}[html]
\lstinputlisting[label=src:ReceiveData, caption=データを表現するクラス]{source/ReceiveData.java}
\end{table}

また、圧縮状態を持つDSを扱うDSMとしてLocalとRemoteそれぞれにCompressed Data Segment Managerの追加した。Compressed DSMの内部では、put/updateが呼ばれた際にReceiveData.classが圧縮表現を持っていればそれを使用し、持っていなければその時点で圧縮表現を作ってput/updateを行う。
ソースコード\ref{src:before}はRemoteからDSをtakeしインクリメントしてLocalにputすることを10回繰り返す例題である。これをDSを圧縮形式で行いたい場合、ソースコード\ref{src:after}のように指定するDSM名の先頭に"compressed"をつければCompressed DSM内部の圧縮Meta Computationが走りDSを圧縮状態で扱うようになる。


\begin{table}[html]
\lstinputlisting[label=src:before, caption=通常のDSを扱うCSの例]{source/beforeCompress.java}
\end{table}

\begin{table}[html]
\lstinputlisting[label=src:after,caption=圧縮したDSを扱うCSの例]{source/afterCompress.java}
\end{table}

これによりユーザは指定するDSMを変えるだけで、他の計算部分を変えずに圧縮表現を持つDSを扱うことができる。ノードは圧縮されたDSを受け取った後、そのまま子ノードにflipすれば圧縮状態のまま送信されるので、送信の際の再圧縮がなくなる。
画面表示の際はReceiveData.class内の{\tt asClass()}(ソースコード\ref {src:asClass} )を使うことで適切な形式でデータを取得できる。
{\tt asClass()}はDSを目的の型にcastするメソッドであり、ReceiveData.classが圧縮表現だけを持っている場合はこのメソッド内で解凍してcastを行っている。
これによりDSの表現を必要になったときに作成できる。

\begin{table}[html]
\lstinputlisting[label=src:asClass, caption=asClassの処理]{source/asClass.java}
\end{table}

\subsection*{[Aliceの通信プロトコルの変更]}
2章 [Data Segmentの表現]で述べたように、Remoteからputされたデータは必ずシリアライズ化されておりbyteArrayで表現される。
しかし、データの表現に圧縮したbyteArrayを追加したため、RemoteからputされたbyteArrayが圧縮されているのかそうでないのかを判断する必要がある。

そこで、Aliceの通信におけるヘッダにあたるCommandMessage.class(ソースコード\ref {src:CommandMessage})にシリアライズ状態表すフラグと、圧縮状態を表すフラグを追加した。
これによってputされたDSMはフラグに応じた適切な形式でReceiveData.class内にDSを格納できる。
また、CommandMessage.classに圧縮前のデータサイズも追加したことで、適切な解凍が可能になった。

\begin{table}[html]
\lstinputlisting[label=src:CommandMessage, caption=CommandMessage]{source/CommandMessage.java}
\end{table}

\begin{table}[htbp]
\caption{CommandMessageの変数名の説明}
\label{tb:variable}
\begin{center}
\begin{tabular} {|l|l|}
  \hline
  変数名&説明\\
  \hline
  type&CommandType {\tt PEEK, PUT}などを表す\\
  \hline
  seq&\shortstack{Data Segmentの待ち合わせを行っている\\Code Segmentを表すunique number }\\
  \hline
  key&どのKeyに対して操作を行うか指定する\\
  \hline

  quickFlag&SEDAを挟まずCommandを処理を行うかを示す\\
  \hline
  serialized&データ本体のシリアライズ状態を示す\\
  \hline

  compressed&データ本体の圧縮状態を示す\\
  \hline

  dataSize&圧縮前のデータサイズを表す\\
  \hline

\end{tabular}
\end{center}
\end{table}


 \section{まとめ}
並列分散フレームワークAliceの計算モデルと実装について説明を行い、Aliceにおけるプログラミング手法を述べた。

Aliceが実用的なアプリケーションを記述するために必要なMeta Computationとして、データの多態性を実現し、指定するDSMの切り替えで扱うデータ表現を変えるようにした。
これにより、必要に応じた形式を扱うことができ、ユーザが記述するComputation部分を大きく変えずに自由度の高い通信を行うことが可能になった。
同様の手法を用いれば、圧縮形式以外にも暗号形式・JSON形式などの複数のデータ表現をユーザに扱いやすい形で拡張することができる。

今後の課題としては、圧縮機能をAliceVNCで用いることで有効性を測る必要がある。また、AliceのMeta ComputationにProxy機能を実装することで、TreeVNCでは実装が困難であったNAT越えの機能を提供できると期待される。

\nocite{*}
%\nocite{opencl}
%\nocite{opencl:ref}
%\nocite{opencl:applied}
%\nocite{yutaka:os}
\bibliographystyle{ipsjunsrt}
\bibliography{sigos}
%\bibliography{cerium,book}


\end{document}