view mid_thesis.tex @ 8:e35adb402a6a

update
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 12 Nov 2018 14:12:44 +0900
parents 5c8e88841a30
children 27fbeff70031
line wrap: on
line source

\documentclass[twocolumn,twoside,9.5pt]{jarticle}
\usepackage[dvipdfmx]{graphicx}
\usepackage{picins}
\usepackage{fancyhdr}
\usepackage{abstract}
\usepackage{url}
\usepackage{float}
%\pagestyle{fancy}
\lhead{\parpic{\includegraphics[height=1zw,keepaspectratio,bb=0 0 251 246]{pic/emblem-bitmap.pdf}}琉球大学主催 工学部情報工学科 卒業研究中間発表会}
\rhead{}
\cfoot{}

\setlength{\topmargin}{-1in \addtolength{\topmargin}{15mm}}
\setlength{\headheight}{0mm}
\setlength{\headsep}{5mm}
\setlength{\oddsidemargin}{-1in \addtolength{\oddsidemargin}{11mm}}
\setlength{\evensidemargin}{-1in \addtolength{\evensidemargin}{21mm}}
\setlength{\textwidth}{181mm}
\setlength{\textheight}{261mm}
\setlength{\footskip}{0mm}
\pagestyle{empty}

\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処理系}
\author{155730B 氏名 {清水}{隆博} 指導教員 : 河野 真治}
\date{}
\maketitle
\thispagestyle{fancy}

\section{研究目的}
スクリプト言語Perl(Perl5)の後継言語としてPerl6が開発されている.
Perl6はMoarVMと言うVMで動作するが,処理時間がPerlを始めとした現在広く使われているスクリプト言語と比較すると非常に低速であり
実務として利用できるレベルに達していない.
またMoarVMの実装も巨大なswitch-case文が使用されており開発の難易度も高い.
この問題を解決するために,CbCを用いてMoarVMの一部を書き直し高速化かつわかりやすい処理系を実装する.
CbCはCよりきめ細やかな実装が出来るため,言語処理系の実装に適していると推測できる.
その為本研究ではCbCを言語処理系の実装に用いた場合の利点と難点についても考察する.

\section{CbC}
Perl6処理系の改良にはgccとLLVM/Clang上に実装したContinuation based C(CbC)を用いる.
CbCはCodeGearを基本的な処理単位とし,CodeGearの遷移でプログラムを記述するCの下位言語である.
CodeGearの宣言は\_\_codeという型を持つ関数として宣言する.
\_\_codeは内部的にはvoid型として扱っているが,プログラマからの扱いはCodeGearである事を示す指示子のような役割である.
CodeGearはCの関数とは異なり返り値を持たず,呼び差し元の関数に戻る代わりに別のCodeGearへ遷移する.
CbCにおけるCodeGear間の継続はスタックに値を積まず,環境も遷移時に持たない為軽量継続と呼ぶ.
CbCは軽量継続を中心にプログラミングする事が可能であるため,レジスタの移動などが行われない.
その為並列化やループ制御,関数呼び出しにおけるスタック制御などを意識したプログラミングスタイルでプログラミングする事が可能である.
\lstinputlisting[label=cbcexample,  caption=cbc\_example.cbc]{src/cbc_example.cbc}



\section{Perl6}
Perlの現在の主流な実装はRakudoである.RakudoはMoarVM,とNQPと呼ばれるPerl6のサブセット,NQPで記述されたPerl6という構成である.
MoarVMはNQPを解釈する.
このNQPで記述されたPerl6の事をRakudoと呼ぶ.
RakudoはMoarVMの他にJVM,Javascriptを動作環境として選択可能である.
言語的な特徴ではPerl5とは違いオブジェクト指向のサポートが強力になり,漸進的型付け言語としての特徴を持つ.

%処理時間は状況にもよるが231Kbのファイルを正規表現で検索する例題を実行した場合
処理時間は状況によるが,231KBのファイルを正規表現で検索する例題の場合Perl5が0.04sに対しMoarVMに乗せたPerl6は0.86sとおよそ20倍の速度差がある.
%* Perl5
%    * 0.04s
%* Ruby
%    * 0.15s
%* Python
%    * 0.06s
%* Java
%    * 0.27s
%* Perl6(Moar)
%    * 0.86s

\section{NQP}
NQPとはPerl6のサブセットである.
その為基本的な文法などはPerl6に準拠しているが,変数を束縛で宣言するなどの違いが見られる.

NQPは最終的にはNQP自身でブートストラップする言語であるが,ビルドの最初にはすでに書かれたMoarvMByteCodeを必要とする.
このMoarVMByteCodeの状態をStage0と言う.
Perl6の一部はNQPを拡張したもので書かれている為,Rakudoを動作させる為にはMoarVMなどのVM,VMに対応させる様にビルドしたNQPがそれぞれ必要となる.
NQPは与えられたStage0を使いStage1をビルドし,そのStage1を利用しStage2をビルドする事で生成できる.

