1 / 61

Ruby プログラムを高速に 実行するための処理系の開発

Ruby プログラムを高速に 実行するための処理系の開発. 日本 Ruby の会 (東京農工大学 大学院) ささだ こういち. 2005 2/19 IPA 未踏ユース 成果報告会. 発表概要. 背景 目標 Ruby の特徴 設計と実装 最適化手法 現時点での性能評価 まとめ. Smithsonian National Museum of Natural History. 背景. オブジェクト指向スクリプト言語 Ruby http://www.ruby-lang.org 使いやすいと評判 世界中で広く利用

warrick
Download Presentation

Ruby プログラムを高速に 実行するための処理系の開発

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Rubyプログラムを高速に実行するための処理系の開発Rubyプログラムを高速に実行するための処理系の開発 日本Rubyの会 (東京農工大学 大学院) ささだ こういち 2005 2/19 IPA 未踏ユース 成果報告会

  2. 発表概要 • 背景 • 目標 • Ruby の特徴 • 設計と実装 • 最適化手法 • 現時点での性能評価 • まとめ Smithsonian National Museum of Natural History

  3. 背景 • オブジェクト指向スクリプト言語Ruby • http://www.ruby-lang.org • 使いやすいと評判 • 世界中で広く利用 • Ruby-talk ML では一日に百通以上 • 最近 Ruby on Rails が人気 • 日本発(主開発者:まつもとゆきひろ(Matz)氏) • 日本発で世界に通用する数少ないソフトウェア • コミュニティ活動も活発 • 日本Rubyの会 • Rubyist Magazine

  4. 背景: Rubyist Magazine 0005 (Feb. 2005) http://jp.rubyist.net/magazine/

  5. 背景: 現状の問題点 • 既存のRuby処理系は遅い • たしかに遅いところも • 誤った常識の流布 「Rubyって遅いんでしょ? 使えないよ」 • あなたが思うほど遅くありません • 高速化の必要性 • Ruby の処理系は魔法(by Matz) • 魔法みたいな処理系のソースコード • ソースコード整理の必要性

  6. 背景: 今までの試み • 他の言語はどうしているの? • バイトコード(仮想マシン型)処理系が適当 • Lisp, Java, .NET, Smalltalk 処理系など • いくつかのRubyバイトコード処理系→不十分 • まつもと氏 平成12年度未踏ソフトウェア創造事業 • 不完全(命令が不十分・コンパイラも無い) • ByteCodeRuby (George Marrows氏) • 現状のRuby処理系よりも遅い→ プロジェクト終了 • その他、作りかけばかり(新しいプロジェクトは増える)

  7. 提案:Rubyプログラムを高速に実行するための処理系の開発提案:Rubyプログラムを高速に実行するための処理系の開発 • VM命令セットの設計 • コンパイラの設計・開発 • 仮想機械(RubyVM)の設計・開発 • JIT (Just In Time), AOT (Ahead of Time) コンパイラ YARV: Yet Another Ruby VM として開発中(オープンソースソフトウェア)

  8. 目標設定 • 世界一速いRuby処理系 • 基本性能で2倍、JITコンパイラでは5倍 AOTコンパイラでは10倍の性能向上を目指す • 世界中の人に使ってもらえるように • RubyVM としての十分な機能を実装 • いずれは次期Rubyの公式実装 Rite に • Ruby2.0 処理系 Rite(現在 1.9.0 開発中) • 本プロジェクトが成功すれば YARV を Rite として採用

  9. Rubyの特徴 • インタプリタ • クラスベースのオブジェクト指向 • ダイナミック • すべてがオブジェクト・実行時に再定義可能 • Evil Eval • プログラミングは楽に、冗長に • 例外処理など大域ジャンプ可能 • スレッドのサポート • Cによる拡張ライブラリ開発が容易 どれだけ無駄を 省けるかが勝負

  10. YARV 概要 • 単純なスタックマシン • 拡張ライブラリとして実装 • 既存のRuby と連携して機能を利用 • 今回新しく作り直さない • ガーベージコレクタ • Ruby Script パーサ • Ruby C API が使える • 大部分,C言語で実装

  11. デモ

  12. YARVの全体像 Ruby Interpreter 拡張ライブラリとして利用 YARV Ruby API を利用 コンパイラ 作る VM 生成系 VM AOT コンパイラ JIT コンパイラ

  13. YARVの動作の流れ Ruby プログラム コンパイラ AOT コンパイラ YARV 命令列 C プログラム JIT コンパイラ C コンパイラ 機械語 拡張ライブラリ VM(実行)

  14. 今までなぜ遅かったのか? Ruby プログラム 抽象構文木 a = a = a = a = b + c メソッド 呼び出し(+) メソッド 呼び出し(+) メソッド 呼び出し(+) 現在の Ruby は 構文木を直接実行 b c b b c c

  15. YARV はなぜ速いのか? a b+c Ruby プログラム a = b + c b c YARV 命令列 c b b+c getlocal b getlocal c send + setlocal a YARV スタックマシン

  16. YARV命令セット • Ruby プログラムを表現できる命令セットを定義 • スタック制御、フロー制御、メソッド定義、・・・ # Ruby program print(“Hello”) # YARV 命令列 putself putstring “Hello” send :print, 1 コンパイル

  17. 命令記述フォーマット • 命令記述フォーマットを定義 • 各命令をこのフォーマットで記述 • 具体的な記述部分は C • いくつか変数を宣言 • VM 実装が非常に楽に • いろいろと自動生成

  18. 命令記述によるVM生成 • 命令記述から生成されるもののまとめ 命令記述 約2000 行 約60命令分 AOT コンパイラ C プログラム 逆アセンブラ ドキュメント VM (22000行・約400命令) これから実装 アセンブラ コンパイラ (主に最適化器) ベリファイア

  19. VM概要 • 5 つのレジスタ • PC: プログラムカウンタ • SP: スタックポインタ • LFP: ローカルフレームポインタ • DFP: ダイナミックフレームポインタ • CFP: コントロールフレームポインタ • 3つのスタックフレーム • メソッド・クラス・ブロックスコープを管理

  20. VM概要 –例外処理 • 例外処理用テーブルを利用 従来の処理系(before) YARV (after) begin … rescue … end ここで毎回 setjmp begin … rescue … end なにもしない 例外が起きたら スタック巻き戻し &例外テーブルチェック 例外が起きたら そこで longjmp

  21. YARV での最適化(高速化) 一般論 • 冗長性の除去 • 一度やったことは二度しない(キャッシュなど) • 計算強度の軽減 • もっと簡単にやろう • トレードオフ • 頻繁に実行するものを速く • その代わりあんまり実行しないものを遅く • マシン(その他)に依存の最適化 • マシンレジスタの利用,分岐予測の考慮,コンパイラの最適化の予測(確認)

  22. YARVでの最適化 • インラインキャッシュ • 命令オペランドにデータを埋め込み,キャッシュ • 定数アクセス • 定数 A へのアクセスは遅い • A::B::C は4命令必要(定数アクセスが3回も) • 各定数アクセスも結構遅い • メソッド検索 • 現在のRuby処理系は1つのハッシュでキャッシュ

  23. 定数アクセスの最適化 Ruby プログラム A::B::C getinlinecache putnil getconstant A getconstant B getconstant C setinlinecache コンパイル 最適化 putnil getconstant A getconstant B getconstant C 2回目以降の実行をスキップ

  24. YARVでの最適化(cont.) • スタックキャッシング • スタックトップの2つをキャッシュ • 5状態 • 命令数は5倍(各状態ごとに命令を用意) • putself_xx_ax • putself_ax_ab • putself_bx_ba • putself_ab_ba • putself_ba_ab

  25. YARV 命令列 getlocal v2 getlocal v3 send + setlocal v1 スタックキャッシングはなぜ早いのか v1 b+c Reg A Ruby プログラム b+c v2 regA v1 = v2 + v3 v2 Reg B YARV命令列(SC) regB v3 v3 getlocal_xx_ax v2 getlocal_xx_ab v3 send_ab_ax + setlocal_ax_xx v1 スタック操作無し! YARV スタックマシン

  26. YARVでの最適化(cont.) • 命令融合 • 頻出する連続した命令列を1命令に • putobject putobject → putobject_x2 • オペランド融合 • putobject true → puttrue • 融合するものを指定すれば,自動的に生成 • 命令記述を解析すれば可能 • コンパイラ(変換器)も自動生成 • プロファイラ

  27. YARVでの最適化(cont.) • 特化命令 • 単純な命令を特殊化 • a + b → opt_plus if(a と b は整数か?) if(整数の + メソッドは再定義されていないか?) return a+b; 通常のメソッド呼び出し a.+(b) を実行

  28. 最適化を含むコンパイラの仕事まとめ Ruby スクリプト Ruby パーサ 構文木 YARV 命令列 基本コンパイラ 特化命令最適化 スタックキャッシュ命令 に変換 オペランド融合最適化 命令融合最適化 その他最適化 YARV コンパイラ

  29. JIT コンパイラ • 実行時に YARV 命令列を機械語に変換 • コードを切り貼り(機械語を直に触りたくない) • Intel i386で、いくつかの命令だけ対応 VM評価関数 の実体 (機械語) YARV 命令列 A B C JIT コンパイル 機械語コード A を処理するところ A を処理するところ コピー B を処理するところ B を処理するところ C を処理するところ C を処理するところ

  30. JIT コンパイラ (cont.) • コピーするとき、相対ジャンプしている命令は書き換えなければならない • VM 評価関数を同じものを2つ作り、機械語(オペランド)レベルで違いがあれば書き換え VM評価関数 の実体 1 VM評価関数 の実体 2 比較 A を処理するところ A を処理するところ

  31. AOT コンパイラ • Ruby プログラムを C プログラムに変換 • 命令記述を変換して貼りつけ(テキスト処理) • ほぼすべての命令に対応 YARV 命令列 A B C 命令記述 AOT コンパイル C プログラム A を処理する記述 A を処理する記述 コピー B を処理する記述 B を処理する記述 C を処理する記述 C を処理する記述

  32. ベンチマーク結果 • 評価環境 • (1) CPU: Intel Celeron 1.7GHz, Mem: 512MB OS: Windows2000 + Cygwin 1.52 • (2) CPU: AMD 64 2.4GHz, Mem: 1024MB OS: Linux amd64 2.6.5-1.358 (Fedora Core 2) • コンパイラ: gcc (GCC) 3.3.3 • コンパイラオプション:-O2 -f-no-crossjumping • 比較対象の ruby 1.9.0 (2005-02-17)

  33. ベンチマーク結果(cont.)

  34. ベンチマーク結果(cont.)

  35. ベンチマーク結果(cont.) AOT コンパイラの効果 メソッド呼び出しが本質的に遅い (バックトレース用情報などが必要になるため) 高速化手法を検討中

  36. ベンチマーク結果(cont.) JIT コンパイラ def m 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 end jitcompile(self, :m) i=0 while i<1000000 i+=1 m end normal YARV: 0.454000 0.000000 0.454000 ( 0.443000) JITed YARV: 0.375000 0.000000 0.375000 ( 0.398000) #=> 21% 高速化

  37. 成果物一覧 • YARV ソースコード • C ソースコード:17 ファイル 約 7500行 • Ruby ソースコード:5 ファイル 約 1200行 • 機能一覧 • ○:変数/制御構造・クラス/メソッド定義・メソッド呼び出し • ○:多くの組み込み関数・組み込みクラス • ○:高速化のためのさまざまな最適化 • △:yield(ブロック呼び出し/2.0仕様)/ defined? • ×:内部構造に関わる組み込み関数(Thread や send)

  38. 品質管理 • Ruby の各構文要素毎にユニットテストを作成 • 10 ファイル • テスト数:103、アサーション数:282 • ベンチマークプログラムの動作を確認 • ベンチマークプログラム数:53 • 速くなるのを見てニヤニヤする

  39. 対外発表など(YARV の宣伝) • 8月 LL weekend • 8月 まつもとさん訪問 • 10月 Ruby Conference 2004(バージニア) • 10月 関西オープンソース 2004 • 1月 プログラミングシンポジウム • 2月 RHG 読書会 • これから:3月 情報処理学会 全国大会 • これから:3月 オープンソースカンファレンス • これから:Rubyist Magazine vol. 6 (5月)~

  40. 開発スケジュール(過去) 7月 8月 9月 10月 11月 12月 1月 2月 見落とし発見 積み残し 命令設計 VM 設計 VM 設計 実装 VM 設計 実装 VM 実装 VM 基本部分最適化 AOT コンパイラ JIT コンパイラ 本業(研究会原稿)

  41. YARV 開発について(現在) • 0.1.1 released • ホームページ • http://www.atdot.net/yarv/ • インストール方法などもここに • メーリングリスト • Yarv-dev (日本語) • Yarv-devel (英語)

  42. 開発スケジュール(未来) • はやいうちに(来年度目標) • 現在の処理系と YARV の統合 • きちんとした JIT・AOT コンパイラ • Ruby 以外の言語 on YARV → YARV 可能性検証 • ほかいろいろ(アセンブラ、プリコンパイル、…) • できるだけはやいうちに • Ruby 2.0 (Rite) リリース • 夢 • YARV OS(with OSKit) • 組み込み機器向け YARV

  43. Ruby Interpreter 拡張ライブラリとして利用 評価器 YARV コンパイラ Ruby API を利用 VM JIT コンパイラ 現在の処理系と YARV の統合

  44. Ruby Interpreter - Ruby 2.0 (Rite) コンパイルされた 標準ライブラリ YARV 世代別 GC コンパイラ 多言語化 Selective Namespace VM … JIT コンパイラ 現在の処理系と YARV の統合

  45. 開発成果のまとめ 各種最適化により順調に高速化 10倍の性能も • 世界一速いRuby処理系 • 基本性能で2倍、JITコンパイラでは5倍 AOTコンパイラでは10倍の性能向上を目指す • 世界中の人に使ってもらえるように • RubyVM としての十分な機能を実装 現在はあまり速くなってない&あまり対応できてない プリミティブはほぼ実装 大規模なプログラムはまだ デバッグデバッグ

  46. 反省点 • よかった点 ~ よくできました • いろいろと宣伝した • 考えていた最適化をいちおう全部試せた→知見を得た • 予想以上に高速化ができた→予想どおりに Ruby が遅かった • 悪かった点 ~ もうすこし頑張りましょう • 大規模アプリケーションの目標をきちんとたてなかった • ロードマップを明確化するべきだった • Ruby 2.0 の仕様にしたが、それだと動かないプログラムばっかり(現在の仕様に準拠すべきだった)

  47. おわり / ご清聴ありがとうございました • Special Thanks • IPA • Yarv-dev / Yarv-devel ML 参加者の皆様 • NaCl まつもとゆきひろさん • 筑波大 前田敦司助教授 • 産総研 首藤一幸さん • And others • RHG 読書会参加者の皆様 • Ruby Hackers

More Related