Mercurial > hg > Papers > 2019 > koo-prosym
view Slide/Slide.md @ 14:3f4ba3dacff5 default tip
比較時間等の修正
author | e165727 <e165727@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 11 Jan 2020 00:07:09 +0900 |
parents | 4e34198dcd05 |
children |
line wrap: on
line source
title: Perl6(Raku)のサーバーを使った高速実行 author: Kouki Fukuda, Shinji Kono profile: 琉球大学 ## 研究背景 - 現在開発の進んでいる言語に Raku がある. スクリプト言語 Raku は任意の VM が選択できるようになっており, 主に利用されている VM に C で書かれた MoarVM が存在する. - MoarVM は JIT コンパイルなどをサポートしているが, 全体的な起動時間及び処理速度が Perl5 や Python , Ruby などの他のスクリプト言語と比較し非常に低速である. その為, 現在日本国内では Raku は実務としてあまり使われていない. - Raku の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される. ## 研究概要 - Raku の実装の一つであるRakudoは、Byte code である MoarVM と、それ上で動作する Raku のsubsetであるnqp (Not Quite Perl)上に構成されている。 - 現状のRakuの実行はRakuで記述されたコンパイラをloadしてJITしながら実行すること自体に時間がかかっている。 - そこで, 同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案し実装する. ## Raku と他言語の起動時間の比較 - perl6と他言語の起動時間の比較行なった. - 実行環境 ``` macOS Mojave version 10.14.5 メモリ8GB プロセッサ2.7GHz Intel Core i5 ``` ``` ruby 2.3.7p456 python 2.7.10 raku 2019.03.1 perl5 v5.18.4 ``` ## Raku と他言語の起動時間の比較 - perl5,ruby,raku,pythonでhelloworldを出力するプログラムを用いて行なった実行結果である. ``` perl5 user 0m0.004s sys 0m0.005s ===== Raku user 0m0.249s sys 0m0.048s ==== ruby user 0m0.083s sys 0m0.038s ==== python user 0m0.013s sys 0m0.021s ==== ``` Raku は 最も早いperl5 の約62.25倍起動速度が遅いことがわかる. ## Rakudo - Rakudoとは現在のRakuの主力な実装である.(Raku は言語名, Rakudo はコンパイラ) - Rakudo は MoarVM, と NQP と呼ばれる Raku のサブセット, NQP と Raku 自身で記述された Raku という構成である. ![](fig/Rakudo.svg) - Rakudoの構成 ## NQP - NQPとはNot Quite Perl の略で Raku の機能を制限したプログラミング言語である. - 基本的な文法などは Raku に準拠しているが, 変数を束縛で宣言するなどの違いがある. - NQPコンパイラ自身もNQPで記述されている ## 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 ## Rakuが遅い理由 - 通常 Ruby のようなスクリプト言語ではまず YARV などのプロセスVM が起動し,その後スクリプトを Byte code に変換して実行という手順を踏む. - Rakudo はインタプリタの起動時間及び, 全体的な処理時間が他のスクリプト言語と比較して低速である. - これは Rakudo 自体が Raku と NQP で書かれているため, MoarVMを起動し, Rakudo と NQP のByte codeを読み取り, Rakudoを起動し, その後スクリプトを読み取り, スクリプトの Byte code 変換というような手順で進むためである. - また Raku は実行時の情報が必要であり, メソッドを実行する際に invoke が走ることも遅い原因である. - invoke はMoarVM の method 呼び出しのbyte codeです. ## Raku による Abyss Server の実装 - 提案手法に沿い『Abyss Server』を実装した. - Abyss Server はUnix domain socketを用いて送信した Raku スクリプトを実行するための Server である. - 下記の図は, Abyss Server を用いたスクリプト言語の実行手順です. ![](fig/Abyss.svg) ## Raku の Unix domain socket 実装 - Unix domain socket でなくINET で実装した場合, 他者からスクリプトを送りつけられる可能性がある. - そのため今回はUnix domain socket を用いて実装しました. - Rakuには現在Unix domain socketの実装がないため, Unix domain socket の実装を行なった. - IO::Socketがroleとして定義されている - 現状 Raku にはIO::Socket::INETとIO::Socket::Asyncの実装がある - IO::Socketを実装した IO::Socket::Unix を実装しました - IO::Socket::Unixの中ではnqpの機能を使う必要がある ## 通常実行と提案手法の速度比較 - 今回は,提案手法での実行速度と通常実行での実行速度, この二つの速度の比較を行う - 題材として行うのはhelloworldを出力するだけのプログラムです. %時間があればフィボナッチの例題も ## 予測 - 前述した通り, Raku はコンパイラの起動に時間がかかっているため, 提案手法を用いることで起動時間分早く実行することができると予測する. ## 1回だけ呼び出した場合 - 通常実行 - 0.2695 sec - 0.2131 sec - 0.3143 sec - 提案手法 - 0.0238 sec - 0.0219 sec - 0.0275 sec - 提案手法は通常実行に比べて約10倍早い実行結果になった ## 10回呼び出した場合 - 通常実行 - 2.187491 sec - 2.242387 sec - 2.198792 sec - 提案手法 - 0.2552448 sec - 0.2340882 sec - 0.2795233 sec - 提案手法は通常実行に比べて約10倍早い実行結果になった ## Abyss Server側の実装 - Abyss Server は起動すると, まず自身にファイルパスを転送するためのソケットを生成し, その後ファイルを受け取るための待機ループに入る. - ファイルパスを受け取ると, ファイルを開き実行する. ``` unit class Abyss::Server:ver<0.0.1>; use MONKEY-SEE-NO-EVAL; use IO::Socket::Unix; 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; } $conn.close; } } ``` ## Abyss Client側の実装 - ユーザーは Abyss Server を起動後,ファイルパスをサーバーに送信する. ``` use IO::Socket::Unix; my $conn = IO::Socket::Unix.new( :host<localhost>, :port(3333) ); $conn.print: 'FILEPASS'; ``` ## Raku のEVAL - Raku では EVAL 関数があり文字列を Raku のソースコード自身として評価できる - Raku では, EVAL は通常は使用できないようになっており, MONKEY-SEE-NO-EVAL という pragma を実行することで使うことができるようになる. ``` use MONKEY-SEE-NO-EVAL; EVAL "say { 5 + 5 }"; # OUTPUT: 10 ``` ## Abyss Serverの利点 - Abyss Serverを用いて実行することで, サーバー上で事前に起動した Rakudo を再利用し, 投げられた Raku スクリプトの実行を行うため, Rakudo の起動時間を短縮できる. - 約10分の1 ## Abyss Serverの欠点 - 現在 Abyss Server には 一度スクリプトを実行した後にサーバー内の環境をリセットする機能が存在しないため,スクリプトがサーバー内の環境に影響を及ぼした場合,通常実行と違う挙動をする危険性がある - Raku に eval の出力を socket に切り替える機能が存在しないので出力が Server 側に返ってしまい,ユーザー側に返ってこない - 同時に二つ以上のタスクを与えられると実行順のスケジューリングができない - 与えられた順番に処理していく - 異常に長いタスクが投げられた場合, 次のタスクが前のタスクが終わるまで実行ができない - 起動時のオプションが選択出来ない ## まとめと今後の課題 - Raku の新たな実行方法の提案,及び実装を行なった. - Raku にUnix domain socket の実装を行なった. - Raku の速度改善において, 同一ホスト内でサーバープロセスを生成し,サーバープロセス内であらかじめコンパイラを立ち上げて起き, 実行するファイル名を転送し,サーバープロセス上でコンパイルを行う手法は有効であると考えられる - 今後は一度投げられたスクリプトをキャッシュで保存しておき,再度実行する際に,そのキャッシュを用いてコンパイル時間を省くような仕組みを入れて開発を進めたいです. ## Raku の実装に関わる様々な言語 - Raku は, Larry wall により設計されたオブジェクト指向スクリプト言語である. - また Raku は漸進的型付け言語である. ![](fig/Raku.svg) ## Rakuの導入