\section{MoarVM}
MoarVMはPerl6に特化したVMである.C言語で実装されている.
JITコンパイルなどが現在導入されているが,起動時間などが低速である問題がある.
MoarVM独自のByteCodeがあり,NQPからこれを出力する機能などが存在している.
% IT図をいれる


\section{MoarVMのディスパッチ}
MoarVMはNQPから変換されたバイトコードを読み取り,都度実行する.
MoarVMの場合この処理はMVM\_interp\_runという関数で行われている.
この関数内ではMoarVMが実行すべき命令が並んだ命令列を持ち,その値で巨大なcase文,またはCのラベルジャンプによって分岐させる.
分岐後は命令に応じた処理をMoarVMが行い,次の命令を実行する.
分岐後は命令にごとの処理を実行し,現在の命令列から,実行した命令の長さ分命令列を進める.
進めた後にcase文の先頭もしくはCのラベルジャンプを利用して次の処理に遷移する.
これを命令コードのディスパッチと呼ぶ.
命令コードの実行の中では,現在のMoarVMのレジスタであるreg\_baseやスレッドごとの環境である構造体tcなどを参照する.
この方法の問題点として,巨大なcase文になっている為命令列の分割が出来ない.
ディスパッチ部分の処理が都度走る為低速になる.
Cファイルでの可読性とモジュール化が損なわれてしまう.
ラベルにbreak pointを設定できない為デバッグし辛いなどがあげられる.
\lstinputlisting[label=origdis,  caption=MoarVM内のインタプリタのディスパッチ]{src/dispatch.c}

\section{CbCMoarVMのディスパッチ}
本研究ではMoarVMは2018.04.01のバージョンで実装している.
命令コードの実行すべき単位はCbCのCodeGearの単位として扱える為命令処理をCodeGearに変換する.
変換されたCodeGearはオリジナルのMoarVMの命令コードと対応させる為にCodeGearの配列に格納する.
MoarVMはこの配列を参照し,要素として得られるCodeGearに軽量継続を行う.
CodeGearでの処理が終了すると,次のCodeGearを決定する為に必要な計算をcbc\_nextというCodeGearで行い,次の命令列に軽量継続する.
\lstinputlisting[label=codeseg,  caption=CbCMoarVM内のインタプリタの状態遷移]{src/cbc_codesegs.cbc}

\begin{figure}[ht]
     \begin{center}
     \includegraphics[width=50mm]{pic/cbc_next.pdf}
     \end{center}
     \caption{CbCにおけるMoarVMバイトコードインタプリタ内の状態遷移}
    \label{fig:perl6cbcinter}
\end{figure}

\begin{figure}[ht]
     \begin{center}
     \includegraphics[width=50mm]{pic/stagenqp.pdf}
     \end{center}
     \caption{NQPのビルドフロー}
    \label{fig:perl6cbcinter2}
\end{figure}

オリジナルのMoarVMとは異なり,同一関数上で実行する訳では無い為,MVM\_interp\_runで定義している局所変数のレジスタreg\_baseなどにアクセスすることは通常では出来ない.
その為CodeGearの遷移において,これら必要なインタプリタの情報を纏めた構造体INTERを宣言し,このポインタであるINTERPを引数として入力する.
各CodeGearではこのINTERPを経由することでレジスタ情報などにアクセスする.

この方法の利点としてCodeGearは単なる関数として扱える為,元のソースコードの様に同一ファイル内に全ての処理を書く必要がない.
またラベルにはbreak pointを設定する事が出来なかったが,CodeGearはデバッガからは関数として見る事ができるため通常のCの関数の様にbreak pointを設定する事が可能である.

このCbCMoarVMのデバッグにはオリジナルのMoarVMとCbCMoarVMが実行した命令コードをデバッガで出力しログを取る必要がある.
取得したログから実行すべき命令番号が設定されている変数opの値を,オリジナルとCbC版で違いが発生するか解析する.

\section{まとめ}
現在はCbCMoarVMの命令ディスパッチに該当するCodeGearの実装を終了し,NQPリポジトリに用意されているテストを80\%通化している.
またMoarVMのデバッグやCbCコードの自動変換ツールなどの手法を確立した.

現在はオブジェクト生成のエラーによりNQPのセルフビルドを実現できていない為,これの原因追求と修正を行う.
また現在は次のCodeGearを計算しているが,これを計算せず直接実行するThreded Codeの実装を行いより高速化を図る.
並行して利用しているCbCコンパイラに幾つかのバグが本研究を通して発見された為,コンパイラのバグの修正を行う.

\nocite{*}
\bibliographystyle{junsrt}
\bibliography{reference}
\end{document}