# HG changeset patch # User e165727 # Date 1581844836 -32400 # Node ID b96b3244307bc8d5ad5e1fbbb9e2904940219714 # Parent 32db366529dd9bdf5274c12aaf8675b84db19742 update paper & slide diff -r 32db366529dd -r b96b3244307b .DS_Store Binary file .DS_Store has changed diff -r 32db366529dd -r b96b3244307b Paper/165727F.pdf Binary file Paper/165727F.pdf has changed diff -r 32db366529dd -r b96b3244307b Paper/chapter1.tex --- a/Paper/chapter1.tex Sun Feb 16 16:23:52 2020 +0900 +++ b/Paper/chapter1.tex Sun Feb 16 18:20:36 2020 +0900 @@ -15,7 +15,7 @@ %Raku は MoarVM に基づくJIT コンパイラを持っており,コンパイルされた結果はプロセッサが実行可能な機械語に相当する. %Raku のような言語に JITコンパイラを持ち, 起動時間が遅い PyPy などの言語がある. -本研究では, スクリプト言語 Raku の起動時間及び, 処理速度の改善を図り, 研究をするにあたり得られた, OS上でscript言語を実行する場合の利点と欠点について述べ, 今後の展望について記載する. +本研究では, スクリプト言語 Raku の起動時間及び, 処理速度の改善を図り, 研究をするにあたり得られた, OS上でスクリプト言語を実行する方法の改善点ついて述べ, 今後の展望について記載する. また, その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し,サーバー上でコンパイルを行う手法を提案する. 著者らは, この提案手法に沿って『Abyss サーバー』を実装している. diff -r 32db366529dd -r b96b3244307b Paper/chapter3.tex --- a/Paper/chapter3.tex Sun Feb 16 16:23:52 2020 +0900 +++ b/Paper/chapter3.tex Sun Feb 16 18:20:36 2020 +0900 @@ -89,6 +89,22 @@ 提案手法 & 0.0238 sec \\ \hline \end{tabular} \end{center} - \caption{通常実行と提案手法の速度比較} + \caption{helloworldの速度比較} \end{table} -提案手法は通常実行に比べて約10倍早い実行結果になった + +提案手法は通常実行に比べて約10倍早い実行結果になった \\ + +実験結果 +\begin{table}[H] + \begin{center} + \begin{tabular}{|l|l|} \hline + Language& Time \\ \hline + 通常実行 & 0.2128 sec \\ + 提案手法 & 0.0415 sec \\ \hline + \end{tabular} + \end{center} + \caption{フィボナッチ数列の例題の速度比較} +\end{table} + +先ほどと同様, 提案手法は通常実行に比べて早い結果となり, 約5倍早い実行結果になった \\ +内部で処理が走っている時間だけさが縮まったと考えられる. diff -r 32db366529dd -r b96b3244307b Paper/chapter4.tex --- a/Paper/chapter4.tex Sun Feb 16 16:23:52 2020 +0900 +++ b/Paper/chapter4.tex Sun Feb 16 18:20:36 2020 +0900 @@ -2,20 +2,24 @@ \section{比較} \begin{itemize} -\item{Microsoft CLR} -\\ +\item{Microsoft CLR}\\ .NET Framework には, 共通言語ランタイム(Common Language Runtime)と呼ばれるランタイム環境がある. .NET対応のソフトウェアは, 様々なプログラミング言語で書かれたソースコードから, いったん共通中間言語 (Common Intermediate Language)による形式に変換されて利用者のもとに配布される. CIL 形式のプログラムを解釈し, コンピュータが直に実行可能な機械語によるプログラムに変換して実行するソフトウェアが CLR である. -現状の Abyss サーバーはプロセスとして立ち上げているが, CLR は OS に直接組み込む必要があるが, Abyss サーバーはプロセス上で実行しているため OS に手を加えず実装が容易である. -\\ -\item{PyPy} -\\ -PyPy は Python の 実装の一つであり, Cpython のサブセットである RPython で記述された 処理系である. -\\ +現状の Abyss サーバーはプロセスとして立ち上げているが, CLR は OS に直接組み込む必要があるが, Abyss サーバーはプロセス上で実行しているため OS に手を加えず実装が容易である. \\ + +\item{FastCGI}\\ +FastCGI とは CGI を改良したものである. +通常のCGIは, ユーザーから要求があるたびにプロセスを生成しプログラムを実行し,プロセスを破棄する. +FastCGIでは一度プログラムが起動し, ロードされるとメモリ上にしばらく残り, 次回実行される際にそのプログラムを再利用する. \\ +FastCGI は Abyss Server とよく似ているが, FastCGI と Abyss Server の違いは. FastCGI は HTTPリクエストが起動のトリガーになっており, Abyss Server はユーザーが実行したいプログラムを送信することが起動のトリガーになっていることである + +\item{PyPy}\\ +PyPy は Python の 実装の一つであり, Cpython のサブセットである RPython で記述された 処理系である. + PyPy は JIT コンパイル を採用しており, 実行時にコードを機械語にコンパイルして効率的に実行させることができる. PyPy は Cpython より実行速度が速いが起動速度は Cpython と比較して約3倍遅い. -Perl6 と同様, PyPyは Cpython と比較して起動時間が遅いため今回提案した手法を応用できると予測できる. +Raku と同様, PyPyは Cpython と比較して起動時間が遅いため今回提案した手法を応用できると予測できる. \\ \end{itemize} \section{Abyss Server の利点} diff -r 32db366529dd -r b96b3244307b Paper/code/client.p6 --- a/Paper/code/client.p6 Sun Feb 16 16:23:52 2020 +0900 +++ b/Paper/code/client.p6 Sun Feb 16 18:20:36 2020 +0900 @@ -1,15 +1,16 @@ use IO::Socket::Unix; -use NativeCall; - -sub close(int32) returns int32 is native { ... } -sub dup(int32 $old) returns int32 is native { ... } -sub dup2(int32 $old, int32 $new) returns int32 is native { ... } my $conn = IO::Socket::INET.new( :host, :port(3333) ); $conn.print: 'Absolute file path'; -say $conn.lines; +my $sock_msg; -$conn.close; +while my $buf = $conn.recv(:bin) +{ + $sock_msg = $buf.decode; + last; +} + +say $sock_msg; diff -r 32db366529dd -r b96b3244307b Paper/main.pdf Binary file Paper/main.pdf has changed diff -r 32db366529dd -r b96b3244307b Prepaper/165727F-pre.pdf Binary file Prepaper/165727F-pre.pdf has changed diff -r 32db366529dd -r b96b3244307b Prepaper/code/abyss.p6 --- a/Prepaper/code/abyss.p6 Sun Feb 16 16:23:52 2020 +0900 +++ b/Prepaper/code/abyss.p6 Sun Feb 16 18:20:36 2020 +0900 @@ -1,17 +1,34 @@ -unit class Abyss::Server:ver<0.0.1>; +use v6.c; +unit class Abyss::Server:ver<0.0.1>:auth; use MONKEY-SEE-NO-EVAL; +use IO::Socket::Unix; +use NativeCall; + +sub close(int32) returns int32 is native { ... } +sub dup(int32 $old) returns int32 is native { ... } +sub dup2(int32 $new, int32 $old) returns int32 is native { ... } -method readeval { - my $listen = IO::Socket::INET.new( - :listen, - :localhost, - :localport(3333) - ); - loop { - my $conn = $listen.accept; - while my $buf = $conn.read(1024) { - EVALFILE $buf.decode; +method readeval +{ + my $listen = IO::Socket::Unix.new( :listen, + :localhost, + :localport(3333) ); + my $backup = dup(1); + say DateTime.now; + + loop + { + my $conn = $listen.accept; + my $sock_msg; + my $buf = $conn.recv(); + $sock_msg = $buf; + close(1); + dup2($conn.native-descriptor(), 1); + EVALFILE $sock_msg; + dup2($backup, 1); + close($backup); + $conn.close; } - $conn.close; - } + + $listen.close; } diff -r 32db366529dd -r b96b3244307b Prepaper/code/client.p6 --- a/Prepaper/code/client.p6 Sun Feb 16 16:23:52 2020 +0900 +++ b/Prepaper/code/client.p6 Sun Feb 16 18:20:36 2020 +0900 @@ -1,5 +1,10 @@ +use IO::Socket::Unix; + my $conn = IO::Socket::INET.new( :host, :port(3333) ); -$conn.print: 'FILEPASS'; +$conn.print: 'Absolute file path'; +say $conn.lines; + +$conn.close; diff -r 32db366529dd -r b96b3244307b Prepaper/pre.pdf Binary file Prepaper/pre.pdf has changed diff -r 32db366529dd -r b96b3244307b Prepaper/pre.tex --- a/Prepaper/pre.tex Sun Feb 16 16:23:52 2020 +0900 +++ b/Prepaper/pre.tex Sun Feb 16 18:20:36 2020 +0900 @@ -37,13 +37,19 @@ \end{onecolabstract}] \thispagestyle{fancy} \section{スクリプト言語の高速実行} - -スクリプト言語RakuはMoarVMというVM上で動作するが,起動時間がPerl5やPython,Rubyなどの主要なスクリプト言語に比べて非常に低速である.この問題を解決するために,Rakuプログラムの,サーバーを用いた実行手法の提案を行う. -ここでいうサーバーとは転送したスクリプトを実行する環境のことである. +現在多くのスクリプト言語はインタプリタ型言語であり, 実行時にインタプリタの立ち上げ, モジュールを読み込み, スクリプトの解釈, スクリプトの実行 といったような処理を担っている. +これらの処理の中にはOS上で事前に行うことで, より起動時間, 及び処理時間の短縮が予想される. -またサーバーでは,サーバーに投げられたRakuをコンパイラで実行する際に,そのスクリプトが次に実行するスクリプトに影響を与えないことを保証する必要がある. -この問題を解決するために,サーバーのコンテナ化を行う. +現在開発の進んでいる言語に スクリプト言語 Raku がある. +Raku は任意の VM が選択できるようになっており, 主に利用されている VM に C で書かれた MoarVM が存在する. +MoarVM は JIT コンパイルなどをサポートしているが, 全体的な起動時間及び処理速度が Perl5 や Python , Ruby などの他のスクリプト言語と比較し非常に低速である. +%Raku は MoarVM に基づくJIT コンパイラを持っており,コンパイルされた結果はプロセッサが実行可能な機械語に相当する. +%Raku のような言語に JITコンパイラを持ち, 起動時間が遅い PyPy などの言語がある. +本研究では, スクリプト言語 Raku の起動時間及び, 処理速度の改善を図り, 研究をするにあたり得られた, OS上でscript言語を実行する場合の利点と欠点について述べ, 今後の展望について記載する. + +また, その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し,サーバー上でコンパイルを行う手法を提案する. +著者らは, この提案手法に沿って『Abyss サーバー』を実装している. \section{Raku} Rakuは元はPerl5の後継言語のPerl6として開発されていたが,現在は名称が変更されRakuとなっている. Rakuの現在の主流な実装はRakudoである.RakudoはMoarVM,とNQPと呼ばれるRakuのサブセット,NQPとRaku自身で記述されたRakuという構成である. @@ -87,7 +93,7 @@ ここではAbyssサーバーについて説明する.AbyssサーバーはRakuで書かれている. クライアント側から投げられたRakuを実行するためのサーバーである. 図1はAbyssサーバーを用いたスクリプト言語実行手順である. AbyssサーバーはユーザーがRakuを実行する際,クライアント側から転送されてきたファイルを事前に起動してあるサーバー側が処理し,その実行結果を返す構造となっている. -この手法を用いることで,サーバー上で事前にRakudoを起動したRakudoを再利用し,投げられたRakuスクリプトの実行を行うためRakudoの起動時間を短縮できると推測できる. +この手法を用いることで,サーバー上で事前に起動したRakudoを再利用し,投げられたRakuスクリプトの実行を行うためRakudoの起動時間を短縮できると推測できる. \begin{figure}[H] @@ -103,7 +109,6 @@ ファイルパスを受け取るとファイルパスをバッファーに変換し読み込む,その後読み込んだバッファーを文字列にデコードし,ファイルパスの文字列を読み込み,ファイルの中身を式として評価する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} @@ -111,11 +116,11 @@ %\section{問題点} \section{まとめ} -中間予稿までにPerl6スクリプトを投げて実行するサーバーの実装、および「自分でプロセス立ち上げてPerl6実行する手法」と「既にあるサーバーに投げてPerl6スクリプトを実行する手法」の差を測るために時間の計測を行った。 +Perl6スクリプトを投げて実行するサーバーの実装, および「自分でプロセス立ち上げてPerl6実行する手法」と「既にあるサーバーに投げてPerl6スクリプトを実行する手法」の差を測るために時間の計測を行った. + -今回実装したサーバーでは,別のスクリプトを実行する前にサーバーのコンテナ化をできていないので次回以降の課題とする. -今回の実装ではTCPソケットを用いたがTCPソケットを用いるとサーバーを立ち上げた際に外部からファイルを転送される可能性があるので,Unix domain socketの実装を行い,それを用いたクライアント・サーバーを作成することで安全性が高まると考えた -Rakuには現状Unix domainソケットの実装がないので、Unix domainソケットを実装し、自分以外が実行できないようにすることが今後の課題に挙げられる. +\section{今後の課題} + また今回例題として用いたものはスクリプト言語Rakuであったが,その他のスクリプト言語にも応用が利くかどうか検討する必要はある 今回用いたRakuのEVALFILE自体にクライアント側に出力を返す実装追加することも今後の課題に挙げられる. diff -r 32db366529dd -r b96b3244307b Slide/Slide.html --- a/Slide/Slide.html Sun Feb 16 16:23:52 2020 +0900 +++ b/Slide/Slide.html Sun Feb 16 18:20:36 2020 +0900 @@ -91,27 +91,21 @@
-

