# HG changeset patch # User Yu Taninari # Date 1312974981 -32400 # Node ID 6d3160dde83b5f27704da390440812d8e8292081 # Parent 119c91756dfe7fb03bb210dddd4e3f5dd7b5322d# Parent e7275c42c957df71cb0de14fbec9dd1fdbdb3adf merge diff -r 119c91756dfe -r 6d3160dde83b yuu-jssst.pdf Binary file yuu-jssst.pdf has changed diff -r 119c91756dfe -r 6d3160dde83b yuu-jssst.tex --- a/yuu-jssst.tex Wed Aug 10 20:14:59 2011 +0900 +++ b/yuu-jssst.tex Wed Aug 10 20:16:21 2011 +0900 @@ -103,9 +103,9 @@ \section{TreeVNCの方針} まず、多人数が参加している授業でVNCを使う場合に起こる問題は、最初で述べたように、一つのコンピュータに多人数が繋がり、処理性能が大幅に落ちてしまうところが問題である。 %この問題を解決する為に、一つのコンピュータに多人数がつながるのではなく目的のコンピュータに繋がっているコンピュータに繋げれば目的の画面を共有することができる。 -この問題を解決する為に、クライアント同士を接続させ、画面描画のデータを受け取ったクライアントが次のクライアントにデータを流すという方法を思いついた。 +この問題を解決する為に、クライアント同士を接続させ、画面描画のデータを受け取ったクライアントが次のクライアントにデータを流すという方法を行うことにした。 %一つのコンピュータに多人数がつながるのではなく目的のコンピュータに繋がっているコンピュータに繋げれば目的の画面を共有することができる。 -画面共有を行いたいクライアントが一種のVNCサーバ自体にもなるのである。 +画面共有を行いたいクライアントが一種のVNCサーバ自体にもなる。 %誰が誰に繋げばよいかを管理することが出来れば多人数が同時に画面共有をスムーズに行うことが出来ると考えた。 また、クライアント同士の接続はツリー構造で行うことで管理がしやすくなると考えた。 クライアント同士の接続の管理はツリーの一番上にいるPC(Top)で行い、このTopだけがVNCサーバへ接続を行うようにする。 @@ -183,28 +183,16 @@ 次にクライアントへの送信と自身のビューアへの描画を並列に行う。 \subsubsection{FramebufferUpdate} -Rfb プロトコル での画面の描画の更新は、FramebufferUpdate単位で行われる。 -FramebufferUpdateは更新を行う画面の矩形の数がまず送られ、 -次にx座標、y座標、横幅、縦幅、エンコードのタイプ、描画データが1セットとなり矩形の数だけデータが送られてくる。 -描画データはエンコードのタイプにしたがった方法で送られてくる。 - +Rfb プロトコルでの画面の描画の更新は、FramebufferUpdateで行われる。 +FramebufferUpdateを受け取ることで画面の再描画が行われる。 +FrameBufferUpdateでは、メッセージタイプと画面の矩形の数がまず送られ、 +次にx座標、y座標、横幅、縦幅、エンコードのタイプ、描画データが矩形の数だけ送られてくる。 +描画データはエンコードのタイプに従った方法で送られてくる。 \subsubsection{描画データの先読み} -FramebufferUpdateで送られくるデータ量はエンコードタイプまで読みこめば知ることができる。 -例えば、RAWエンコードの場合は width * height * 4 のバイト数が送られてくる。4はピクセルのデータ量である。 -ヘッダーと計算で求めた数の分だけバイトを読み込むことで1つのFramebufferUpdate単位でコピーを行うことができる。 - -\begin{figure}[!htbp] -\begin{center} -\includegraphics[scale = 0.5]{fig/multicastqueue.eps} -\end{center} -\caption{ -Vncサーバ(Parent)から受け取ったデータを自身に繋がっているクライアントへ送信する。クライアントは次のクライアント -へデータを送信する。 -} -\label{figure:splaying} -\end{figure} - +1回のFramebufferUpdateで送られくるデータ量はエンコードタイプまで読みこめば知ることができる。 +例えば、RAWエンコードの場合は width * height * 4 のバイト数が送られてくる(4はピクセルのデータ量である)。 +計算で求めた数の分とヘッダーを合わせた数だけバイトを読み込むことで1回分のFramebufferUpdateのコピーを行うことができる。 \subsubsection{MulticastQueue} @@ -214,29 +202,41 @@ CountDownLatch一回CountDownされたときに待機しているスレッドを解放するように宣言する。更新情報が来るまでawaitを用いてスレッドを待機させる。更新情報が来たときCountDownを行う。すると、スレッドが開放されるので同時に更新情報を参照することができる。 +\begin{figure}[tb] +\begin{center} +\includegraphics[scale = 0.5]{fig/multicastqueue.eps} +\end{center} +\caption{ +クライアントへは並列にデータを送信する。 +} +\label{figure:splaying} +\end{figure} + \subsubsection{timeout} MultiCastQueueを使ってのデータの取得には問題が発生した。 それは、接続してきたクライアントがデータを取得しない状況、例えばサスペンド状態になったときにTopのメモリの中にデータが残り続けるというものである。 -メモリに残り続けたデータはやがてメモリオーバーフローを引き起こしてしまうのである。 - +メモリに残り続けたデータはやがてメモリオーバーフローを引き起こしてしまうのである。その様子を図3に示す。 \begin{figure}[!htbp] \begin{center} \includegraphics[scale = 0.5]{fig/TimeOut2.eps} \end{center} -\caption{クライアントサスペンド時のTopのメモリ} +\caption{ +クライアントサスペンド時のTopのメモリの様子。 +データが残り続けメモリを圧迫してしまう。 +} \label{figure:splaying} \end{figure} -そこで、ある一定の時間がたつと代わりにデータをpollしてくれるTimeOut用のスレッドを作成した。 +そこで、ある一定の時間がたつと代わりにデータを取得してくれるTimeOut用のスレッドを作成した。 TimeOutスレッドはサスペンドしているクライアントの代わりにデータを取得する。 \begin{figure}[!htbp] \begin{center} \includegraphics[scale = 0.5]{fig/TimeOut3.eps} \end{center} -\caption{TimeOutがpollを行う} +\caption{TimeOutが代わりにデータを取得する} \label{figure:splaying} \end{figure} @@ -247,45 +247,48 @@ VNCで扱うRfb プロトコルには、使えるエンコーディングのタイプの1つとしてZRLE(Zlib Run-Length Encoding)がある。 ZRLEはZlibで圧縮されたデータとそのデータのバイト数がヘッダーとして付けられ送られてくる。 Zlibはフリーのデータ圧縮及び解凍を行うライブラリである。 -可逆圧縮アルゴリズムのdeflaterを実装している。deflaterを用いてデータの圧縮が行える。 +可逆圧縮アルゴリズムの圧縮と解凍が行えるjava.util.zip.deflaterとjava.util.zip.inflaterを実装している。 -\subsubsection{java.util.zip.deflaterのバグ} -deflaterはプリセット辞書をもち、Zlib圧縮されたデータはその辞書を用いて解凍が行われる。 -辞書は更新されることもあるのでZlib圧縮されたデータを解凍する為には辞書のデータも受け取る必要がある。 -しかし、JavaにはこのZlibの辞書を相手へ書きだす(flush)する機能が無い。 -元々のZlibの規約にはこの辞書をflushする機能があったがJavaには実装されていなかった。 - +\subsubsection{java.util.zip.deflaterの実装の問題} +Zlib圧縮は辞書を持っていて、その辞書に登録されているデータを元に解凍が行われる。 +しかし、java.util.zip.deflaterは現在持っている辞書を書き出すこと(flush)ができないことが分かった。 +辞書を書きだすことができない為、Zlib圧縮されたデータを途中から受け取ってもデータが正しく解凍を行うことができない。 +%元々のZlibの規約にはこの辞書をflushする機能があったがJavaには実装されていなかった。 \subsubsection{ZRLEE(ZRLE Economy)} そこで、TopがZRLEで受け取ったデータをunzipし、データをzipし直して最後にfinish() -をいれることで初めからデータを読んでいなくても解凍を行えるようにした。 +をいれることで初めからデータを読んでいなくても解凍を行えるようにした(毎回新しい辞書を使うようにした)。 このエンコードはZRLEEエンコードと定義した。 一度ZRLEEエンコードに変換してしまえば、そのデータをそのまま流すだけで良い。 よって変換はTopが行う一回だけですむ。 -ただし、deflaterでは前回までの通信で得た辞書をクリアしないといけないため、クライアント側では毎回 -deflaterは新しいものを使うことになる。 +ただし、deflater,inflaterでは前回までの通信で得た辞書をクリアしないといけないため、 +Topとクライアント側では毎回新しく作る必要がある(クライアント側はinflaterだけ)。 また、ZRLEEはクライアント側が対応していなければならないという問題がある。 \subsubsection{ZRLEとZRLEEのデータ圧縮率の比較} RAW,ZRLE,ZRLEEのデータ量の比較を行った。 図6は1920 * 1080の画面の全描画にかかるデータ量を測った結果を示した図である。ZRLEEの方がデータ量が少なくですんでいる。 これは、ZRLE(Zlib)が初めに送られた辞書を用いての解凍が余り有効的に働いていない場合があるからだと思われる。 -つまりVNCの場合はZRLEEの様に毎回辞書のデータを付加させて送ってもデータ量に差がでないのである。 +つまりVNCの場合はZRLEEの様に毎回辞書のデータを付加させて送ってもデータ量に差がでない可能性があることが分かった。 + \begin{figure}[!htbp] \begin{center} \includegraphics[scale = 0.5]{fig/compare_encoding.eps} \end{center} -\caption{RAW,ZRLE,ZRLEEによる1画面(1920*1080)描画にかかるデータ量} +\caption{ +RAW,ZRLE,ZRLEEによる1画面(1920*1080)描画にかかるデータ量。 +x軸はピクセル数、y軸はバイト数を表している。 +} \label{figure:splaying} \end{figure} \section{評価} TreeVNCの実装を行い、Vnc Reflectorとの比較を行った。 -テスト環境はBlade サーバ上にVMを48台用意して行った。 -Blade サーバの外にTreeVNCとVnc Reflectorを起動させたPCを置き、VM48台にアクセスさせた。 +テスト環境はBlade サーバ上にVMを48台用意し、Blade サーバの外にTreeVNCとVnc Reflectorを +起動させたPCを置き、VM48台にアクセスさせて実験を行った。 %Blade サーバ上のVMとVnc Reflectorを起動するPCはGbitEthernetとスイッチで繋げられている。 \subsection{Vnc Reflectorとの比較結果} @@ -309,24 +312,12 @@ \section{まとめ} 本研究では、VNCとツリー構造を用いて画面共有システムを開発した。結果スループットを落とすことなく48台で接続を行うことがきた。 -Zlib圧縮に使用されるjava.util.zip.deflaterのバグも発見したので、代わりとなるエンコードZRLEEの実装を行った。 +Zlib圧縮に使用されるjava.util.zip.deflaterの問題も発見したので、 +ZRLEの代わりとなるZRLEEを用意した。 クライアントへのデータ転送をマルチキャストで行う等、実装には改良の余地がある。 \section{参考サイト} -RFB Prococol 3.8 - -http://srgia.com/docs/rfbprotocol3.8.html - -2011:08:08 - -RFC 1950 ZLIB Compressed Data Format Specification version 3.3 日本語訳 - futomi's CGI Cafe - -http://www.futomi.com/lecture/japanese/rfc1950.html - -2011:08:08 - - \end{document}