Mercurial > hg > Papers > 2019 > koo-prosym
view Paper/koo.tex @ 1:1923d7d99433
add mindmap
author | e165727 <e165727@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 05 Nov 2019 15:46:34 +0900 |
parents | 5e53003f8f1f |
children | fdb00b58c78c |
line wrap: on
line source
% withpage: ページ番号をつける (著者確認用) % english: 英語原稿用フォーマット \documentclass{ipsjprosym} %\documentclass[withpage, english]{ipsjprosym} \usepackage[dvipdfmx]{graphicx} \usepackage{latexsym} \usepackage{comment} \usepackage{listings} \usepackage{here} \lstset{ language=C, tabsize=2, frame=single, basicstyle={\tt\footnotesize}, % identifierstyle={\footnotesize}, % commentstyle={\footnotesize\itshape}, % keywordstyle={\footnotesize\ttfamily}, % ndkeywordstyle={\footnotesize\ttfamily}, % 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}} \usepackage{url} \begin{document} % Title, Author %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{Perl6のサーバを使った実行} %\affiliate{IPSJ}{情報処理学会} \affiliate{IERYUKYU}{琉球大学工学部情報工学科} \author{福田 光希}{Kouki FUKUDA}{IERYUKYU}[k.fukuda@cr.ie.u-ryukyu.ac.jp] \author{河野 真治}{Shinji KONO}{IERYUKYU}[kono@ie.u-ryukyu.ac.jp] %概要 \begin{abstract} スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている. Perl6は設計と実装が区分されており様々な処理系が開発されている. 現在主流なPerl6はRakudoと言われるプロジェクトである. RakudoではPerl6自体をNQP(NotQuitPerl)と言われるPerl6のサブセットで記述し, NQPをVMが解釈するという処理の流れになっている. このVMは任意のVMが選択できるようになっており,主に利用されているVMにCで書かれたMoarVMが存在する. MoarVMはJITコンパイルなどをサポートしているが, 全体的な起動時間及び処理速度がPerl5と比較し非常に低速である. この問題を解決するためにContinuation based C (CbC)という言語を一部用いてMoarVMの書き換えを行う. CbCはCよりも細かな単位で記述が可能である為, 言語処理系の実装に適していると考えられる. CbCに関する今までの研究においては, 言語処理系にCbCを利用した事例が少ない. その為, 本稿ではCbCを言語処理系に用いた場合の利点やデバッグ手法などについても述べる. \end{abstract} \begin{jkeyword} プログラミング言語, コンパイラ, CbC, Perl6, MoarVM, Raku \end{jkeyword} \maketitle % Body %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{スクリプト言語の高速実行} スクリプト言語Perl6は任意のVMが選択できるようになっており,主に利用されているVMにCで書かれたMoarVMが存在する. MoarVMはJITコンパイルなどをサポートしているが, 全体的な起動時間及び処理速度がPerl5やPython,Rubyなどの主要なスクリプト言語と比較し非常に低速である. この問題を解決するために, Perl6プログラムのサーバーを用いた実行手法の提案を行う. ここでいうサーバーとは転送したスクリプトを実行する環境のことである. またサーバーでは,サーバーに投げられたRakuをコンパイラで実行する際に,そのスクリプトが次に実行するスクリプトに影響を与えないことを保証する必要がある. この問題を解決するために,サーバーのコンテナ化を行う. \section{Raku} この章では現在までのRakuの遍歴及びRakuの言語的な特徴について記載する. \subsection{Rakuの構想} Perl6 は 2002 年に LarryWall が Perl を置き換え る言語として設計を開始した.Perl5 の言語的な問題点であるオブジェクト指向機能の強力なサポー トなどを取り入れた言語として設計された.Perl5 は設計と実装が同一であり, Larry らによって書かれた C 実装のみだった.Perl6 は設計と実装が分離している.言語的な特徴としては, 独自に Perl6 の文法を拡張可能な Grammar, Perl5 と比較した 場合のオブジェクト指向言語としての進化も見られる.また Perl6 は漸進的型付け言語である.従来の Perl の様に変数に代入する対象の型や, 文脈に応じて型を変更する動的型言語としての側面を 持ちつつ, 独自に定義した型を始めとする様々な 型に, 静的に変数の型を設定する事が可能である. Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しない.従って現在では Perl6 と Perl5 は別言語としての開発方針になっている.Perl6 は現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられている. Rakuは元はPerl5の後継言語のPerl6として開発されていたが,現在は名称が変更されRakuとなっている. Rakuの現在の主流な実装はRakudoである.RakudoはMoarVM,とNQPと呼ばれるRakuのサブセット,NQPとRaku自身で記述されたRakuという構成である. MoarVMはNQPとByte Codeを解釈する. NQP とは Not Quite Perl の略で Raku のサブセットである.その為基本的な文 法などは Raku に準拠しているが,変数を束縛で宣言する などの違いが見られる. このNQPで記述されたRakuの事をRakudoと呼ぶ. RakudoはMoarVMの他にJVM,Javascriptを動作環境として選択可能である. Rakuの起動は,MoarVMを起動,nqpをロード,Rakudoをロードもしくはコンパイルし,その後JITしながら実行する. \begin{figure}[H] \begin{center} \includegraphics[width=70mm]{images/Rakudo.pdf} \end{center} \caption{Rakudoの構成} \label{fig:perl6cbcinter} \end{figure} \subsection{MoarVM} \begin{comment} MoarVM は Raku に特化した VM である.C言語で実装されている. JITコンパイルなどが現在導入されているが,起動時間などが低速である問題がある. MoarVM 独自の ByteCode があり, NQP からこれを出力する機能などが存在している. \end{comment} \subsection{NQP} \begin{comment} NQPとはRakuのサブセットである. その為基本的な文法などはRakuに準拠しているが,変数を束縛で宣言するなどの違いが見られる. NQPは最終的にはNQP自身でブートストラップする言語であるが,ビルドの最初にはすでに書かれたMoarvMByteCodeを必要とする. このMoarVMByteCodeの状態をStage0と言う. Rakuの一部はNQPを拡張したもので書かれている為,Rakudoを動作させる為にはMoarVMなどのVM,VMに対応させる様にビルドしたNQPがそれぞれ必要となる. NQPは与えられたStage0を使いStage1をビルドし,そのStage1を利用しStage2をビルドする事で生成できる. \end{comment} RakudoにおけるNQPは現在MoarVM, JVM上で動作する. NQPはPerl6のサブセットであるため, 主な文法などはPerl6に準拠しているが幾つか異なる点が存在する. NQPは最終的にはNQP自身でブートストラップする言語であるが, ビルドの最初にはすでに書かれたMoarVMのバイトコードを必要とする. このMoarVMのバイトコードの状態をStage0と言う.%い, バイトコードが付随するソースディレクトリ内のディレクトリ名として設定されている. Perl6の一部はNQPを拡張したもので書かれている為, Rakudoを動作させる為にはMoarVMなどのVM, VMに対応させる様にビルドしたNQPがそれぞれ必要となる. 現在のNQPではMoarVM, JVMに対応するStage0はそれぞれMoarVMのバイトコード, jarファイルが用意されている. MoarVMのModuleLoaderはStage0にあるMoarVMのバイトコードで書かれた一連のファイルが該当する. Stage0にあるファイルをMoarVMに与えることで, NQPのインタプリタが実行される様になっている. これはStage0の一連のファイルは, MoarVMのバイトコードなどで記述されたNQPコンパイラのモジュールである為である. NQPのインタプリタはセルフビルドが完了すると, nqpというシェルスクリプトとして提供される. このシェルスクリプトは, ライブラリパスなどを設定してMoarVMの実行バイナリであるmoarを起動するものである. %NQPは6modelと呼ばれるオブジェクトモデルを採用としている.%が, これを構築する為に必要なNQPCORE,正規表現系のQRegex,MoarVMのModuleLoaderなどがMoarVMBytecodeで記述されている.これらMoarVMBytecodeの拡張子は.MoarVMである. %MoarVMに対してStage0のディレクトリにライブラリパスを設定し, nqp.MoarVMを実行させることでnqpの対話型環境が起動する. \begin{figure}[ht] \begin{center} \includegraphics[width=70mm]{fig/tgraph.pdf} \end{center} \caption{NQPのビルドフロー} \label{fig:nqpbuild} \end{figure} NQPのビルドフローを図\ref{fig:nqpbuild}に示す. RakudoによるPerl6に処理系はNQPにおけるnqpと同様に, moarにライブラリパスなどを設定したperl6というシェルスクリプトである. このperl6を動かすためにはself buildしたNQPコンパイラが必要となる. その為にStage0を利用してStage1をビルドしNQPコンパイラを作成する. Stage1は中間的な出力であり, 生成されたNQPファイルはStage2と同一であるが, MoarVMのバイトコードが異なる. Perl6では完全なセルフコンパイルを実行したNQPが要求される為, Stage1を利用してもう一度ビルドを行いStage2を作成する. Perl6のテストスイートであるRoastやドキュメントなどによって設計が定まっているPerl6とは異なりNQP自身の設計は今後も変更になる可能性が開発者から公表されている. 現在の公表されているNQPのオペコードはNQPのリポジトリに記述されているものである. %\subsection{Rakudo Perl6} %Rakudo実装上におけるPerl6はRakudo Perl6と呼ばれているGitリポジトリで管理されているプログラムのことである. %前述した通りRakudo Perl6はPerl6のサブセットであるNQPを用いて記述されている. %従ってyaccやlexと言ったPerl5の文字解析, 構文解析に利用していたプログラムは利用せず, NQP側で構文定義などを行っている. %NQPはNQP自身でBootstrappingされている為, Rakudo Perl6のbuild時にはNQPの実行環境として要したVM, それに基づいてbuildしたNQPがそれぞれ必要となる. \subsection{なぜRakuは遅いのか} 通常Rubyのようなスクリプト言語ではまずrubyVMが起動し,その後スクリプトをByte code に変換して実行という手順を踏む. Rakudo はインタプリタの起動時間及び、 全体的な処理時間が他のスクリプト言語と比較して非常に低速である。 これはRakudo自体がRakuで書かれているため,MoarVMを起動し,RakudoとNQP をコンパイルし,その後スクリプトのByte code変換というような手順で進むためである。 またRakuは実行時の情報が必要であり,メソッドを実行する際にinvokeが走ることも遅い原因である. \section{Abyssサーバー} ここではAbyssサーバーについて説明する.AbyssサーバーはRakuで書かれている. クライアント側から投げられたRakuを実行するためのサーバーである. 図1はAbyssサーバーを用いたスクリプト言語実行手順である. AbyssサーバーはユーザーがRakuを実行する際,クライアント側から転送されてきたファイルを事前に起動してあるサーバー側が処理し,その実行結果を返す構造となっている. この手法を用いることで,サーバー上で事前にRakudoを起動したRakudoを再利用し,投げられたRakuスクリプトの実行を行うためRakudoの起動時間を短縮できると推測できる. \begin{figure}[H] \begin{center} \includegraphics[width=80mm]{images/abyss.pdf} \end{center} \caption{Abyssサーバーを用いたスクリプト言語実行手順} \label{fig:perl6cbcinter} \end{figure} Code1はAbyss サーバーのソースコードである. Abyssサーバーは起動すると,まず自身にファイルを転送するためのソケットを生成し,その後ファイルを受け取るための待機ループに入る. ファイルパスを受け取るとファイルパスをバッファーに変換し読み込む,その後読み込んだバッファーを文字列にデコードし,ファイルパスの文字列を読み込み,ファイルの中身を式として評価するEVALFILEを用いて,プログラムを実行する. Code1の2行目にあるMONKEY−SEE−NO−EVALはRaku上でEVALFILEを使用可能にするpragmaである. 現状のRakuのEVALFILEでは,出力がサーバー側に返っているので,クライアント側から出力を見るためにクライアント側に返す必要がある. \lstinputlisting[label=codeseg, caption=Abyssサーバーのsource code]{code/abyss.p6} \lstinputlisting[label=codeseg, caption=クライアント側のsource code]{code/client.p6} %通常、自分でプロセス立ち上げてPerl6を実行する際は, %\section{問題点} \section{まとめ} 中間予稿までにPerl6スクリプトを投げて実行するサーバーの実装、および「自分でプロセス立ち上げてPerl6実行する手法」と「既にあるサーバーに投げてPerl6スクリプトを実行する手法」の差を測るために時間の計測を行った。 今回実装したサーバーでは,別のスクリプトを実行する前にサーバーのコンテナ化をできていないので次回以降の課題とする. 今回の実装ではTCPソケットを用いたがTCPソケットを用いるとサーバーを立ち上げた際に外部からファイルを転送される可能性があるので,Unix domain socketの実装を行い,それを用いたクライアント・サーバーを作成することで安全性が高まると考えた Rakuには現状Unix domainソケットの実装がないので、Unix domainソケットを実装し、自分以外が実行できないようにすることが今後の課題に挙げられる. また今回例題として用いたものはスクリプト言語Rakuであったが,その他のスクリプト言語にも応用が利くかどうか検討する必要はある 今回用いたRakuのEVALFILE自体にクライアント側に出力を返す実装追加することも今後の課題に挙げられる. \begin{acknowledgment} 謝辞が必要であれば,ここに書く. \end{acknowledgment} \begin{thebibliography}{9} \bibitem{キー1} Andrew Shitov. Perl6 Deep Dive \bibitem{キー2} 清水隆博, 河野真治. CbC を用いた Perl6 処理系. 琉球大学工学部情報工学科平成 30 年度学位論文 (学士), 2018. \bibitem{キー3} Perl6 Documentation\\{https://docs.perl6.org} (2019/10/22 アクセス) \bibitem{latex} 奥村晴彦, 黒木裕介: \textbf{LaTeX2e美文書作成入門}. 技術評論社, 2013. \end{thebibliography} \nocite{*} \bibliographystyle{ipsjsort} \bibliography{reference} \end{document}