10/22 に三鷹駅近くのモダンタイムスさんで行われた Mitaka.rb #5 に、三鷹クラスタの一員として のこのこ行ってきた。
主催の @ysakaki さん他関係各位ありがとうございました&お疲れ様でした。
「Mitaka.rb ってどんなん?」という人には、→ @ysakaki さんのお料理写真いっぱいいっぱいの記事 をどぞ。食べ物は雄弁。
Mitaka.rb 参加は2回目。
前回 ( Mitaka.rb #3 pgcafe Nite! ) よりも三鷹率があがってる? 自宅から半径 100mなご近所さん話題とか、三鷹〜調布間のローカルネタでずいぶんもりあがることができた。
また .rb なだけあって、Windows 7 を褒め称えたり、Boost をケナしたり、Delphi を熱く語ったり、と Ruby な話題にも事欠かなかった。
歓談&おいしい食事のあとのLTコーナーで「明日使える超高速 Ruby 〜 Ruby で Xbyak 〜」という話をさせてもらって、三鷹方面に "Xbyak" が読める人を20人ほど増やしてきた。
ちなみに前回は「Javascript で Ruby の作り方」。
なにがどう「明日使える」のかは資料を見てもらうとして、ネタである "RXbyak" について簡単に紹介。
RXbyak は、ネイティブコードを生成する C++ ライブラリである Xbyak (光成さん作) を Ruby から使えるようにした Ruby 拡張である。
つまり、どこからどうみても Ruby にしか見えないこのコードが、動く。
require 'RXbyak' rx = RXbyak.new rx.mov :eax, [:esp, 8] # mov eax, (esp+8) // 第1引数のポインタ rx.movq :xmm0, [:eax] # movq xmm0, (eax) rx.mov :eax, [:esp, 12] # mov eax, (esp+12) // 第2引数のポインタ rx.movq :xmm1, [:eax] # movq xmm1, (eax) rx.mulsd :xmm0, :xmm1 # mulsd xmm0, xmm1 // かけ算 rx.mov :eax, [:esp, 4] # mov eax, (esp+4) // 返値のポインタ rx.movq [:eax], :xmm0 # movq (eax), xmm0 rx.ret # ret puts rx.call(256.0, 256.0) # => 65536.0 puts rx.call(123.45, 678.9) # => 83810.205
……とまあ、(例によって)ちょっとお馬鹿なことを全力でやるニコニコ系LTだったわけだが、この「どこからどうみても Ruby にしか見えない」キモかわいいコードを見ているうちに、なんかこれはこれでアリかな、という気になってくるw
Ruby が遅いのは承知の上で、それでも Ruby を使うのは、その人にとっては開発が短時間で済むとか、Ruby の記述の柔軟性とか、そういうポイントがあるわけだ。
だから、C/C++ で書けば速くなることはわかっていても(そしてそのスキルがあったとしても)、はいそうしましょう、というわけにはなかなかいかない。
それに本当に速くしたい部分はごくごく一部、他は Ruby のままでかまわない、ということも往々にしてある。
RXbyak はそんな「Ruby のままで速くなる方法」の一つになれる、かも?
他にも RubyInline という Ruby コードの中に C を書ける拡張があるが(知らなかったw。会場で id:akasata さんに教えてもらった)、JIT(動的生成) & アセンブラ(SIMD うはうは)というあたりは RXbyak の魅力かな。
あと、コンパイラ揃えるのが面倒でまだ試してないけど、RXbyak は Windows でも動く(はず)。
それから、この手の言語生成技術はただでさえややこしい&見通しが悪くなりやすいので、できるだけ短く書ける、やわらかいコードで行う方がいい気がする。って、それなんて Ruby?
とまあ、そんな妄想を抱こうにも、いまはまだ実装率が低すぎて上のサンプルくらいしか動かないwww
Ruby 拡張は初挑戦なのに、C++ ライブラリである Xbyak を組み込もうというのは少々無謀(Ruby 拡張は C で書くのが原則)。
しかも思いついて実装を始めたのが日曜日から、なぁんてタイトなスケジュールでは、サンプルが動いた後は資料を作るのがやっと。
そのうち、ニューラルネットワーク実装を RXbyak で動かすあたりまでは最低限作り込むつもりだけど、まずは明日の PRML 読書会の予習だ〜。
(蛇足) ネタがわからない人向けの解説。
- RXbyak は、アセンブラを動的に生成するコードが Ruby で書けるようになる拡張。上のサンプルコードは Ruby DSL で x86 アセンブラを書いている。
- JIT とは、元となるプログラムなどから動的にネイティブコード(=マシン語)を生成すること。実行時に与えられるデータを使って最適化などできるので、C/C++ で素直に書くより速くなることが期待できる。正規表現の実装などでは普通に用いられている。
- 普通のプログラムは汎用的に(どのCPUでも)動くことを考慮して、CPU の新しめの機能を使い切ってはいない(現行のほとんどのパソコンが対応していても)。それらを使うにはアセンブラ(あるいは同等のコード)を書くしかない。