comparison Paper/anatofuz.tex @ 74:93f1484eab1e

fix
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Tue, 27 Nov 2018 15:22:57 +0900
parents bd348011ecac
children 1c1307cedf11
comparison
equal deleted inserted replaced
73:140f086fee21 74:93f1484eab1e
51 このVMは任意のVMが選択できるようになっており, 現在はMoarVM, JavaVM, JavaScriptが動作環境として選択可能である. 51 このVMは任意のVMが選択できるようになっており, 現在はMoarVM, JavaVM, JavaScriptが動作環境として選択可能である.
52 主に利用されているVMにCで書かれたMoarVMが存在する. 52 主に利用されているVMにCで書かれたMoarVMが存在する.
53 MoarVMはJITコンパイルなどをサポートしているが, 全体的な起動時間及び処理速度がPerl5と比較し非常に低速である. 53 MoarVMはJITコンパイルなどをサポートしているが, 全体的な起動時間及び処理速度がPerl5と比較し非常に低速である.
54 この問題を解決するためにContinuation based C (CbC)という言語を一部用いてMoarVMの書き換えを行う. 54 この問題を解決するためにContinuation based C (CbC)という言語を一部用いてMoarVMの書き換えを行う.
55 CbCはCよりも細かな単位で記述が可能である為, 言語処理系の実装に適していると考えられる. 55 CbCはCよりも細かな単位で記述が可能である為, 言語処理系の実装に適していると考えられる.
56 その為, 本論文ではCbCを言語処理系に用いた場合の利点やデバッグ手法などについても述べる. 56 その為, 本稿ではCbCを言語処理系に用いた場合の利点やデバッグ手法などについても述べる.
57 57
58 58
59 \end{abstract} 59 \end{abstract}
60 60
61 \begin{jkeyword} 61 \begin{jkeyword}
71 現在活発に開発が進んでいる言語にPerl6がある. 71 現在活発に開発が進んでいる言語にPerl6がある.
72 Perl6はMoarVMと呼ばれるVMを中心としたRakudoと呼ばれる実装が現在の主流となっている. 72 Perl6はMoarVMと呼ばれるVMを中心としたRakudoと呼ばれる実装が現在の主流となっている.
73 Rakudoは処理速度が他のプログラミング言語と比較しても非常に低速である. 73 Rakudoは処理速度が他のプログラミング言語と比較しても非常に低速である.
74 その為, 現在日本国内ではPerl6を実務として利用するケースは概ね存在しない. 74 その為, 現在日本国内ではPerl6を実務として利用するケースは概ね存在しない.
75 Perl6の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される. 75 Perl6の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される.
76 その為本研究では, CbCを用いた言語処理系の実装の一例としてMoarVMをCbCで書き換えたCbCMoarVMを提案する. 76 その為本稿では, CbCを用いた言語処理系の実装の一例としてMoarVMをCbCで書き換えたCbCMoarVMを提案する.
77 77
78 CbCをMoarVMの実装として利用した場合, CbCの持つ機能によってMoarVMの高速化を中心とした改良に有益な効果があると推測出来る. 78 CbCをMoarVMの実装として利用した場合, CbCの持つ機能によってMoarVMの高速化を中心とした改良に有益な効果があると推測出来る.
79 また, 現在までのCbCを用いた研究においては言語処理系への応用例が少ない. 79 また, 現在までのCbCを用いた研究においては言語処理系への応用例が少ない.
80 従って, 本研究はCbCをスクリプト言語の実装に適応した場合, どのような利点やプログラミング上の問題点に遭遇するか, CbCの応用としての側面でも行う. 80 従って, 本稿はCbCをスクリプト言語の実装に適応した場合, どのような利点やプログラミング上の問題点に遭遇するか, CbCの応用としての側面でも行う.
81 この際にCbCを用いた言語処理系のデバッグを行う際には, CbCを使わずに記述されたオリジナルの言語処理系との並列デバッグが必要となる. 81 この際にCbCを用いた言語処理系のデバッグを行う際には, CbCを使わずに記述されたオリジナルの言語処理系との並列デバッグが必要となる.
82 従ってMoarVMにCbCを適応した場合, どのようにすれば並列デバッグが行えるかについて述べる. 82 従ってMoarVMにCbCを適応した場合, どのようにすれば並列デバッグが行えるかについて述べる.
83 本稿ではまずCbC, Perl6の特徴及び現在の実装について述べ, 本研究で行ったCbCで書き換えたMoarVMについてデバッグ手法も含め解説する. 83 本稿ではまずCbC, Perl6の特徴及び現在の実装について述べ, CbCで書き換えたMoarVMについてデバッグ手法も含め解説する.
84 そして本研究で得られたCbCを言語処理系に適応した場合の利点と欠点について述べ, 今後の展望について記載する. 84 研究にあたり, 得られたCbCを言語処理系に適応した場合の利点と欠点について述べ, 今後の展望について記載する.
85 85
86 \section{CbC} 86 \section{CbC}
87 \subsection{CbCの概要} 87 \subsection{CbCの概要}
88 CbCは当研究室で開発しているプログラミング言語である. 88 CbCは当研究室で開発しているプログラミング言語である.
89 Cレベルでのプログラミングを行う場合, 本来プログラマが行いたい処理の他にmallocなどを利用したメモリのアロケートやエラーハンドリングなどを記述する必要がある. 89 Cレベルでのプログラミングを行う場合, 本来プログラマが行いたい処理の他にmallocなどを利用したメモリのアロケートやエラーハンドリングなどを記述する必要がある.
125 まずCodeGear内で宣言した局所変数のポインタを大域変数の配列などに保存した状態でgotoしてしまうとtail call最適化が無効となる. 125 まずCodeGear内で宣言した局所変数のポインタを大域変数の配列などに保存した状態でgotoしてしまうとtail call最適化が無効となる.
126 これはただの関数呼び出しになってしまう為, 直接的な被害はないもののCbCとしての利点が損なわれてしまう. 126 これはただの関数呼び出しになってしまう為, 直接的な被害はないもののCbCとしての利点が損なわれてしまう.
127 %また本来は操作しないはずのスタック領域の操作が入ってしまうため, プログラマの意図と反したスタックポインタなのど操作が行われてしまいバグが発生する可能性が存在する. 127 %また本来は操作しないはずのスタック領域の操作が入ってしまうため, プログラマの意図と反したスタックポインタなのど操作が行われてしまいバグが発生する可能性が存在する.
128 また, CbCの挙動としてCodeGearへの遷移時には軽量継続を行う為スタック領域の操作は行われないはずである. 128 また, CbCの挙動としてCodeGearへの遷移時には軽量継続を行う為スタック領域の操作は行われないはずである.
129 しかし, 現状は配列にCodeGearのアドレスを代入し, 間接的に軽量継続を行おうとすると, スタック領域の操作が通常の関数呼び出しの様に行われてしまう. 129 しかし, 現状は配列にCodeGearのアドレスを代入し, 間接的に軽量継続を行おうとすると, スタック領域の操作が通常の関数呼び出しの様に行われてしまう.
130 %これは一部CbCコンパイラが利用しているgcc側のref-zoneという機能が影響していたが
130 131
131 \subsection{CbCとCの互換性} 132 \subsection{CbCとCの互換性}
132 CbCコンパイラはコンパイル対象のソースコードがCbCであるかどうかを判断する. 133 CbCコンパイラはコンパイル対象のソースコードがCbCであるかどうかを判断する.
133 この際にCodeGearを利用していない場合は通常のCプログラムとして動作する. 134 この際にCodeGearを利用していない場合は通常のCプログラムとして動作する.
134 その為今回検証するMoarVMのビルドにおいてもCbCで書き換えたソースコードがあるMoarVMと, 手を加えていないオリジナルのMoarVMの2種類を同一のCbCコンパイラでビルドする事が可能である. 135 その為今回検証するMoarVMのビルドにおいてもCbCで書き換えたソースコードがあるMoarVMと, 手を加えていないオリジナルのMoarVMの2種類を同一のCbCコンパイラでビルドする事が可能である.
167 168
168 Perl6は言語仕様及び処理実装がPerl5と大幅に異なっており, 言語的な互換性が存在しない. 169 Perl6は言語仕様及び処理実装がPerl5と大幅に異なっており, 言語的な互換性が存在しない.
169 従って現在ではPerl6とPerl5は別言語としての開発方針になっている. 170 従って現在ではPerl6とPerl5は別言語としての開発方針になっている.
170 Perl6は現在有力な処理系であるRakudoから名前を取りRakuという別名がつけられている. 171 Perl6は現在有力な処理系であるRakudoから名前を取りRakuという別名がつけられている.
171 172
172 \subsection{Pugs} 173 \subsection{Rakudo以前の処理系}
173 Perl6の実装は様々なものが実装された. 174 Perl6の実装は様々なものが実装された.
174 まず2005年に唐鳳によってHaskellで実装されたPugs\cite{pugs}が登場した. 175 まず2005年に唐鳳によってHaskellで実装されたPugs\cite{pugs}が登場した.
175 Pugsは最初に登場したPerl6実装であり, この実装を基にしてPerl6の仕様も修正された. 176
176 現在Pugsは歴史的な実装となっており, 更新はされていない.
177
178 \subsection{Parrot}
179 その後Pythonとの共同動作環境としてParrot\cite{parrot}が実装された. 177 その後Pythonとの共同動作環境としてParrot\cite{parrot}が実装された.
180 ParrotはPASMと呼ばれるバイトコードを解釈可能なレジスタマシンである. 178 ParrotはPASMと呼ばれるバイトコードを解釈可能なレジスタマシンである.
181 ParrotでのPerl6の実装はNQP(NotQuitPerl)と呼ばれるPerl6のサブセットでPerl6を記述するというアイディアの基実装された. 179 ParrotでのPerl6の実装はNQP(NotQuitPerl)と呼ばれるPerl6のサブセットでPerl6を記述するというアイディアの基実装された.
182 ParrotVMは2006年のversion8.1.0が最後のリリースである. 180 ParrotVMは2006年のversion8.1.0が最後のリリースである.
183 こちらもPugsと同様に現在のPerl6プロジェクトでは歴史的な実装とされている. 181 こちらもPugsと同様に現在のPerl6プロジェクトでは歴史的な実装とされている.
256 現在のPerl6が他のプログラミング言語と比較した場合どのような違いがでるのか計測した. 254 現在のPerl6が他のプログラミング言語と比較した場合どのような違いがでるのか計測した.
257 macOSの/var/log/system.logファイルから正規表現でログ中のプログラムが書き込んだ回数を個別に数え上げるというものである. 255 macOSの/var/log/system.logファイルから正規表現でログ中のプログラムが書き込んだ回数を個別に数え上げるというものである.
258 今回はファイルを231Kと3GBの二種類用意し, どの様な違いが出るのか測定した. 256 今回はファイルを231Kと3GBの二種類用意し, どの様な違いが出るのか測定した.
259 257
260 測定した環境は次の通りである. 258 測定した環境は次の通りである.
259 今回は現在広く使用されているスクリプト言語であるPython, Perl5
260 またRakudoの処理系による処理時間の差を計測する為にMoarVM, JVMに構築したPerl6の処理速度を計測を行った.
261 JVM自体の処理時間とRakudoを構築したJVMの速度の差を見るために, 同様のプログラムをJava10でも行った.
261 262
262 \begin{itemize} 263 \begin{itemize}
263 \item Perl6 (MoarVM) ver.2018.04.01 264 \item Perl6 (MoarVM) ver.2018.04.01
264 \item Perl6 (JVM) 2018.06-163-g612d071b8 built on JVM 265 \item Perl6 (JVM) 2018.06-163-g612d071b8 built on JVM
265 \item Python 3.6.5 266 \item Python 3.6.5
276 3G & 2331.08 & 1665.56 & 101.16 & 48.85 & 41.35\\ \hline 277 3G & 2331.08 & 1665.56 & 101.16 & 48.85 & 41.35\\ \hline
277 \end{tabular} 278 \end{tabular}
278 \end{table} 279 \end{table}
279 280
280 計測結果からファイルサイズが小さい場合はMoarVMよりJVMに乗せたPerl6が低速であるが, ファイルサイズが大きい場合はJavaのJITが働くためMoarVMより高速に動いていると推測できる. 281 計測結果からファイルサイズが小さい場合はMoarVMよりJVMに乗せたPerl6が低速であるが, ファイルサイズが大きい場合はJavaのJITが働くためMoarVMより高速に動いていると推測できる.
282
281 283
282 %# 計測(3GB) 284 %# 計測(3GB)
283 285
284 %* Perl5c 286 %* Perl5c
285 % * 41.35s 287 % * 41.35s
312 314
313 \section{CbCによるMoarVM} 315 \section{CbCによるMoarVM}
314 この章では改良を行ったPerl6処理系であるMoarVMについて述べる. 316 この章では改良を行ったPerl6処理系であるMoarVMについて述べる.
315 今回改良を行ったMoarVMは2018.04.01であり, 利用したNQPは2018.04-3-g45ab6e3バージョンである. 317 今回改良を行ったMoarVMは2018.04.01であり, 利用したNQPは2018.04-3-g45ab6e3バージョンである.
316 \subsection{方針} 318 \subsection{方針}
319 Rakudo処理系の処理速度はNQPコンパイラ側の処理速度, 実行環境であるMoarVMなどのVM環境の主に2種類が影響していると考えられる.
320 NQP側はNQPで書かれている為, NQPの記述を修正すれば高速化することも考えられるが, 今回はVM側の処理系に着目した.
321 Rakudoが動作するVMは複数存在するが, MoarVMが現在主流の処理系である.
322 MoarVM自身はCで記述されているため, CbCを導入する事が可能である.
323 CbCの持つCodeGearや軽量継続を導入する事で, 通常のMoarVMと比較してよりきめ細やかな実装が出来ると推測される.
324 CodeGearをThreadedCodeなどに応用する事で, MoarVMの高速化が見込める.
325 また, CbCに関する今までの研究においては, CbCを言語処理系に応用した例が少ない為, CbCを言語処理系に適応した場合の挙動などを確認したい.
326 その為, 本稿ではCbCをMoarVMに導入したCbCMoarVMを実装する.
327
328
317 MoarVMそのものをCbCで書き換えることも考えられるがMoarVM自体既に巨大なプロジェクトである為すべてを書き換える事は困難である. 329 MoarVMそのものをCbCで書き換えることも考えられるがMoarVM自体既に巨大なプロジェクトである為すべてを書き換える事は困難である.
318 その為まず比較的CbCで書き換えることが容易な箇所を修正する. 330 その為まず比較的CbCで書き換えることが容易な箇所を修正する.
319 前章までに述べた通りCbCのCodeGearはコンパイラの基本ブロックに該当する. 331 前章までに述べた通りCbCのCodeGearはコンパイラの基本ブロックに該当する.
320 従ってMoarVMにおける基本ブロックの箇所をCodeGearに書き換える事が可能である. 332 従ってMoarVMにおける基本ブロックの箇所をCodeGearに書き換える事が可能である.
321 MoarVMにおける基本ブロックはインタプリタが実行するバイトコードごとの処理に該当する. 333 MoarVMにおける基本ブロックはインタプリタが実行するバイトコードごとの処理に該当する.
392 \caption{CbCにおけるMoarVMバイトコードインタプリタ内の状態遷移} 404 \caption{CbCにおけるMoarVMバイトコードインタプリタ内の状態遷移}
393 \label{fig:perl6cbcinter} 405 \label{fig:perl6cbcinter}
394 \end{figure} 406 \end{figure}
395 407
396 バイトコードの数は膨大である為, すべてを手作業で変換する事は望ましくない. 408 バイトコードの数は膨大である為, すべてを手作業で変換する事は望ましくない.
397 本研究ではPerlScriptを用いてinterp.cからCbCのCodeGearを自動生成するスクリプトを作成した. 409 従ってPerlScriptを用いてinterp.cからCbCのCodeGearを自動生成するスクリプトを作成した.
398 このスクリプトでは以下の修正手続きを実行する. 410 このスクリプトでは以下の修正手続きを実行する.
399 411
400 \begin{itemize} 412 \begin{itemize}
401 \item OP(.*)の.*部分をCodeGearの名前として, 先頭にcbc\_をつけた上で設定する. 413 \item OP(.*)の.*部分をCodeGearの名前として, 先頭にcbc\_をつけた上で設定する.
402 \item cur\_opなど構造体INTERのメンバ変数はポインタiから参照するように修正する 414 \item cur\_opなど構造体INTERのメンバ変数はポインタiから参照するように修正する
416 \section{MoarVMのデバッグ} 428 \section{MoarVMのデバッグ}
417 429
418 MoarVM自体のデバッグはMoarVMのリポジトリにテストコードが付随していない為単体では実行不可能である. 430 MoarVM自体のデバッグはMoarVMのリポジトリにテストコードが付随していない為単体では実行不可能である.
419 また, CbCを用いて言語処理系の改良時を行った際に言語処理系のデバッグを行う場合は, CbCを用いないオリジナルの処理系との並列デバッグが必要となる. 431 また, CbCを用いて言語処理系の改良時を行った際に言語処理系のデバッグを行う場合は, CbCを用いないオリジナルの処理系との並列デバッグが必要となる.
420 MoarVM自体にはデバッグを支援するツールが存在しない為, MoarVM自体のデバッグ方法や, CbCを用いた処理系との並列デバッグについて独自の手法を利用する必要がある. 432 MoarVM自体にはデバッグを支援するツールが存在しない為, MoarVM自体のデバッグ方法や, CbCを用いた処理系との並列デバッグについて独自の手法を利用する必要がある.
421 本研究ではMoarVMのデバッグにおけるCデバッガの使用方法とMoarVMのテスト方法についても示す. 433 本稿ではMoarVMのデバッグにおけるCデバッガの使用方法とMoarVMのテスト方法についても示す.
422 434
423 \subsection{MoarVMのバイトコードのデバッグ} 435 \subsection{MoarVMのバイトコードのデバッグ}
424 MoarVMの実行バイナリであるmoarに対して, MoarVMのバイトコードをdumpオプションを付けて読み込ませると, バイトコードがMoarVMによるアセンブリコードとして出力される. 436 MoarVMの実行バイナリであるmoarに対して, MoarVMのバイトコードをdumpオプションを付けて読み込ませると, バイトコードがMoarVMによるアセンブリコードとして出力される.
425 しかしこれはMoarVMが実行したバイトコードのトレースではなく, MoarVMのバイトコードを変換したものに過ぎない. 437 しかしこれはMoarVMが実行したバイトコードのトレースではなく, MoarVMのバイトコードを変換したものに過ぎない.
426 また, 明らかに異なる挙動を示すオリジナルのMoarVMと, CbCで書き換えたCbCMoarVM両者のmoarを利用しても同じ結果が返ってきてしまう. 438 また, 明らかに異なる挙動を示すオリジナルのMoarVMと, CbCで書き換えたCbCMoarVM両者のmoarを利用しても同じ結果が返ってきてしまう.
479 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている. 491 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている.
480 492
481 また現在はclang上に実装したCbCコンパイラではCodeGear内部のtaill call除去のエラーが発生してしまう為コンパイルする事が出来ない. 493 また現在はclang上に実装したCbCコンパイラではCodeGear内部のtaill call除去のエラーが発生してしまう為コンパイルする事が出来ない.
482 その為現在はgcc上に実装したcbcコンパイラを利用しgdbを利用しデバッグを行う. 494 その為現在はgcc上に実装したcbcコンパイラを利用しgdbを利用しデバッグを行う.
483 495
496 \subsection{他手法との比較}
497 本稿ではPerl6処理系の改良としてCbCを用い, 初期の実装を行った.
498 CbCを用い無い場合のMoarVMの改良方法としては, 命令コードに対応する処理をCの関数として記述し, この関数のポインタを利用する方法が考えられる.
499 関数ポインタの配列を作成し, 次の命令コードに対応する関数をポインタ経由で実行する.
500 Cの関数ポインタを利用した場合, CbCと同様に処理のモジュール化は可能である.
501 しかし, CbCとは違い軽量継続ではなく関数呼び出しで処理をする為, Cのスタックフレームが非常に巨大になる.
502 Cの関数呼び出しのコストから, 通常のcase文やラベルジャンプを利用した場合と速度差的に優位にならない.
503
504
484 505
485 \section{CbCMoarVMの利点と欠点} 506 \section{CbCMoarVMの利点と欠点}
486 MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された. 507 MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された.
487 本章ではまず利点を述べ, 次に現段階でのCbCを適応した場合の欠点について考察する. 508 本章ではまず利点を述べ, 次に現段階でのCbCを適応した場合の欠点について考察する.
488 509
586 従ってThreadedCodeを実現するにあたり新たな処理系を開発する必要がなく, 既存の資源を利用してThreadedCodeが実現出来る. 607 従ってThreadedCodeを実現するにあたり新たな処理系を開発する必要がなく, 既存の資源を利用してThreadedCodeが実現出来る.
587 これを繰り返す事でperlccなどと比較してより高速化したThrededCodeが実現できる. 608 これを繰り返す事でperlccなどと比較してより高速化したThrededCodeが実現できる.
588 609
589 610
590 \section{まとめ} 611 \section{まとめ}
591 本論文ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した. 612 本稿ではCbCによってPerl6の処理系であるMoarVMインタプリタの一部改良とその手法を示した.
592 CbCMoarVMではオリジナルのMoarVMと比較して以下の様な利点が見られた. 613 CbCMoarVMではオリジナルのMoarVMと比較して以下の様な利点が見られた.
593 614
594 \begin{itemize} 615 \begin{itemize}
595 \item CodeGear単位で命令処理を記述する事が可能となり, モジュール化が可能となった. 616 \item CodeGear単位で命令処理を記述する事が可能となり, モジュール化が可能となった.
596 \item ThreadedCodeを実装する際に効率的に実装ができる見込みが立った. 617 \item ThreadedCodeを実装する際に効率的に実装ができる見込みが立った.