# HG changeset patch # User Takahiro SHIMIZU # Date 1541656679 -32400 # Node ID 2bf64cfb91b10a02e2fb165c04ebb0d3adc2caa5 # Parent 3e4ffa621ae980068cf030ab6f923fbcf2ba103c add CbC evaluation and CbCinterp fig diff -r 3e4ffa621ae9 -r 2bf64cfb91b1 Paper/anatofuz.pdf Binary file Paper/anatofuz.pdf has changed diff -r 3e4ffa621ae9 -r 2bf64cfb91b1 Paper/anatofuz.tex --- a/Paper/anatofuz.tex Wed Nov 07 22:35:07 2018 +0900 +++ b/Paper/anatofuz.tex Thu Nov 08 14:57:59 2018 +0900 @@ -93,7 +93,7 @@ \_\_codeはCbCコンパイラの扱いはvoidと同じ型であるが,CbCプログラミングではCodeSegmentである事を示す識別子としての意味で利用する. \subsection{軽量継続} -TBD +CbCでは次のCodeSegmentに移行する際,Cの \subsection{現在の実装} CbCは現在主要なCコンパイラであるgcc及びllvmをバックエンドとしたclang上の2種類の実装が存在する. @@ -211,7 +211,7 @@ このラベルテーブルの中身はラベルが変換されたアドレスであるため,Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる. 巨大なcase文として実行された場合,実行時間が遅いだけでなく,ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する. -CbCMoarVMではこの問題を解決するために,それぞれの命令に対応するCodeSegmentを作成し,これらへのポインタを持つCbCのCodeSegmentのテーブルを作成した. +CbCMoarVMではこの問題を解決するために,それぞれの命令に対応するCodeSegmentを作成し,CodeSegment名前を要素として持つCbCのCodeSegmentのテーブルを作成した. \subsection{命令実行箇所のCodeSegmentへの変換} ラベルテーブルやcase文のswitch相当の命令実行箇所をCbCに変換し,CodeSegmentの遷移として利用する. @@ -220,12 +220,23 @@ そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない. 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける. +\begin{figure}[ht] + \begin{center} + \includegraphics[width=70mm]{fig/cbc_next.pdf} + \end{center} + \caption{CbCにおけるインタプリタの関数遷移} + \label{fig:sendTask} +\end{figure} + + \subsection{MoarVMのBytecodeのデバッグ} moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される. しかしこれはmoarvmが実行したbytecodeのトレースではなくmoarvm bytecodeを変換したものに過ぎない. また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう. そのため今回のMoarVMBytecodeインタプリタの実装のデバッグにはこの方法は適さない. 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある. +\lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt} + \subsection{MoarVMの並列デバッグ手法} しかしMoarVMが実行する命令は膨大な数がある. @@ -271,16 +282,38 @@ MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である. この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる. -\section{CbCを用いる事についての評価} -Perl6処理系はまずPerl6の豊富な文法に対応する物を作成せねばならず,類似する他のプログラミング言語処理系と比較してもより複雑となっている. -実際にPerl5を始めとしたスクリプト言語とPerl6がどのような処理時間の違いが見られるかを実測する. +\section{CbCを用いる事についての利点と欠点} +MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された. +本章ではまず利点を述べ,次に現段階でのCbCを適応した場合の欠点について考察する. + +\subsection{利点} +\subsection{コード分割} +オリジナルのMoarVMでは命令コードに対応する箇所はラベルジャンプ,もしくはswitch文で実装されていた. +その為同じCファイルに命令コードの実行の定義が存在しなければならない. +今後MoarVMに新たなバイトコードが導入されていく事を考えるとinterp.cが巨大になる可能性がある. +関数単位での処理の比重が偏る事に加え, +switch文中に書かれている処理は他の関数から呼ぶ事が出来ないため,余計な手間がかかる箇所が発生すると考えられる. +CbCMoarVMの場合,CodeSegmentとして基本ブロックを記述出来る為オリジナルのMoarVMの様にswtich文のブロック中に書く必要性が無くなる. +その為類似する命令系をコード分割し,モジュール化する事が可能である. +これは通常のインタプリタの実装と比べ可読性と言う意味とモノリシックアーキテクチャをマイクロ化出来るという意味でも利点である. +\subsubsection{MoarVMのデバッグ} +MoarVMのバイトコードインタプリタの箇所はオリジナルの実装ではラベルジャンプを用いて実装されている. +その為,直接ラベルにbreak pointをかける事が出来ない. +作業者がデバッガが読み込んでいるCソースコードの位置を把握し,行番号を指定してdebug pointを設定する必要があった. + +CbCMoarVMの場合,CodeSegment単位でバイトコードの処理単位を記述している為,通常の関数と同じく直接CodeSegmentにデバッグポイントをかける事が可能である. +これはCプログラミングの関数に対してのデバッグで,状態ごとにbreak pointをかける事が出来ることを意味する. +通常のC言語で言語処理系を実装した場合と比較して扱いやすくなっていると言える. +さらにラベルテーブルでの管理場合,次のバイトコード箇所は数値でしか確認できず,実際にどこに飛ぶのかはラベルテーブル内と数値を作業者が手作業で確認する必要があった. +スクリプトなどを組めば効率化は出来るがデバッガ上で完結しない為手間がかかる. +CbC実装ではCODESテーブル内は次のCodeSegmentの名前が入っている為,数値からCodeSegmentの名前をデバッガ上で確認する事が出来る. % \subsection{単純なループ処理の測定} % 簡単な例題としてfor文を用いて100000回ループさせ,ある変数をインクリメントするというプログラムを作成する. % 今回の評価対象としてPerl6は2018年4月にリリースされたMoarVM,NQP,Rakudoの実装を用いる. % Perl5は5.26.2を利用した. -% + % \begin{table}[htb] % \begin{tabular}{|c|c|c|} \hline % ループ回数 & Perl5 (sec) & Perl6(sec) \\ \hline \hline @@ -290,6 +323,16 @@ % \end{tabular} % \end{table} +\subsection{欠点} +\subsubsection{CbCコンパイラ} +前章までに複数述べた通りCbCコンパイラが現在非常にバグを発生させやすい状態になっている. +CbCコンパイラはgccとllvm/clangに実装している為,これらのアップデートに追従する必要がある. +しかしコンパイラのバージョンに応じてCbCで利用するコンパイラ内のAPIが異なる場合が多く,APIの変更に伴う修正作業などを行う必要がある. + +CbCMoarVMではCからCbCへ,CbCからCへの遷移などが複数回繰り返されているが,CodeSegmentでのtail callの強制が非常に難関である. +tail callの強制には関数定義の箇所や引数,スタック領域のサイズ修正などを行う必要がある. +この実装の為にはどのケースで関数が定義されているかをCbCコンパイラで明確に分割する必要がある. + \section{今後の課題} 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した. diff -r 3e4ffa621ae9 -r 2bf64cfb91b1 Paper/fig/cbc_next.pdf Binary file Paper/fig/cbc_next.pdf has changed diff -r 3e4ffa621ae9 -r 2bf64cfb91b1 Paper/src/cbc_next.graffle Binary file Paper/src/cbc_next.graffle has changed diff -r 3e4ffa621ae9 -r 2bf64cfb91b1 Paper/src/origin_breakpoint.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/src/origin_breakpoint.txt Thu Nov 08 14:57:59 2018 +0900 @@ -0,0 +1,35 @@ +dalmore gdb --args ../../MoarVM_Original/MoarVM/moar --libpath=src/vm/moar/stage0 gen/moar/stage1/nqp +(gdb) b dummy +Function "dummy" not defined. +Make breakpoint pending on future shared library load? (y or [n]) y +Breakpoint 1 (dummy) pending. +(gdb) command 1 +Type commands for breakpoint(s) 1, one per line. +End with a line saying just "end". +>up +>p *(MVMuint16 *)(cur_op) +>c +>end +(gdb) c +The program is not being run. +(gdb) run +Starting program: /mnt/dalmore-home/one/src/Perl6/nqp/../../MoarVM_Original/MoarVM/moar --libpath=src/vm/moar/stage0 gen/moar/stage1/nqp.moarvm +[Thread debugging using libthread_db enabled] +Using host libthread_db library "/lib64/libthread_db.so.1". +[New Thread 0x7ffff629a700 (LWP 176412)] + +Breakpoint 1, dummy () at src/core/interp.c:46 +46 } +#1 0x00007ffff75608fe in MVM_interp_run (tc=0x604a20, + initial_invoke=0x7ffff76c7168 , invoke_data=0x67ff10) + at src/core/interp.c:119 +119 goto NEXT; +$1 = 159 + +Breakpoint 1, dummy () at src/core/interp.c:46 +46 } +#1 0x00007ffff75689da in MVM_interp_run (tc=0x604a20, + initial_invoke=0x7ffff76c7168 , invoke_data=0x67ff10) + at src/core/interp.c:1169 +1169 goto NEXT; +$2 = 162