Mercurial > hg > Papers > 2022 > riono-master
changeset 20:d550ccb7f803
update chapter 2
author | riono <e165729@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 29 Jan 2022 19:39:47 +0900 |
parents | 88508b9cb03f |
children | 866f4329e430 |
files | Paper/chapter/1-Christie.tex Paper/chapter/2-RewriteCS.tex Paper/chapter/2-Unity.tex Paper/master_paper.pdf Paper/src/cs/TakeExample.cs Paper/src/cs/ThreadPoolExecutor.cs Paper/src/java/ThreadPoolExecutor.java |
diffstat | 7 files changed, 150 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/Paper/chapter/1-Christie.tex Sat Jan 29 15:18:09 2022 +0900 +++ b/Paper/chapter/1-Christie.tex Sat Jan 29 19:39:47 2022 +0900 @@ -87,7 +87,7 @@ DGの宣言には型と変数を直接宣言し、変数名としてkeyを記述する。 そして、その宣言の上にannotationでTakeまたはPeekを指定する(ソースコード\ref{src:TakeExample})。 -\lstinputlisting[label=src:TakeExample, caption=Takeの例]{src/TakeExample.java} +\lstinputlisting[label=src:TakeExample, caption=Takeの例]{src/java/TakeExample.java} annotationで指定したDGはCGを生成した際にCodeGear.class内で待ち合わせの処理が行われる。 これにはJavaのreflectionAPIを利用しており、annotationと同時に変数名も取得できるため、面数名によるkeyの指定が可能になっている。 @@ -98,7 +98,7 @@ リモートノードに対してTake/Peekをする際には、TakeFrom/PeekFrom annotationを用いる(ソースコード\ref{src:TakeFromExample})。 -\lstinputlisting[label=src:TakeFromExample, caption=TakeFromの例]{src/TakeFromExample.java} +\lstinputlisting[label=src:TakeFromExample, caption=TakeFromの例]{src/java/TakeFromExample.java} \section{データの型整合性} @@ -107,7 +107,7 @@ ChristieではannotationでDGの宣言を行っているため、直接変数の型を宣言することが可能となっている。 ソースコード\ref{src:InputDGExample}はDGのデータを扱う例である。 -\lstinputlisting[label=src:InputDGExample, caption=DGのデータを扱う例]{src/InputDG.java} +\lstinputlisting[label=src:InputDGExample, caption=DGのデータを扱う例]{src/java/InputDG.java} DGとして宣言した変数の型は、JavaのreflectionAPIを用いてCGMで保存され、LocalやRemoteノードと通信する際に適切な変換が行われれる。 この様にプログラマが指定せずとも正しい型でデータを取得できるため、プログラマの負担を減らし信頼性を保証することができる。 @@ -117,9 +117,9 @@ 以下のソースコード\ref{src:StartCGExample}、\ref{src:CGExample}、\ref{src:CounteObj}はLocalDGMにputしたDGを取り出して表示し、 インクリメントして10回繰り返す例題である。 -\lstinputlisting[label=src:StartCGExample, caption=StartCodeGearの記述例]{src/StartCGExample.java} -\lstinputlisting[label=src:CGExample, caption=CodeGearの記述例]{src/CodeGearExample.java} -\lstinputlisting[label=src:CounteObj, caption=DGとして送信されるオブジェクトのクラス]{src/CountObject.java} +\lstinputlisting[label=src:StartCGExample, caption=StartCodeGearの記述例]{src/java/StartCGExample.java} +\lstinputlisting[label=src:CGExample, caption=CodeGearの記述例]{src/java/CodeGearExample.java} +\lstinputlisting[label=src:CounteObj, caption=DGとして送信されるオブジェクトのクラス]{src/java/CountObject.java} Chrisiteでは、StartCodeGear(以下StartCG)から処理を開始する。 StartCGはStartCodeGear.javaを継承することで記述可能である。 @@ -155,7 +155,7 @@ 6行目にあるように、RemoteDGMを立ち上げるにはCGMが持つcreateRemoteDGMメソッドを用いる。 引数にはRemoteDGM名と接続するremoteノードhost名、ポート番号を指定している。 -\lstinputlisting[label=src:2LocalDGM, caption=LocalDGMを2つ作る例]{src/RemoteDGMCommunication.java} +\lstinputlisting[label=src:2LocalDGM, caption=LocalDGMを2つ作る例]{src/java/RemoteDGMCommunication.java} remoteへの接続と同じ様にアクセスが可能になっており、コードを変更せずに同一マシン上の1つのアプリケーション内で分散アプリケーションのテストが可能となっている。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/chapter/2-RewriteCS.tex Sat Jan 29 19:39:47 2022 +0900 @@ -0,0 +1,90 @@ +\chapter{ChristieのC\#への書き換え} + +\section{Unity} +UnityはUnity Technologiesが開発、公開しているゲームエンジンである。 +画像や3Dモデルの表示、物理演算、UIのイベント機能などゲーム制作に必要な機能が標準で備わっており、 +個人でもゲーム開発が可能となっている。 +さまざまなプラットフォームに対応可能であり、PC、iOS、Androidやその他コンシューマ機器も開発可能である。 +また、非常に動作が軽いことも特徴であり、スペックが低いノートPCでも十分ゲーム開発が可能である。 + +プログラミング言語としてはC\#がサポートされている。 +最新バージョンである2021.2.8ではC\# 9がサポートされており、 +.NET Frameworkはバージョン4.6に対応している。 +C\#向けの既存のAPIや外部ライブラリ、Unity用に開発されたAPIなども使用可能である。 +拡張性が高く、開発に必要な機能を作成しUnityのメニューから実行することも可能である。 + + +本研究では、開発環境を整えるためのハードルの低さ、公開されている通信ライブラリの豊富さなどを考慮しUnityを採用した。 +Unity上でChristieを動作させるために、Javaで記述されているChristieをC\#に書き換えを行う。 + +\section{Christie Sharpの書き換えの基本方針} +Javaで記述されたChristieと区別するため、C\#で記述するChristieをChrisite Sharpとする。 +Chrisite Sharpではコードの保守性や、Christie設計時の意図などを守るため、Chrisiteと同じ挙動、同じ動作をする必要がある。 +初めにC\#単体で動作するように、Christieの核となる部分の書き換えを行った。 + + +ChristieはJava 9から開発されていたため、現在では非推奨なコードやバージョンアップが必要な箇所が存在する。 +そこで書き換えを行う際に、C\#に対応しつつ処理動作の向上や最適化を行うために以下の改良を行った。 + +\begin{itemize} + \item MessagePackの変更及びバージョンアップ + \item ThreadPoolからTaskへの変更 +\end{itemize} + + +\section{attributeの実装} +ChristieではDGを取得する際に、annotationを用いてTakeやPeekなどのコマンドを処理していた。 +Christie Sharpはannotationではなく、代わりにattributeを利用してコマンドの処理を行っている。 + +\lstinputlisting[label=src:JavaTakeImple, caption=JavaにおけるTake annotationの実装]{src/java/Take.java} +\lstinputlisting[label=src:CSTakeImple, caption=C\#におけるTake attributeの実装]{src/cs/Take.cs} + +ソースコード\ref{src:JavaTakeImple}はJavaにおけるTake annotationの実装である。 +Javaでannotationを自作する際には、\@interfaceで宣言を行う。 +1行目ではannotationの適用可能箇所を指定しておりフィールド変数に対して付与可能としている。 +また、2行目はannotationの情報をどの段階まで保持するかを指定しており、Takeの場合JVMによって保存され、ランタイム環境で使用可能となっている。 + +ソースコード\ref{src:CSTakeImple}はC\#におけるTake attributeの実装である。 +C\#でattributeを自作する際には、System.Attributeを継承する必要がある。 +attributeの適用可能箇所については、1行目にてフィールド変数を指定している。 + + +attributeの使用方法はannotationと同じく変数の宣言の前に、[ ]内に使用するattributeを宣言する(ソースコード\ref{src:CSTakeExample})。 + +\lstinputlisting[label=src:CSTakeExample, caption=Take attributeの例]{src/cs/TakeExample.cs} + + + +\section{TaskによるCodeGearの処理} +ChrisiteではCGの実行にThreadPoolを利用していた。 +しかしThreadPoolは管理や生成が煩雑であり、コストパフォーマンスの低下につながりやすい。 +C\#にはThreadをより使いやすく高機能にしたTaskという機能がある。 +TaskはC\#のThreadPoolを拡張しており、内部にThreadPoolと実行待ちQueueを持っている。 +Task.RunメソッドやTask.Factory.StartNewメソッドで処理を実行でき、処理が渡されるとThreadPoolで処理されるため、Christieと同じ動作をすると考え、Christie SharpではTaskで書き換えを行った。 + +\lstinputlisting[label=src:JavaThreadPoolExecutor, caption=ChristieにおけるThreadPoolの実装の一部]{src/java/ThreadPoolExecutor.java} + +ソースコード\ref{src:JavaThreadPoolExecutor}はChristieにおけるCodeGearを処理するThreadPoolの実装の一部である。 +Javaでは独自にThreadPoolを実装する際にはThreadPoolExecutorを継承する。 +またThreadの優先度を変更する機能が実装されており、CodeGear実行時に処理の優先度を設定することが可能となっている。 + +\newpage + +\lstinputlisting[label=src:CSThreadPoolExecutor, caption=Christie SharpにおけるThreadPoolの実装]{src/cs/ThreadPoolExecutor.cs} + +ソースコード\ref{src:CSThreadPoolExecutor}はソースコード\ref{src:JavaThreadPoolExecutor}をC\#に書き換えを行ったものである。 +CGの実行には14行目のExecuteを呼び出し、Taskで実行を行っている。 + + +Threadの優先度による実行順変更については、実装の優先度が低かったため今回は実装を行っていない。 +Taskのスケジューラーは自作可能であり、実行待ちQueueの処理順を変更することができるため実装可能である。 + + +\section{Socket通信用のThreadをTaskに変更} + + +\section{MessagePackの変更} + + +\section{送信データの修正} +
--- a/Paper/chapter/2-Unity.tex Sat Jan 29 15:18:09 2022 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -\chapter{ChristieのUnityへの対応} - -\section{Unity} -UnityはUnity Technologiesが開発、公開しているゲームエンジンである。 -画像や3Dモデルの表示、物理演算、UIのイベント機能などゲーム制作に必要な機能が標準で備わっており、 -個人でもゲーム開発が可能となっている。 -さまざまなプラットフォームに対応可能であり、PC、iOS、Androidやその他コンシューマ機器も開発可能である。 -また、非常に動作が軽いことも特徴であり、スペックが低いノートPCでも十分ゲーム開発が可能である。 - -プログラミング言語としてはC\#がサポートされている。 -最新バージョンである2021.2.8ではC\# 9がサポートされており、 -.NET Frameworkはバージョン4.6に対応している。 -C\#向けの既存のAPIや外部ライブラリ、Unity用に開発されたAPIなども使用可能である。 -拡張性が高く、開発に必要な機能を作成しUnityのメニューから実行することも可能である。 - - -本研究では、開発環境を整えるためのハードルの低さ、公開されている通信ライブラリの豊富さなどを考慮しUnityを採用した。 - - -\section{Christie Sharpの書き換えの基本方針} -Javaで記述されたChristieと区別するため、C\#で記述するChristieをChrisite Sharpとする。 -Chrisite Sharpではコードの保守性や、Christie設計時の意図などを守るため、Chrisiteと同じ挙動、同じ動作をする必要がある。 -初めにC\#単体で動作するように、Christieの核となる部分の書き換えを行った。 - - -ChristieはJava 9から開発されていたため、現在では非推奨なコードやバージョンアップが必要な箇所が存在する。 -そこで書き換えを行う際に、C\#に対応しつつ処理動作の向上や最適化を行うために以下の改良を行った。 - -\begin{itemize} - \item MessagePackの変更及びバージョンアップ - \item ThreadPoolからTaskへの変更 -\end{itemize} - - -\section{attributeの実装} -ChristieではDGを取得する際に、annotationを用いてTakeやPeekなどのコマンドを処理していた。 -Christie Sharpはannotationではなく、代わりにattributeを利用してコマンドの処理を行っている。 - -\lstinputlisting[label=src:JavaTakeImple, caption=JavaにおけるTake annotationの実装]{src/Take.java} -\lstinputlisting[label=src:CSTakeImple, caption=C\#におけるTake attributeの実装]{src/Take.cs} - -ソースコード\ref{src:JavaTakeImple}はJavaにおけるTake annotationの実装である。 -Javaでannotationを自作する際には、\@interfaceで宣言を行う。 -1行目ではannotationの適用可能箇所を指定しておりフィールド変数に対して付与可能としている。 -また、2行目はannotationの情報をどの段階まで保持するかを指定しており、Takeの場合JVMによって保存され、ランタイム環境で使用可能となっている。 - -ソースコード\ref{src:CSTakeImple}はC\#におけるTake attributeの実装である。 -C\#でattributeを自作する際には、System.Attributeを継承する必要がある。 -attributeの適用可能箇所については、1行目にてフィールド変数を指定している。 - -%attributeの使用方法について - - -\section{TaskによるCGの処理} - - - -\section{MessagePackの変更} - - -\section{送信データの修正} -
--- a/Paper/src/cs/TakeExample.cs Sat Jan 29 15:18:09 2022 +0900 +++ b/Paper/src/cs/TakeExample.cs Sat Jan 29 19:39:47 2022 +0900 @@ -0,0 +1,1 @@ +[Take] public string data; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/src/cs/ThreadPoolExecutor.cs Sat Jan 29 19:39:47 2022 +0900 @@ -0,0 +1,17 @@ +public class ThreadPoolExecutors { + + public ThreadPoolExecutors() { + int nWorkerThreads; + int nIOThreads; + ThreadPool.GetMinThreads(out nWorkerThreads, out nIOThreads); + ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads); + } + + public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) { + ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads); + } + + public void Execute(CodeGearExecutor command) { + Task.Factory.StartNew(() => command.Run()); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/src/java/ThreadPoolExecutor.java Sat Jan 29 19:39:47 2022 +0900 @@ -0,0 +1,35 @@ +public class PriorityThreadPoolExecutors { + + public static ThreadPoolExecutor createThreadPool(int nThreads, int keepAliveTime) { + return new PriorityThreadPoolExecutor(nThreads, nThreads, keepAliveTime, TimeUnit.MILLISECONDS); + } + private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor { + private static final int DEFAULT_PRIORITY = 0; + private static AtomicLong instanceCounter = new AtomicLong(); + + public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, + int keepAliveTime, TimeUnit unit) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, + ComparableTask.comparatorByPriorityAndSequentialOrder())); + } + + @Override + public void execute(Runnable command) { + // If this is ugly then delegator pattern needed + if (command instanceof ComparableTask) //Already wrapped + super.execute(command); + else { + super.execute(newComparableRunnableFor(command)); + } + } + + private Runnable newComparableRunnableFor(Runnable runnable) { + return new ComparableRunnable((CodeGearExecutor) runnable); + } + + @Override + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { + return new ComparableFutureTask<>((CodeGearExecutor)runnable, value); + } + } +}