comparison Paper/anatofuz.tex @ 68:96d62f0292d3

update
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 19 Nov 2018 17:08:39 +0900
parents 60a15dd5023c
children 5aa4743552b7
comparison
equal deleted inserted replaced
67:60a15dd5023c 68:96d62f0292d3
215 215
216 216
217 Stage0にあるファイルをMoarVMに与えることで, NQPのインタプリタが実行される様になっている. 217 Stage0にあるファイルをMoarVMに与えることで, NQPのインタプリタが実行される様になっている.
218 これはStage0の一連のファイルは, MoarVMのバイトコードなどで記述されたNQPコンパイラのモジュールである為である. 218 これはStage0の一連のファイルは, MoarVMのバイトコードなどで記述されたNQPコンパイラのモジュールである為である.
219 NQPのインタプリタはセルフビルドが完了すると, nqpというシェルスクリプトとして提供される. 219 NQPのインタプリタはセルフビルドが完了すると, nqpというシェルスクリプトとして提供される.
220 このシェルスクリプトは, ライブラリパスなどを設定してのバイナリであるmoarを起動するものである. 220 このシェルスクリプトは, ライブラリパスなどを設定してMoarVMの実行バイナリであるmoarを起動するものである.
221 %NQPは6modelと呼ばれるオブジェクトモデルを採用としている.%が, これを構築する為に必要なNQPCORE,正規表現系のQRegex,MoarVMのModuleLoaderなどがMoarVMBytecodeで記述されている.これらMoarVMBytecodeの拡張子は.MoarVMである. 221 %NQPは6modelと呼ばれるオブジェクトモデルを採用としている.%が, これを構築する為に必要なNQPCORE,正規表現系のQRegex,MoarVMのModuleLoaderなどがMoarVMBytecodeで記述されている.これらMoarVMBytecodeの拡張子は.MoarVMである.
222 %MoarVMに対してStage0のディレクトリにライブラリパスを設定し, nqp.MoarVMを実行させることでnqpの対話型環境が起動する. 222 %MoarVMに対してStage0のディレクトリにライブラリパスを設定し, nqp.MoarVMを実行させることでnqpの対話型環境が起動する.
223 223
224 \begin{figure}[ht] 224 \begin{figure}[ht]
225 \begin{center} 225 \begin{center}
247 247
248 248
249 \subsection{現在のPerl6} 249 \subsection{現在のPerl6}
250 Perl6の言語仕様\cite{perl6design}とその時点での実装状況をまとめた公式ドキュメント\cite{perl6doc}は分離している. 250 Perl6の言語仕様\cite{perl6design}とその時点での実装状況をまとめた公式ドキュメント\cite{perl6doc}は分離している.
251 従来は言語仕様は自然言語の仕様書であったが, 現在はテストスイートであるRoast\cite{roast}そのものと定義されている. 251 従来は言語仕様は自然言語の仕様書であったが, 現在はテストスイートであるRoast\cite{roast}そのものと定義されている.
252 現在のPerl6の仕様を読む場合Roastを確認し, 現在rakudo上に実装されている機能を見る場合は公式ドキュメントを確認する必要がある. 252 現在のPerl6の仕様を読む場合Roastを確認し, 現在Rakudo上に実装されている機能を見る場合は公式ドキュメントを確認する必要がある.
253 253
254 \subsection{処理速度} 254 \subsection{処理速度}
255 現在のPerl6が他のプログラミング言語と比較した場合どのような違いがでるのか計測した. 255 現在のPerl6が他のプログラミング言語と比較した場合どのような違いがでるのか計測した.
256 macOSの/var/log/system.logファイルから正規表現でログ中のプログラムが書き込んだ回数を個別に数え上げるというものである. 256 macOSの/var/log/system.logファイルから正規表現でログ中のプログラムが書き込んだ回数を個別に数え上げるというものである.
257 今回はファイルを231Kと3GBの二種類用意し, どの様な違いが出るのか測定した. 257 今回はファイルを231Kと3GBの二種類用意し, どの様な違いが出るのか測定した.
309 % * 21.48s 309 % * 21.48s
310 310
311 311
312 \section{CbCによるMoarVM} 312 \section{CbCによるMoarVM}
313 この章では改良を行ったPerl6処理系であるMoarVMについて述べる. 313 この章では改良を行ったPerl6処理系であるMoarVMについて述べる.
314 今回改良を行ったMoarVMは2018.04.01であり, 利用したnqpは2018.04-3-g45ab6e3バージョンである. 314 今回改良を行ったMoarVMは2018.04.01であり, 利用したNQPは2018.04-3-g45ab6e3バージョンである.
315 \subsection{方針} 315 \subsection{方針}
316 MoarVMそのものをCbCで書き換えることも考えられるがMoarVM自体既に巨大なプロジェクトである為すべてを書き換える事は困難である. 316 MoarVMそのものをCbCで書き換えることも考えられるがMoarVM自体既に巨大なプロジェクトである為すべてを書き換える事は困難である.
317 その為まず比較的CbCで書き換えることが容易な箇所を修正する. 317 その為まず比較的CbCで書き換えることが容易な箇所を修正する.
318 前章までに述べた通りCbCのCodeGearはコンパイラの基本ブロックに該当する. 318 前章までに述べた通りCbCのCodeGearはコンパイラの基本ブロックに該当する.
319 従ってMoarVMにおける基本ブロックの箇所をCodeGearに書き換える事が可能である. 319 従ってMoarVMにおける基本ブロックの箇所をCodeGearに書き換える事が可能である.
325 関数内では命令列が保存されているcur\_op, 現在と次の命令を指し示すop, Threadの環境が保存されているThreadcontextなどの変数を利用する. 325 関数内では命令列が保存されているcur\_op, 現在と次の命令を指し示すop, Threadの環境が保存されているThreadcontextなどの変数を利用する.
326 命令実行は大きく二種類の動作があり, Cのgotoが利用できる場合はCode\ref{orig_macro}に示すMVM\_CGOTOフラグが立ちラベル遷移を利用する. 326 命令実行は大きく二種類の動作があり, Cのgotoが利用できる場合はCode\ref{orig_macro}に示すMVM\_CGOTOフラグが立ちラベル遷移を利用する.
327 それ以外の場合は巨大なcase文として命令を実行する. 327 それ以外の場合は巨大なcase文として命令を実行する.
328 328
329 ラベル遷移を利用する場合はCode\ref{oplabelsh}に示すラベルテーブルLABELSにアクセスし, テーブルに登録されているアドレスを取得し, マクロNEXTで遷移する. 329 ラベル遷移を利用する場合はCode\ref{oplabelsh}に示すラベルテーブルLABELSにアクセスし, テーブルに登録されているアドレスを取得し, マクロNEXTで遷移する.
330 Code\ref{cbc_dispatch_c}に示すno\_opは何もせず次の命令に移動する為, goto NEXT;のみ記述されている. 330 Code\ref{dispatch_c}に示すno\_opは何もせず次の命令に移動する為, goto NEXT;のみ記述されている.
331 331
332 このラベルテーブルの中身はラベルが変換されたアドレスであるため, 実際に呼ばれている命令コードの名前はデバッガレベルでは確認できない. 332 このラベルテーブルの中身はラベルが変換されたアドレスであるため, 実際に呼ばれている命令コードの名前はデバッガレベルでは確認できない.
333 Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる. 333 Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる.
334 巨大なcase文として実行された場合, 実行時間が遅いだけでなく, ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する. 334 巨大なcase文として実行された場合, 実行時間が遅いだけでなく, ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する.
335 335
370 その為INTERPのメンバであるMoarVMのレジスタそのものをアーキテクチャのレジスタ上に乗せる事が可能である. 370 その為INTERPのメンバであるMoarVMのレジスタそのものをアーキテクチャのレジスタ上に乗せる事が可能である.
371 371
372 命令実行中のCodeGearの遷移を図\ref{fig:perl6cbcinter}に示す. 372 命令実行中のCodeGearの遷移を図\ref{fig:perl6cbcinter}に示す.
373 この中で実線で書かれている部分はCbCのgoto文で遷移し, 波線の箇所は通常のCの関数呼び出しとなっている. 373 この中で実線で書かれている部分はCbCのgoto文で遷移し, 波線の箇所は通常のCの関数呼び出しとなっている.
374 374
375 現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextが行っていた. 375 現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextが行っている.
376 その為cbc\_nextから命令コードに対応するCodeGearに継続し, CodeGearからcbc\_nextに継続するサイクルが基本の流れである. 376 その為cbc\_nextから命令コードに対応するCodeGearに継続し, CodeGearからcbc\_nextに継続するサイクルが基本の流れである.
377 CodeGear内からCの関数は問題なく呼ぶ事が可能であるため, Cの関数を利用する処理は変更せず記述する事ができる. 377 CodeGear内からCの関数は問題なく呼ぶ事が可能であるため, Cの関数を利用する処理は変更せず記述する事ができる.
378 また変換対象はswitch文であるため, breakせず次のcaseに移行した場合に対応するように別のCodeGearに継続し,その後cbc\_nextに継続するパターンも存在する. 378 また変換対象はswitch文であるため, breakせず次のcaseに移行した場合に対応するように別のCodeGearに継続し,その後cbc\_nextに継続するパターンも存在する.
379 379
380 \lstinputlisting[label=cbc_codesegs_c, caption=CbCMoarVMのバイトコードに対応するCodeGear]{./src/cbc_codesegs.cbc} 380 \lstinputlisting[label=cbc_codesegs_c, caption=CbCMoarVMのバイトコードに対応するCodeGear]{./src/cbc_codesegs.cbc}
413 また, CbCを用いて言語処理系の改良時を行った際に言語処理系のデバッグを行う場合は, CbCを用いないオリジナルの処理系との並列デバッグが必要となる. 413 また, CbCを用いて言語処理系の改良時を行った際に言語処理系のデバッグを行う場合は, CbCを用いないオリジナルの処理系との並列デバッグが必要となる.
414 MoarVM自体にはデバッグを支援するツールが存在しない為, MoarVM自体のデバッグ方法や, CbCを用いた処理系との並列デバッグについて独自の手法を利用する必要がある. 414 MoarVM自体にはデバッグを支援するツールが存在しない為, MoarVM自体のデバッグ方法や, CbCを用いた処理系との並列デバッグについて独自の手法を利用する必要がある.
415 本研究ではMoarVMのデバッグにおけるCデバッガの使用方法とMoarVMのテスト方法についても示す. 415 本研究ではMoarVMのデバッグにおけるCデバッガの使用方法とMoarVMのテスト方法についても示す.
416 416
417 \subsection{MoarVMのバイトコードのデバッグ} 417 \subsection{MoarVMのバイトコードのデバッグ}
418 MoarVMの実行バイナリであるコマンドmoarに対して, MoarVMのバイトコードをdumpオプションを付けて読み込ませると, バイトコードがMoarVMによるアセンブリコードとして出力される. 418 MoarVMの実行バイナリであるmoarに対して, MoarVMのバイトコードをdumpオプションを付けて読み込ませると, バイトコードがMoarVMによるアセンブリコードとして出力される.
419 しかしこれはMoarVMが実行したバイトコードのトレースではなく, MoarVMのバイトコードを変換したものに過ぎない. 419 しかしこれはMoarVMが実行したバイトコードのトレースではなく, MoarVMのバイトコードを変換したものに過ぎない.
420 また, 明らかに異なる挙動を示すオリジナルのMoarVMと, CbCで書き換えたCbCMoarVM両者のmoarを利用しても同じ結果が返ってきてしまう. 420 また, 明らかに異なる挙動を示すオリジナルのMoarVMと, CbCで書き換えたCbCMoarVM両者のmoarを利用しても同じ結果が返ってきてしまう.
421 そのため今回のMoarVMのバイトコードインタプリタの実装のデバッグにはこの方法は適さない. 421 そのため今回のMoarVMのバイトコードインタプリタの実装のデバッグにはこの方法は適さない.
422 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある. 422 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある.
423 423
431 \lstinputlisting[label=orig_b, caption=オリジナル版MoarVMに対してのbreak point設定]{./src/origin_b_set.txt} 431 \lstinputlisting[label=orig_b, caption=オリジナル版MoarVMに対してのbreak point設定]{./src/origin_b_set.txt}
432 432
433 433
434 \subsection{MoarVMの並列デバッグ手法} 434 \subsection{MoarVMの並列デバッグ手法}
435 しかしMoarVMが実行する命令は膨大な数がある. 435 しかしMoarVMが実行する命令は膨大な数がある.
436 その為gdbでMoarVMをCbCとオリジナル版での並列デバッグを人間が同時に行うことは困難である. 436 その為gdbなどのCデバッガで, オリジナルのMoarVMと, 一部をCbCで記述したCbCMoarVMの並列デバッグを手動で全て行うことは困難である.
437 Perlなどのスクリプトを用いて自動的に解析したいため, ログを残す為にscriptコマンドを実行した状態でgdbを起動する. 437 Perlなどのスクリプトを用いて自動的に解析したいため, ログを残す為にscriptコマンドを実行した状態でgdbを起動する.
438 トレースでは実行した命令名のみ取得できれば良い為, Code\ref{cbc_b}, \ref{orig_b}でbreak pointにcommandとして設定している様に,設定されたcur\_opの値を出力し続けるのみの動きを導入する. 438 トレースでは実行した命令名のみ取得できれば良い為, Code\ref{cbc_b}, \ref{orig_b}でbreak pointにcommandとして設定している様に,設定されたcur\_opの値を出力し続けるのみの動きを導入する.
439 439
440 実際に実行したログ・ファイルの一部をそれぞれCode\ref{debug_origmoar}, \ref{debug_cbcmoar}に示す. 440 実際に実行したログ・ファイルの一部をそれぞれCode\ref{debug_origmoar}, \ref{debug_cbcmoar}に示す.
441 \lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt} 441 \lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt}
451 また主に次のCodeGearに遷移する際にCbCコンパイラのバグが生じている可能性もある為, アセンブラレベルの命令を確認しながらデバッグを進めることとなる. 451 また主に次のCodeGearに遷移する際にCbCコンパイラのバグが生じている可能性もある為, アセンブラレベルの命令を確認しながらデバッグを進めることとなる.
452 452
453 \subsection{MoarVMのテスト方法} 453 \subsection{MoarVMのテスト方法}
454 454
455 MoarVMは単体で実行する事が不可能である. 455 MoarVMは単体で実行する事が不可能である.
456 またNQPのリポジトリに付随するテストはnqpで書かれている為, NQPをビルド出来ない場合MoarVMのテストを行う事が出来ない. 456 またNQPのリポジトリに付随するテストはNQPで書かれている為, NQPをビルド出来ない場合MoarVMのテストを行う事が出来ない.
457 その為, 正常に動作しているMoarVMとNQPを用意し, このNQP側からMoarVMのバイトコードにNQPのテストを変換する. 457 その為, 正常に動作しているMoarVMとNQPを用意し, このNQP側からMoarVMのバイトコードにNQPのテストを変換する.
458 変換されたMoarVMのバイトコードはMoarバイナリに渡す事で実行可能であり, テストを行う事が出来る. 458 変換されたMoarVMのバイトコードはMoarバイナリに渡す事で実行可能であり, テストを行う事が出来る.
459 459
460 \subsection{CbCコンパイラによるバグ} 460 \subsection{CbCコンパイラによるバグ}
461 これまでのCbCに関する研究においては, 複数個の入出力をCodeGearに与えるユースケースで利用していた. 461 これまでのCbCに関する研究においては, 複数個の入出力をCodeGearに与えるユースケースで利用していた.
576 これを繰り返す事でperlccなどと比較してより高速化したThrededCodeが実現できる. 576 これを繰り返す事でperlccなどと比較してより高速化したThrededCodeが実現できる.
577 577
578 578
579 \section{まとめ} 579 \section{まとめ}
580 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した. 580 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した.
581 CbCMoarVMではオリジナルのMoarVMと比較して以下の様な利点が見られた. 581 CbCMoarVMではオリジナルのMoarVMと比較して以下の様な利点が見られた.
582 582
583 \begin{itemize} 583 \begin{itemize}
584 \item CodeGear単位で命令処理を記述する事が可能となり, モジュール化が可能となった. 584 \item CodeGear単位で命令処理を記述する事が可能となり, モジュール化が可能となった.
585 \item ThreadedCodeを実装する際に効率的に実装ができる見込みが立った. 585 \item ThreadedCodeを実装する際に効率的に実装ができる見込みが立った.
586 \item CodeGearを導入した命令単位での最適化が可能となった. 586 \item CodeGearを導入した命令単位での最適化が可能となった.
587 \item break pointを命令の処理単位でかける事が可能となった. 587 \item break pointを命令の処理単位でかける事が可能となった.
588 \end{itemize} 588 \end{itemize}
589 589
590 今後CbCでの開発をより深く行っていくにあたり, CbCコンパイラそのものの信頼性を向上させる必要がある. 590 今後CbCでの開発をより深く行っていくにあたり, CbCコンパイラそのものの信頼性を向上させる必要がある.
591 MoarVMの開発を行うにあたり新たに発見された複数のバグを修正し, より安定するコンパイラにする為に改良を行う. 591 MoarVMの開発を行うにあたり新たに発見された複数のバグを修正し, より安定するコンパイラにする為に改良を行う.
592 592
593 現在CbCMoarVMで直接バイトコードを入力した場合のnqpのテストはJVM, JavaScriptのテストを除く中で80\%パスする. 593 現在CbCMoarVMで直接バイトコードを入力した場合のNQPのテストはJVM, JavaScriptのテストを除く中で80\%パスする.
594 また数値の計算と出力などの簡単なNQPの例題を作成し, オリジナルのNQP,MoarVMでバイトコード化したものを入力した際も正常に動作している. 594 また数値の計算と出力などの簡単なNQPの例題を作成し, オリジナルのNQP,MoarVMでバイトコード化したものを入力した際も正常に動作している.
595 しかしNQPのセルフビルドは現在オブジェクトの生成に一部失敗している為成功していない. 595 しかしNQPのセルフビルドは現在オブジェクトの生成に一部失敗している為成功していない.
596 今後はさらに複雑な例題やNQPのセルフビルド, Perl6の動作を行っていく. 596 今後はさらに複雑な例題やNQPのセルフビルド, Perl6の動作を行っていく.
597 597
598 MoarVMではGCからオブジェクトを守る為にMVMROOTというマクロを利用し, 局所変数のポインタをスタックに登録する処理を行っている. 598 MoarVMではGCからオブジェクトを守る為にMVMROOTというマクロを利用し, 局所変数のポインタをスタックに登録する処理を行っている.