Rubyでインラインアセンブラできるようなクラスを作ってみた
界隈でRubyが遅いとか言われているので、「インラインアセンブリできれば超早くなるんじゃね?!」と思って、やってみた。ちなみに、Linux上じゃないと動かないよ!
クラスファイルasm.rbのダウンロードはこちらから
このファイルと同じフォルダに、以下のようなsample.rbを設置しまして・・・
require "asm" str=<<-E .section .data message: .ascii "hello,gas!\n" .section .text .global start start: //システムコール4番(write)をコールしたい。 movl $4,%eax movl $1,%ebx //引数2:出力先に対して書き込みたいバッファ movl $message,%ecx //NULL文字を入れて12文字 movl $12,%edx int $0x80 E Asm.new(str).exe("start")
以下のコマンドを実行すると・・・
$ ruby sample.rb hello,gas!
おお、ちゃんと動きました!!これでRubyが超早くなるね☆
実行時にちょっとファイルが吐き出されちゃうけど、そんなことは気にしないでね!
挙動
えらい書くのが遅くなっていましましたが、一応挙動を説明させてもらいます。需要なさそうですが(w
- ソースコードを文字列(上記の例ではstr)として用意します。
- Asm.newの引数として、ソースコードの入った文字列strを渡します。
- Asmクラスのinitalizeメソッドが呼ばれます。内部では、うけとった文字列をダイナミックにアセンブルし、共有ライブラリAsmFunctions.soを生成します。Asmクラスを使用する際にmkmfが、必要な理由はここにあります。
- 共有ライブラリAsmFunctions.soをカレントプロセスの読み込みます。
- 初期化が終わり、Asmクラスのインスタンスが返ってきます。
- Asmクラスのインスタンスは、execメソッドを所持しています。この関数の引数として、アセンブリソースコード中でグローバルシンボルとして定義されているものを与えると、そのグローバルシンボルを呼ぶことができます。
というわけで、明らかにIOや共有ライブラリの読み込み方が遅いので、間違っても高速化なんてできません(w
ご利用の際にはご注意を。