研究背景

+

スクリプト言語の高速実行

    -
  • 現在開発の進んでいる言語に Raku がある. -スクリプト言語 Raku は任意の VM が選択できるようになっており, 主に利用されている VM に C で書かれた MoarVM が存在する.
  • -
  • MoarVM は JIT コンパイルなどをサポートしているが, 全体的な起動時間及び処理速度が Perl5 や Python , Ruby などの他のスクリプト言語と比較し非常に低速である. -その為, 現在日本国内では Raku は実務としてあまり使われていない.
  • -
  • Raku の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される.
  • +
  • 現在多くのスクリプト言語はインタプリタ型言語であり, 実行時にインタプリタの立ち上げ, モジュールを読み込み, スクリプトの解釈, スクリプトの実行 といったような処理を担っている.
  • +
  • これらの処理の中にはOS上で事前に行うことで, より起動時間, 及び処理時間の短縮が予想される.
  • +
  • 頻繁にコードを書き換え実行するスクリプト言語では起動時間をできるだけ短くしたい.
  • +
  • その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案する
  • +
  • この提案手法に沿って『Abyss サーバー』を実装した.
- - -
- -
- -

研究概要

-
    -
  • Raku の実装の一つであるRakudoは、Byte code である MoarVM と、それ上で動作する Raku のsubsetであるnqp (Not Quite Perl)上に構成されている。
  • -
  • 現状のRakuの実行はRakuで記述されたコンパイラをloadしてJITしながら実行すること自体に時間がかかっている。
  • -
  • そこで, 同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案し実装する.
  • -
