Mercurial > hg > Papers > 2019 > anatofuz-prosym
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 |