comparison Paper/anatofuz.tex @ 20:2bf64cfb91b1

add CbC evaluation and CbCinterp fig
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Thu, 08 Nov 2018 14:57:59 +0900
parents 3e4ffa621ae9
children 5ba21dfc6e0c
comparison
equal deleted inserted replaced
19:3e4ffa621ae9 20:2bf64cfb91b1
91 CbCではCの関数の代わりにCodeSegmentを導入する. 91 CbCではCの関数の代わりにCodeSegmentを導入する.
92 CodeSegmentはCの関数宣言の型名の代わりに\_\_codeと書くことで 宣言できる. 92 CodeSegmentはCの関数宣言の型名の代わりに\_\_codeと書くことで 宣言できる.
93 \_\_codeはCbCコンパイラの扱いはvoidと同じ型であるが,CbCプログラミングではCodeSegmentである事を示す識別子としての意味で利用する. 93 \_\_codeはCbCコンパイラの扱いはvoidと同じ型であるが,CbCプログラミングではCodeSegmentである事を示す識別子としての意味で利用する.
94 94
95 \subsection{軽量継続} 95 \subsection{軽量継続}
96 TBD 96 CbCでは次のCodeSegmentに移行する際,Cの
97 97
98 \subsection{現在の実装} 98 \subsection{現在の実装}
99 CbCは現在主要なCコンパイラであるgcc及びllvmをバックエンドとしたclang上の2種類の実装が存在する. 99 CbCは現在主要なCコンパイラであるgcc及びllvmをバックエンドとしたclang上の2種類の実装が存在する.
100 gccはバージョン9.0.0に,clangは7.0.0に対応している. 100 gccはバージョン9.0.0に,clangは7.0.0に対応している.
101 101
209 209
210 ラベル遷移を利用する場合はラベルテーブルにアクセスし,テーブルに登録されているアドレスを取得し,NEXTで遷移する. 210 ラベル遷移を利用する場合はラベルテーブルにアクセスし,テーブルに登録されているアドレスを取得し,NEXTで遷移する.
211 このラベルテーブルの中身はラベルが変換されたアドレスであるため,Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる. 211 このラベルテーブルの中身はラベルが変換されたアドレスであるため,Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる.
212 巨大なcase文として実行された場合,実行時間が遅いだけでなく,ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する. 212 巨大なcase文として実行された場合,実行時間が遅いだけでなく,ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する.
213 213
214 CbCMoarVMではこの問題を解決するために,それぞれの命令に対応するCodeSegmentを作成し,これらへのポインタを持つCbCのCodeSegmentのテーブルを作成した. 214 CbCMoarVMではこの問題を解決するために,それぞれの命令に対応するCodeSegmentを作成し,CodeSegment名前を要素として持つCbCのCodeSegmentのテーブルを作成した.
215 215
216 \subsection{命令実行箇所のCodeSegmentへの変換} 216 \subsection{命令実行箇所のCodeSegmentへの変換}
217 ラベルテーブルやcase文のswitch相当の命令実行箇所をCbCに変換し,CodeSegmentの遷移として利用する. 217 ラベルテーブルやcase文のswitch相当の命令実行箇所をCbCに変換し,CodeSegmentの遷移として利用する.
218 interp.cは?に示す様なスタイルで記述されている. 218 interp.cは?に示す様なスタイルで記述されている.
219 OP(.*)の.*に該当する箇所はバイトコードの名前である.通常このブロックにはLABELから遷移する為,バイトコードの名前はLABELSの配列の添字に変換されている. 219 OP(.*)の.*に該当する箇所はバイトコードの名前である.通常このブロックにはLABELから遷移する為,バイトコードの名前はLABELSの配列の添字に変換されている.
220 そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない. 220 そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない.
221 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける. 221 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける.
222 222
223 \begin{figure}[ht]
224 \begin{center}
225 \includegraphics[width=70mm]{fig/cbc_next.pdf}
226 \end{center}
227 \caption{CbCにおけるインタプリタの関数遷移}
228 \label{fig:sendTask}
229 \end{figure}
230
231
223 \subsection{MoarVMのBytecodeのデバッグ} 232 \subsection{MoarVMのBytecodeのデバッグ}
224 moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される. 233 moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される.
225 しかしこれはmoarvmが実行したbytecodeのトレースではなくmoarvm bytecodeを変換したものに過ぎない. 234 しかしこれはmoarvmが実行したbytecodeのトレースではなくmoarvm bytecodeを変換したものに過ぎない.
226 また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう. 235 また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう.
227 そのため今回のMoarVMBytecodeインタプリタの実装のデバッグにはこの方法は適さない. 236 そのため今回のMoarVMBytecodeインタプリタの実装のデバッグにはこの方法は適さない.
228 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある. 237 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある.
238 \lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt}
239
229 240
230 \subsection{MoarVMの並列デバッグ手法} 241 \subsection{MoarVMの並列デバッグ手法}
231 しかしMoarVMが実行する命令は膨大な数がある. 242 しかしMoarVMが実行する命令は膨大な数がある.
232 その為gdbでMoarVMをCbCとオリジナル版での並列デバッグを人間が同時に行うことは困難である. 243 その為gdbでMoarVMをCbCとオリジナル版での並列デバッグを人間が同時に行うことは困難である.
233 Perlなどのスクリプトを用いて自動的に解析したいため,ログを残す為にscriptコマンドを実行した状態でgdbを起動する. 244 Perlなどのスクリプトを用いて自動的に解析したいため,ログを残す為にscriptコマンドを実行した状態でgdbを起動する.
269 PerlccはPerlのバイトコードをCに変換しただけであり,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない. 280 PerlccはPerlのバイトコードをCに変換しただけであり,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない.
270 またPerlccで生成されたCのソースコードは難解であり,これをデバッグするのが困難でもある. 281 またPerlccで生成されたCのソースコードは難解であり,これをデバッグするのが困難でもある.
271 MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である. 282 MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である.
272 この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる. 283 この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる.
273 284
274 \section{CbCを用いる事についての評価} 285 \section{CbCを用いる事についての利点と欠点}
275 Perl6処理系はまずPerl6の豊富な文法に対応する物を作成せねばならず,類似する他のプログラミング言語処理系と比較してもより複雑となっている. 286 MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された.
276 実際にPerl5を始めとしたスクリプト言語とPerl6がどのような処理時間の違いが見られるかを実測する. 287 本章ではまず利点を述べ,次に現段階でのCbCを適応した場合の欠点について考察する.
277 288
278 289 \subsection{利点}
290 \subsection{コード分割}
291 オリジナルのMoarVMでは命令コードに対応する箇所はラベルジャンプ,もしくはswitch文で実装されていた.
292 その為同じCファイルに命令コードの実行の定義が存在しなければならない.
293 今後MoarVMに新たなバイトコードが導入されていく事を考えるとinterp.cが巨大になる可能性がある.
294 関数単位での処理の比重が偏る事に加え,
295 switch文中に書かれている処理は他の関数から呼ぶ事が出来ないため,余計な手間がかかる箇所が発生すると考えられる.
296
297 CbCMoarVMの場合,CodeSegmentとして基本ブロックを記述出来る為オリジナルのMoarVMの様にswtich文のブロック中に書く必要性が無くなる.
298 その為類似する命令系をコード分割し,モジュール化する事が可能である.
299 これは通常のインタプリタの実装と比べ可読性と言う意味とモノリシックアーキテクチャをマイクロ化出来るという意味でも利点である.
300
301 \subsubsection{MoarVMのデバッグ}
302 MoarVMのバイトコードインタプリタの箇所はオリジナルの実装ではラベルジャンプを用いて実装されている.
303 その為,直接ラベルにbreak pointをかける事が出来ない.
304 作業者がデバッガが読み込んでいるCソースコードの位置を把握し,行番号を指定してdebug pointを設定する必要があった.
305
306 CbCMoarVMの場合,CodeSegment単位でバイトコードの処理単位を記述している為,通常の関数と同じく直接CodeSegmentにデバッグポイントをかける事が可能である.
307 これはCプログラミングの関数に対してのデバッグで,状態ごとにbreak pointをかける事が出来ることを意味する.
308 通常のC言語で言語処理系を実装した場合と比較して扱いやすくなっていると言える.
309 さらにラベルテーブルでの管理場合,次のバイトコード箇所は数値でしか確認できず,実際にどこに飛ぶのかはラベルテーブル内と数値を作業者が手作業で確認する必要があった.
310 スクリプトなどを組めば効率化は出来るがデバッガ上で完結しない為手間がかかる.
311 CbC実装ではCODESテーブル内は次のCodeSegmentの名前が入っている為,数値からCodeSegmentの名前をデバッガ上で確認する事が出来る.
279 % \subsection{単純なループ処理の測定} 312 % \subsection{単純なループ処理の測定}
280 % 簡単な例題としてfor文を用いて100000回ループさせ,ある変数をインクリメントするというプログラムを作成する. 313 % 簡単な例題としてfor文を用いて100000回ループさせ,ある変数をインクリメントするというプログラムを作成する.
281 % 今回の評価対象としてPerl6は2018年4月にリリースされたMoarVM,NQP,Rakudoの実装を用いる. 314 % 今回の評価対象としてPerl6は2018年4月にリリースされたMoarVM,NQP,Rakudoの実装を用いる.
282 % Perl5は5.26.2を利用した. 315 % Perl5は5.26.2を利用した.
283 % 316
284 % \begin{table}[htb] 317 % \begin{table}[htb]
285 % \begin{tabular}{|c|c|c|} \hline 318 % \begin{tabular}{|c|c|c|} \hline
286 % ループ回数 & Perl5 (sec) & Perl6(sec) \\ \hline \hline 319 % ループ回数 & Perl5 (sec) & Perl6(sec) \\ \hline \hline
287 % 1000000 & 0.131 & 1.444 \\ \hline 320 % 1000000 & 0.131 & 1.444 \\ \hline
288 % 10000000 & 0.131 & 1.444 \\ \hline 321 % 10000000 & 0.131 & 1.444 \\ \hline
289 % 100000000 & 3.258 & 124.69 \\ \hline 322 % 100000000 & 3.258 & 124.69 \\ \hline
290 % \end{tabular} 323 % \end{tabular}
291 % \end{table} 324 % \end{table}
292 325
326 \subsection{欠点}
327 \subsubsection{CbCコンパイラ}
328 前章までに複数述べた通りCbCコンパイラが現在非常にバグを発生させやすい状態になっている.
329 CbCコンパイラはgccとllvm/clangに実装している為,これらのアップデートに追従する必要がある.
330 しかしコンパイラのバージョンに応じてCbCで利用するコンパイラ内のAPIが異なる場合が多く,APIの変更に伴う修正作業などを行う必要がある.
331
332 CbCMoarVMではCからCbCへ,CbCからCへの遷移などが複数回繰り返されているが,CodeSegmentでのtail callの強制が非常に難関である.
333 tail callの強制には関数定義の箇所や引数,スタック領域のサイズ修正などを行う必要がある.
334 この実装の為にはどのケースで関数が定義されているかをCbCコンパイラで明確に分割する必要がある.
335
293 336
294 \section{今後の課題} 337 \section{今後の課題}
295 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した. 338 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した.
296 CbCのCodeSegment部分を用いることできめ細やかな記述が出来,デバッグし辛い箇所もbreakpointの設定などが容易になった. 339 CbCのCodeSegment部分を用いることできめ細やかな記述が出来,デバッグし辛い箇所もbreakpointの設定などが容易になった.
297 340