Mercurial > hg > Papers > 2019 > anatofuz-midterm
changeset 5:97ca0612ce5b
update mid_thesis
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 09 Nov 2018 22:14:45 +0900 |
parents | 0cfdbf1cec79 |
children | 2964605b812f |
files | Makefile cbc_codesegs.cbc cbc_example.cbc cbc_next.pdf mid_thesis.pdf mid_thesis.tex |
diffstat | 6 files changed, 84 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Nov 09 17:18:25 2018 +0900 +++ b/Makefile Fri Nov 09 22:14:45 2018 +0900 @@ -32,5 +32,5 @@ clean: - rm -f *.dvi *.aux *.log *.pdf *.ps *.gz *.bbl *.blg *.toc *~ *.core + rm -f *.dvi *.aux *.log *.ps *.gz *.bbl *.blg *.toc *~ *.core
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbc_codesegs.cbc Fri Nov 09 22:14:45 2018 +0900 @@ -0,0 +1,12 @@ +__code cbc_no_op(INTERP i){ + goto cbc_next(i); +} +__code cbc_const_i32(INTERP i){ + MVM_exception_throw_adhoc(i->tc, "const_iX NYI"); + goto cbc_const_i64(i); +} +__code cbc_const_i64(INTERP i){ + GET_REG(i->cur_op, 0,i).i64 = MVM_BC_get_I64(i->cur_op, 2); + i->cur_op += 10; + goto cbc_next(i); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbc_example.cbc Fri Nov 09 22:14:45 2018 +0900 @@ -0,0 +1,14 @@ +int main (){ + int data = 0; + goto cg1(&data); +} + +__code cg1(int *datap){ + (*datap)++; + goto cg2(datap); +} + +__code cg2(int *datap){ + (*datap)++; + printf("%d\n",*datap); +}
--- a/mid_thesis.tex Fri Nov 09 17:18:25 2018 +0900 +++ b/mid_thesis.tex Fri Nov 09 22:14:45 2018 +0900 @@ -20,7 +20,33 @@ \setlength{\footskip}{0mm} \pagestyle{empty} -\input{dummy.tex} +\usepackage{comment} +\usepackage{listings} +\lstset{ + language=C, + tabsize=2, + frame=single, + basicstyle={\ttfamily\footnotesize}, % + identifierstyle={\footnotesize}, % + commentstyle={\footnotesize\itshape}, % + keywordstyle={\footnotesize\bfseries}, % + ndkeywordstyle={\footnotesize}, % + stringstyle={\footnotesize\ttfamily}, + breaklines=true, + captionpos=b, + columns=[l]{fullflexible}, % + xrightmargin=0zw, % + xleftmargin=1zw, % + aboveskip=1zw, + numberstyle={\scriptsize}, % + stepnumber=1, + numbersep=0.5zw, % + lineskip=-0.5ex, +} +\renewcommand{\lstlistingname}{Code} +\usepackage{caption} +\captionsetup[lstlisting]{font={small, tt}} + \renewcommand{\abstractname}{概要} \begin{document} \title{CbCを用いたPerl6処理系} @@ -31,45 +57,32 @@ \section{研究目的} スクリプト言語Perl(Perl5)の後継言語としてPerl6が開発されている. -Perl6は設計と実装が分離しており,現在はRakudoと呼ばれる実装が主流となっている. -RakudoではPerl6をコンパイラ開発者用のサブセットであるNQPで実装し,NQPをVMで動作させる. -現在はNQPを解釈できるVMとしてMoarVM,JVM,Javascriptが存在する. -主に利用されているのはMoarVMであるが処理時間がPerlを始めとした現在広く使われているスクリプト言語と比較すると非常に低速であり +Perl6はMoarVMと言うVMで動作するが,処理時間がPerlを始めとした現在広く使われているスクリプト言語と比較すると非常に低速であり 実務として利用できるレベルに達していない. またMoarVMの実装も巨大なswitch-case文が使用されており開発の難易度も高い. -その為CbCを用いてMoarVMの一部を書き直し高速化かつわかりやすい処理系を実装を検討する. +この問題を解決するために,CbCを用いてMoarVMの一部を書き直し高速化かつわかりやすい処理系を実装する. +CbCはCよりきめ細やかな実装が出来るため,言語処理系の実装に適していると推測できる. +その為本研究ではCbCを言語処理系の実装に用いた場合の利点と難点についても考察する. \section{CbC} -Perl6処理系の改良にはLLVM/Clang上に実装したContinuation based C(CbC)を用いる. -CbCはCからコンパイルする事が可能である為Cのリソースを利用したCとは異なる言語である. -CbCはCodeGearを基本的な処理単位とし,CodeGearの遷移でプログラムを記述する. +Perl6処理系の改良にはgccとLLVM/Clang上に実装したContinuation based C(CbC)を用いる. +CbCはCodeGearを基本的な処理単位とし,CodeGearの遷移でプログラムを記述するCの下位言語である. CodeSegmentの宣言は\_\_codeという型を持つ関数として宣言する. ただしこの関数は\_\_codeという型を返すわけではなく,CodeGearである事を示す指示子のような役割である. CodeGearはCの関数とは異なり返り値を持たず,呼び差し元の関数に戻る代わりに別のCodeGearへ遷移する. -返り値を使わず,別の関数呼び出しを実行するプログラミングスタイルを継続と呼ぶが,C言語における継続とは異なり -CbCにおけるCodeGear間の継続はスタックに値を積まず,スタックの変更を行わない. -また自分自身がどの行にいるかという情報を環境と言うが,CbCはこの環境を持たず継続する. -これを通常の継続と区別して軽量継続と呼ぶ. +CbCにおけるCodeGear間の継続はスタックに値を積まず,環境も遷移時に持たない為軽量継続と呼ぶ. CbCは軽量継続を中心にプログラミングする事が可能であるため,レジスタの移動などが行われない. その為並列化やループ制御,関数呼び出しにおけるスタック制御などを意識したプログラミングスタイルでプログラミングする事が可能である. +\lstinputlisting[label=cbcexample, caption=cbc\_example.cbc]{cbc_example.cbc} + \section{Perl6} -スクリプト言語Perl6はスクリプト言語であるPerlの後継言語として開発が初められたプログラミング言語である. -Perlは現在5が接頭辞につくバージョンとなっており,その次期バージョンとして当初は開発された為Perl6と名付けられている. -現在はPerl5との非互換な文法や独自の機能の追加などによりPerlとは別言語として開発が進められている. -Perl6はPerlとは異なりプログラミング言語の設計と実装が分離しており,様々な実装が開発された. -Haskellによって実装されたPugs,PythonとPerl6の共通基盤として言語処理系のVMであるParrotが実装された. -Parrot自身はNQP(NotQuitPerl)と呼ばれるサブセットを解釈し,Perl6はNQPを用いて実装されている. -現在はParrotの開発が終了し,Rakudoと呼ばれる実装が主流となっている. -RakudoではMoarVMと言われるVMがNQPを解釈し,Parrotと同様にPerl6はNQPで実装されている. -Parrotとは異なりMoarVMはPerl6プロジェクトに特化した仮想環境である. +Perlの現在の主流な実装はRakudoである.RakudoはMoarVM,とNQPと呼ばれるPerl6のサブセット,NQPで記述されたPerl6という構成である. +MoarVMはNQPを解釈する. このNQPで記述されたPerl6の事をRakudoと呼ぶ. RakudoはMoarVMの他にJVM,Javascriptを動作環境として選択可能である. - -言語的な特徴ではPerl5とは違いオブジェクト指向のサポートが強力になっている. -またPerl6は漸進的型付け言語である. -従来のPerlの様に変数に代入する対象の型や文脈に応じて型を変更する動的型言語としての側面を持ちつつ独自に定義した型を始めとする様々な型に静的に変数の型を設定する事が可能である. +言語的な特徴ではPerl5とは違いオブジェクト指向のサポートが強力になり,漸進的型付け言語としての特徴を持つ. %処理時間は状況にもよるが231Kbのファイルを正規表現で検索する例題を実行した場合 処理時間は状況によるが,231KBのファイルを正規表現で検索する例題の場合Perl5が0.04sに対しMoarVMに乗せたPerl6は0.86sとおよそ20倍の速度差がある. @@ -99,14 +112,13 @@ このVMはOSレベルの仮想化を行うVMではなく,擬似的なアセンブラを解釈するソフトウェアとしての擬似機械のことである. MoarVMはC言語で実装されておりPerl6に特化した仮想機械となっている. MoarVMは個別で起動することが出来ず,NQPもしくはPerl6をMoarVMに入力として与え実行する. -またMoarVMはレジスタマシンである為,仮想的なレジスタを持っている. +またMoarVMはレジスタマシンであり仮想的なレジスタ利用し計算を行う. -\section{MoarVMにおける命令コードのディスパッチ} +\section{MoarVMのディスパッチ} MoarVMはNQPから変換されたバイトコードを読み取り,都度実行する. MoaRVMの場合この処理はMVM\_interp\_runという関数で行われている. この関数内ではMoarVMが実行すべき命令が並んだ命令列を持ち,その値で巨大なcase文,またはCのラベルジャンプによって分岐させる. 分岐後は命令に応じた処理をMoarVMが行い,次の命令を実行する. -例えばno\_op命令は何も実行せず,次の命令に遷移するなどである. 次の命令に遷移する為には,現在の命令列から,実行した命令の長さ分プログラムカウンタの様な変数をインクリメントする. インクリメント後の命令列が指す値を,実行すべき命令として設定し,その値がなんであるかを読み取る. 読み取りが終了後,再びswitch文,またはラベルジャンプでその処理へと遷移する. @@ -117,7 +129,7 @@ Cファイルでの可読性とモジュール化が損なわれてしまう. ラベルにbreak pointを設定できない為デバッグし辛いなどがあげられる. -\section{CbCによるMoarVMの命令ディスパッチ部分の修正} +\section{CbCMoarVMのディスパッチ} 本研究ではMoarVMは2018.04.01のバージョンで実装している. 命令コードの実行すべき単位はCbCのCodeGearの単位として見れる. その為この処理を命令ごとCodeGearとして変換する. @@ -127,6 +139,16 @@ MoarVMはこの配列を参照し,要素として得られるCodeGearに軽量継続を行う. CodeGearでの処理が終了すると,次のCodeGearを決定する為に必要な計算をcbc\_nextというCodeGearで行う. cbc\_nextで次の遷移先が決定すると,そのCodeGearに軽量継続を行う.CbCMoarVMではこれを繰り返す. +\lstinputlisting[label=codeseg, caption=CbCMoarVM内のインタプリタの状態遷移]{cbc_codesegs.cbc} + +\begin{figure}[ht] + \begin{center} + \includegraphics[width=70mm]{cbc_next.pdf} + \end{center} + \caption{CbCにおけるMoarVMバイトコードインタプリタ内の状態遷移} + \label{fig:perl6cbcinter} +\end{figure} + オリジナルのMoarVMとは異なり,同一関数上で実行する訳では無い為,MVM\_interp\_runで定義している局所変数のレジスタreg\_baseなどにアクセスすることは通常では出来ない. その為CodeSegmentの遷移において,これら必要なインタプリタの情報を纏めた構造体INTERを宣言し,このポインタであるINTERPを引数として入力する. @@ -137,11 +159,12 @@ このCbCMoarVMのデバッグにはオリジナルのMoarVMとCbCMoarVMが実行した命令コードをデバッガで出力しログを取る必要がある. 取得したログから実行すべき命令番号が設定されている変数opの値を,オリジナルとCbC版で違いが発生するか解析する. -違いがあった場合,この命令を実行する箇所にbreak pointをかけて変数の値を比較する. -\section{今後の課題} -現在は命令処理のCodeGear変換が実装し,実際に多くのMoarVMByteCodeの実行が可能である. -しかしオブジェクト生成のエラーによりNQPのセルフビルドは実現できていない為,これの原因追求と修正を行う. +\section{まとめ} +現在はCbCMoarVMの命令ディスパッチに該当するCodeGearの実装を終了し,NQPリポジトリに用意されているテストを80\%通化している. +またMoarVMのデバッグやCbCコードの自動変換ツールなどの手法を確立した. + +現在はオブジェクト生成のエラーによりNQPのセルフビルドを実現できていない為,これの原因追求と修正を行う. また現在は次のCodeGearを計算しているが,これを計算せず直接実行するThreded Codeの実装を行いより高速化を図る. 並行して利用しているCbCコンパイラに幾つかのバグが本研究を通して発見された為,コンパイラのバグの修正を行う.