+ @@ -121,7 +115,7 @@

Raku と他言語の起動時間の比較

    -
  • perl6と他言語の起動時間の比較行なった.
  • +
  • Raku と他言語の起動時間の比較行なった.
  • 実行環境
@@ -180,61 +174,28 @@
  • Rakudoの構成
  • - - -
    - -
    - -

    NQP

    -
      -
    • NQPとはNot Quite Perl の略で Raku のサブセットである.
    • -
    • 基本的な文法などは Raku に準拠しているが, 変数を束縛で宣言するなどの違いがある.
    • -
    • NQPコンパイラ自身もNQPで記述されている
    • -
    • NQP は MoarVM や JVMの違いを吸収してAPIを提供している
    • -
    - - - -
    - -
    - -

    MoarVM

    -
      -
    • MoarVM は Raku に特化したVM
    • -
    • C 言語で実装されている
    • -
    • JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある
    • -
    - + -

    Perl6 の名称変更

    -
      -
    • Raku はPerlの次期メジャーバージョンとして設計が始められ, 元々Perl6という名称であったが, Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しないため別名がつけられました.
    • -
    • 現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられた.
    • -
    - - +## MoarVM +- MoarVM は Raku に特化したVM +- C 言語で実装されている +- JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある -
    +## Perl6 の名称変更 +- Raku はPerlの次期メジャーバージョンとして設計が始められ, 元々Perl6という名称であったが, Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しないため別名がつけられました. +- 現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられた. -
    - -

    Rakudoの語源

    -
      -
    • ちなみに Rakudo の語源は, 楽土と駱駝道で
    • -
    • 楽土の方はLallyが楽に言語を作りたいという意味で Rakudo
    • -
    • 駱駝道の方は Perlのマスコットキャラクターが🐪だったからです -
        -
      • http://blogs.perl.org/users/zoffix_znet/2017/07/the-hot-new-language-named-rakudo.html
      • -
      -
    • -
    +## Rakudoの語源 +- ちなみに Rakudo の語源は, 楽土と駱駝道で +- 楽土の方は日本語で「楽園」という意味で +- 駱駝道の方は Perlのマスコットキャラクターが🐪だったからです + - http://blogs.perl.org/users/zoffix_znet/2017/07/the-hot-new-language-named-rakudo.html +--> @@ -269,36 +230,18 @@

    - - -
    - -
    - -

    Raku の Unix domain socket 実装

    -
      -
    • Unix domain socket でなくINET で実装した場合, 他者からスクリプトを送りつけられる可能性がある. -
        -
      • そのため今回はUnix domain socket を用いて実装しました.
      • -
      -
    • -
    • Rakuには現在Unix domain socketの実装がないため, Unix domain socket の実装を行なった.
    • -
    • IO::Socketがroleとして定義されている -
        -
      • Raku での role は他の言語の interface に相当するものである
      • -
      -
    • -
    • 現状 Raku にはIO::Socket::INETとIO::Socket::Asyncの実装がある -
        -
      • 先ほど上で説明したようにINETとAsyncはセキュリティの問題で使えない
      • -
      -
    • -
    • IO::Socketを実装した IO::Socket::Unix を実装した -
        -
      • IO::Socket::Unixの中ではnqpの機能を使う必要がある
      • -
      -
    • -
    + @@ -383,24 +326,34 @@
  • ファイルパスを受け取ると, ファイルを開き実行する.
  • -
    unit class Abyss::Server:ver<0.0.1>;
    -use MONKEY-SEE-NO-EVAL;
    -use IO::Socket::Unix;
    +
    sub close(int32) returns int32 is native { ... }
    +sub dup(int32 $old) returns int32 is native { ... }
    +sub dup2(int32 $new, int32 $old) returns int32 is native { ... }
    +
    +method readeval 
    +{
    +    my $listen = IO::Socket::Unix.new(  :listen,
    +                                        :localhost<localhost>,
    +                                        :localport(3333) );            
    +    my $backup = dup(1);
    +    say DateTime.now;
     
    -method readeval {
    -  my $listen = IO::Socket::Unix.new( 
    -    :listen,
    -    :localhost<localhost>,
    -    :localport(3333) 
    -    );
    -  loop {
    -    my $conn = $listen.accept;
    -    while my $buf = $conn.read(1024) {
    -      EVALFILE $buf.decode;
    +    loop
    +    {
    +        my $conn = $listen.accept;
    +        my $sock_msg;
    +        my $buf = $conn.recv();
    +        $sock_msg = $buf;
    +        close(1);
    +        dup2($conn.native-descriptor(), 1);
    +        EVALFILE $sock_msg;
    +        dup2($backup, 1);
    +        close($backup);
    +        $conn.close;
         }
    -    $conn.close;
    -  }
    -}
    +
    +    $listen.close;
    +}}
     
    @@ -414,34 +367,28 @@
  • ユーザーは Abyss Server を起動後,ファイルパスをサーバーに送信する.
  • -
    use IO::Socket::Unix;
    -
    -my $conn = IO::Socket::Unix.new( :host<localhost>,
    +
    my $conn = IO::Socket::INET.new( :host<localhost>,
                                      :port(3333) );
     
    -$conn.print: 'FILEPASS';
    -
    +$conn.print: 'Absolute file path'; - - -
    +say $conn.lines; -
    - -

    Raku のEVAL

    -
      -
    • Raku では EVAL 関数があり文字列を Raku のソースコード自身として評価できる
    • -
    • Raku では, EVAL は通常は使用できないようになっており, MONKEY-SEE-NO-EVAL という pragma を実行することで使うことができるようになる.
    • -
    +$conn.close; +
    + @@ -470,7 +417,6 @@

    Abyss Serverの欠点

    • 現在 Abyss Server には 一度スクリプトを実行した後にサーバー内の環境をリセットする機能が存在しないため,スクリプトがサーバー内の環境に影響を及ぼした場合,通常実行と違う挙動をする危険性がある
    • -
    • Raku に eval の出力を socket に切り替える機能が存在しないので出力が Server 側に返ってしまい,ユーザー側に返ってこない
    • 同時に二つ以上のタスクを与えられると実行順のスケジューリングができない
      • 与えられた順番に処理していく
      • @@ -494,29 +440,6 @@
      • 今後は一度投げられたスクリプトをキャッシュで保存しておき,再度実行する際に,そのキャッシュを用いてコンパイル時間を省くような仕組みを入れて開発を進めたいです.
      - - -
    - -
    - -

    Raku の実装に関わる様々な言語

    -
      -
    • Raku は, Larry wall により設計されたオブジェクト指向スクリプト言語である.
    • -
    • また Raku は漸進的型付け言語である.
    • -
    - -

    - - - -
    - -
    - -

    Rakuの導入

    - -
    diff -r 32db366529dd -r b96b3244307b Slide/Slide.md --- a/Slide/Slide.md Sun Feb 16 16:23:52 2020 +0900 +++ b/Slide/Slide.md Sun Feb 16 18:20:36 2020 +0900 @@ -2,10 +2,13 @@ author: Kouki Fukuda, Shinji Kono profile: 琉球大学 -## 研究背景 +## スクリプト言語の高速実行 - 現在多くのスクリプト言語はインタプリタ型言語であり, 実行時にインタプリタの立ち上げ, モジュールを読み込み, スクリプトの解釈, スクリプトの実行 といったような処理を担っている. - これらの処理の中にはOS上で事前に行うことで, より起動時間, 及び処理時間の短縮が予想される. - - 頻繁にコードを書き換え実行するスクリプト言語では起動時間をできるだけ短くしたい + - 頻繁にコードを書き換え実行するスクリプト言語では起動時間をできるだけ短くしたい. + - その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案する + - この提案手法に沿って『Abyss サーバー』を実装した. + - またスクリプト言語の速度改善を行うにあたり, 本研究では Raku というスクリプト言語を用いた. + ## MoarVM - MoarVM は Raku に特化したVM - C 言語で実装されている - JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある + ## Rakuが遅い理由 - 通常 Ruby のようなスクリプト言語ではまず YARV などのプロセスVM が起動し,その後スクリプトを Byte code に変換して実行という手順を踏む. +- - Rakudo はインタプリタの起動時間及び, 全体的な処理時間が他のスクリプト言語と比較して低速である. - これは Rakudo 自体が Raku と NQP で書かれているため, MoarVMを起動し, Rakudo と NQP のByte codeを読み取り, Rakudoを起動し, その後スクリプトを読み取り, スクリプトの Byte code 変換というような手順で進むためである. - また Raku は実行時の情報が必要であり, メソッドを実行する際に invoke が走ることも遅い原因である. @@ -97,6 +113,7 @@ ![](fig/Abyss.svg) + + ## 通常実行と提案手法の速度比較 - 今回は,提案手法での実行速度と通常実行での実行速度, この二つの速度の比較を行う @@ -144,12 +163,6 @@ - ファイルパスを受け取ると, ファイルを開き実行する. ``` -use v6.c; -unit class Abyss::Server:ver<0.0.1>:auth; -use MONKEY-SEE-NO-EVAL; -use IO::Socket::Unix; -use NativeCall; - sub close(int32) returns int32 is native { ... } sub dup(int32 $old) returns int32 is native { ... } sub dup2(int32 $new, int32 $old) returns int32 is native { ... } @@ -185,22 +198,24 @@ ``` use IO::Socket::Unix; -use NativeCall; - -sub close(int32) returns int32 is native { ... } -sub dup(int32 $old) returns int32 is native { ... } -sub dup2(int32 $old, int32 $new) returns int32 is native { ... } my $conn = IO::Socket::INET.new( :host, :port(3333) ); $conn.print: 'Absolute file path'; -say $conn.lines; +my $sock_msg; -$conn.close; +while my $buf = $conn.recv(:bin) +{ + $sock_msg = $buf.decode; + last; +} + +say $sock_msg; ``` + ## Abyss Serverの利点 - Abyss Serverを用いて実行することで, サーバー上で事前に起動した Rakudo を再利用し, 投げられた Raku スクリプトの実行を行うため, Rakudo の起動時間を短縮できる. @@ -227,18 +243,11 @@ - 異常に長いタスクが投げられた場合, 次のタスクが前のタスクが終わるまで実行ができない - 起動時のオプションが選択出来ない +## OS上でスクリプト言語を実行する方法の改善点 +- + ## まとめと今後の課題 - Raku の新たな実行方法の提案,及び実装を行なった. - Raku にUnix domain socket の実装を行なった. - Raku の速度改善において, 同一ホスト内でサーバープロセスを生成し,サーバープロセス内であらかじめコンパイラを立ち上げて起き, 実行するファイル名を転送し,サーバープロセス上でコンパイルを行う手法は有効であると考えられる - 今後は一度投げられたスクリプトをキャッシュで保存しておき,再度実行する際に,そのキャッシュを用いてコンパイル時間を省くような仕組みを入れて開発を進めたいです. - - -## Raku の実装に関わる様々な言語 -- Raku は, Larry wall により設計されたオブジェクト指向スクリプト言語である. -- また Raku は漸進的型付け言語である. - -![](fig/Raku.svg) - -## Rakuの導入 - diff -r 32db366529dd -r b96b3244307b Slide/Slide.pdf.html --- a/Slide/Slide.pdf.html Sun Feb 16 16:23:52 2020 +0900 +++ b/Slide/Slide.pdf.html Sun Feb 16 18:20:36 2020 +0900 @@ -75,27 +75,21 @@
    -

    研究背景

    +

    スクリプト言語の高速実行

      -
    • 現在開発の進んでいる言語に Raku がある. -スクリプト言語 Raku は任意の VM が選択できるようになっており, 主に利用されている VM に C で書かれた MoarVM が存在する.
    • -
    • MoarVM は JIT コンパイルなどをサポートしているが, 全体的な起動時間及び処理速度が Perl5 や Python , Ruby などの他のスクリプト言語と比較し非常に低速である. -その為, 現在日本国内では Raku は実務としてあまり使われていない.
    • -
    • Raku の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される.
    • +
    • 現在多くのスクリプト言語はインタプリタ型言語であり, 実行時にインタプリタの立ち上げ, モジュールを読み込み, スクリプトの解釈, スクリプトの実行 といったような処理を担っている.
    • +
    • これらの処理の中にはOS上で事前に行うことで, より起動時間, 及び処理時間の短縮が予想される.
    • +
    • 頻繁にコードを書き換え実行するスクリプト言語では起動時間をできるだけ短くしたい.
    • +
    • その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案する
    • +
    • この提案手法に沿って『Abyss サーバー』を実装した.
    - - -
    - -
    - -

    研究概要

    -
      -
    • Raku の実装の一つであるRakudoは、Byte code である MoarVM と、それ上で動作する Raku のsubsetであるnqp (Not Quite Perl)上に構成されている。
    • -
    • 現状のRakuの実行はRakuで記述されたコンパイラをloadしてJITしながら実行すること自体に時間がかかっている。
    • -
    • そこで, 同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案し実装する.
    • -
    + @@ -105,7 +99,7 @@

    Raku と他言語の起動時間の比較

      -
    • perl6と他言語の起動時間の比較行なった.
    • +
    • Raku と他言語の起動時間の比較行なった.
    • 実行環境
    @@ -164,61 +158,28 @@
  • Rakudoの構成
  • - - -
    - -
    - -

    NQP

    -
      -
    • NQPとはNot Quite Perl の略で Raku のサブセットである.
    • -
    • 基本的な文法などは Raku に準拠しているが, 変数を束縛で宣言するなどの違いがある.
    • -
    • NQPコンパイラ自身もNQPで記述されている
    • -
    • NQP は MoarVM や JVMの違いを吸収してAPIを提供している
    • -
    - - - -
    - -
    - -

    MoarVM

    -
      -
    • MoarVM は Raku に特化したVM
    • -
    • C 言語で実装されている
    • -
    • JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある
    • -
    - + -

    Perl6 の名称変更

    -
      -
    • Raku はPerlの次期メジャーバージョンとして設計が始められ, 元々Perl6という名称であったが, Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しないため別名がつけられました.
    • -
    • 現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられた.
    • -
    - - +## MoarVM +- MoarVM は Raku に特化したVM +- C 言語で実装されている +- JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある -
    +## Perl6 の名称変更 +- Raku はPerlの次期メジャーバージョンとして設計が始められ, 元々Perl6という名称であったが, Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しないため別名がつけられました. +- 現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられた. -
    - -

    Rakudoの語源

    -
      -
    • ちなみに Rakudo の語源は, 楽土と駱駝道で
    • -
    • 楽土の方はLallyが楽に言語を作りたいという意味で Rakudo
    • -
    • 駱駝道の方は Perlのマスコットキャラクターが🐪だったからです -
        -
      • http://blogs.perl.org/users/zoffix_znet/2017/07/the-hot-new-language-named-rakudo.html
      • -
      -
    • -
    +## Rakudoの語源 +- ちなみに Rakudo の語源は, 楽土と駱駝道で +- 楽土の方は日本語で「楽園」という意味で +- 駱駝道の方は Perlのマスコットキャラクターが🐪だったからです + - http://blogs.perl.org/users/zoffix_znet/2017/07/the-hot-new-language-named-rakudo.html +--> @@ -253,36 +214,18 @@

    - - -
    - -
    - -

    Raku の Unix domain socket 実装

    -
      -
    • Unix domain socket でなくINET で実装した場合, 他者からスクリプトを送りつけられる可能性がある. -
        -
      • そのため今回はUnix domain socket を用いて実装しました.
      • -
      -
    • -
    • Rakuには現在Unix domain socketの実装がないため, Unix domain socket の実装を行なった.
    • -
    • IO::Socketがroleとして定義されている -
        -
      • Raku での role は他の言語の interface に相当するものである
      • -
      -
    • -
    • 現状 Raku にはIO::Socket::INETとIO::Socket::Asyncの実装がある -
        -
      • 先ほど上で説明したようにINETとAsyncはセキュリティの問題で使えない
      • -
      -
    • -
    • IO::Socketを実装した IO::Socket::Unix を実装した -
        -
      • IO::Socket::Unixの中ではnqpの機能を使う必要がある
      • -
      -
    • -
    + @@ -367,24 +310,34 @@
  • ファイルパスを受け取ると, ファイルを開き実行する.
  • -
    unit class Abyss::Server:ver<0.0.1>;
    -use MONKEY-SEE-NO-EVAL;
    -use IO::Socket::Unix;
    +
    sub close(int32) returns int32 is native { ... }
    +sub dup(int32 $old) returns int32 is native { ... }
    +sub dup2(int32 $new, int32 $old) returns int32 is native { ... }
    +
    +method readeval 
    +{
    +    my $listen = IO::Socket::Unix.new(  :listen,
    +                                        :localhost<localhost>,
    +                                        :localport(3333) );            
    +    my $backup = dup(1);
    +    say DateTime.now;
     
    -method readeval {
    -  my $listen = IO::Socket::Unix.new( 
    -    :listen,
    -    :localhost<localhost>,
    -    :localport(3333) 
    -    );
    -  loop {
    -    my $conn = $listen.accept;
    -    while my $buf = $conn.read(1024) {
    -      EVALFILE $buf.decode;
    +    loop
    +    {
    +        my $conn = $listen.accept;
    +        my $sock_msg;
    +        my $buf = $conn.recv();
    +        $sock_msg = $buf;
    +        close(1);
    +        dup2($conn.native-descriptor(), 1);
    +        EVALFILE $sock_msg;
    +        dup2($backup, 1);
    +        close($backup);
    +        $conn.close;
         }
    -    $conn.close;
    -  }
    -}
    +
    +    $listen.close;
    +}}
     
    @@ -398,34 +351,28 @@
  • ユーザーは Abyss Server を起動後,ファイルパスをサーバーに送信する.
  • -
    use IO::Socket::Unix;
    -
    -my $conn = IO::Socket::Unix.new( :host<localhost>,
    +
    my $conn = IO::Socket::INET.new( :host<localhost>,
                                      :port(3333) );
     
    -$conn.print: 'FILEPASS';
    -
    +$conn.print: 'Absolute file path'; - - -
    +say $conn.lines; -
    - -

    Raku のEVAL

    -
      -
    • Raku では EVAL 関数があり文字列を Raku のソースコード自身として評価できる
    • -
    • Raku では, EVAL は通常は使用できないようになっており, MONKEY-SEE-NO-EVAL という pragma を実行することで使うことができるようになる.
    • -
    +$conn.close; +
    + @@ -454,7 +401,6 @@

    Abyss Serverの欠点

    • 現在 Abyss Server には 一度スクリプトを実行した後にサーバー内の環境をリセットする機能が存在しないため,スクリプトがサーバー内の環境に影響を及ぼした場合,通常実行と違う挙動をする危険性がある
    • -
    • Raku に eval の出力を socket に切り替える機能が存在しないので出力が Server 側に返ってしまい,ユーザー側に返ってこない
    • 同時に二つ以上のタスクを与えられると実行順のスケジューリングができない
      • 与えられた順番に処理していく
      • @@ -478,29 +424,6 @@
      • 今後は一度投げられたスクリプトをキャッシュで保存しておき,再度実行する際に,そのキャッシュを用いてコンパイル時間を省くような仕組みを入れて開発を進めたいです.
      - - -
    - -
    - -

    Raku の実装に関わる様々な言語

    -
      -
    • Raku は, Larry wall により設計されたオブジェクト指向スクリプト言語である.
    • -
    • また Raku は漸進的型付け言語である.
    • -
    - -

    - - - -
    - -
    - -

    Rakuの導入

    - -