くまりゅう日記

もっと過去の日記
[.NET | BeOS | Blender | COLLADA | fossil | mono | monotone | NPR | OpenGL | PeerCastStation | Riko | Ruby | Silverlight | TRPG | XNA | ゲーム | ゲーム作り | プログラム | | 模型]

2010-01-12

_ 日記

イベント終わったー!!

連休はずっとイベントでした。3D3Dうるせーからアバター見にいくおとか考えてたんだけどそういやそれどころじゃないじゃない。

金曜日深夜から配信はじめていつもどおりgdgdで0時に開始。ちょっくら不備があってページが更新されなかったりあったけどすぐに対処してオープン。

それから一旦寝てちょっとだるいのでだらだら。しかしどうもページのキャッシュに不備があって更新したつもりのページが更新されなかったりしたらしい。やっちゃった。

負荷的には大丈夫そうだったのでキャッシュを切って対処した。あとはファイルサイズが1MBまでしかアップできないとか。おー、Datastoreの1エンティティが1MBまでって気付かなかったよ。やべえって。

他にもいろいろまずいところはあったんだけどなんか適当に回避したり今更なんで放置したよ!次回も俺がやるなら反省を生かしてもっとちゃんとしたいところ。

しかし主に俺以外の活躍により非常に盛り上がっていいイベントだった。次回は前回同様秋といってた人もいるけどこっそり5月あたりにやってもいいかもしんない。1月、9月だと春から秋までが長すぎて秋から春までが短いんだよね。4ヶ月毎にならした方がいいかもしれん。出す方は大変なんだけど。特にゲームとかは。

ま、あとのことは後で考えよう。たのしかったです。

あと収支的には、いや支出しかないけど、たぶん$2くらい。CPU負荷は余裕で下り帯域だけ無料分突破しました。

_ [COLLADA][Ruby] Ruby/DAEとか

Ruby/DAEは3DモデルなんかのデータフォーマットであるところのCOLLADAをRubyで比較的手軽にあつかいたいとかなんとかの奴です。いまつくってます。と、たまに解説。

以前COLLADA RefinaryのConditionarを扱えるようにしたいなーという話をしてたんで、そもそもCOLLADA Refinaryってどうやってできてんのよって調べたんですよ。

で、見たらCOLLADA RefinaryはJavaなんだけど、ConditionarはC++でCOLLADA DOM使っててJNIでそれを呼んでいた。そうですか。そこまでするならなんでJavaなん。

あとrefinaryはコマンドラインからでも呼べるのでべつにそれでもいいかなーと。

最近はスキーマを手書きしてるんですけど。というのもXSDむずかしすぎるからRELAXNGで。しかしめんどいなーと思いはじめて、あれ、もしかしてこれCOLLADA DOMのラッパを書いた方が早いんじゃねと思いはじめた。

なんで最初からそうしなかったかというのは、昔のCOLLADA DOMはCOLLADAのバージョン毎に別ビルドになってたのでそれはどうかなーというのが一つ。あとはIntegrationって機能がC++じゃないと無理な作りしてるのでそれも使いたいっていうのがひとつ。

だが今のCOLLADA DOMはバージョン別のCOLLADAを同時には無理でも一つのバイナリで扱えるような感じだ。よく見てないけどたぶんできんだろ。

あとIntegrationはコンパイル時から定義してないといけないからラッパでなんとかするのは無理…でもないがやりたくないな。まあこれはRubyで再実装してもそんなに手間ではないだろう。

ということでべつにCOLLADA DOMのラッパで駄目な理由が無くなってしまった。あー。無駄な作業だったかね。

と思ったんだが、良く考えたらPure RubyだとRubyが動くとこならどこでも動くんだった。COLLADA DOMのラッパだと拡張ライブラリになるからMRIじゃないと動かないが、Pure RubyならJRubyでもIronRubyでもMacRubyでもRubiniusでも安心だ。そのまま動くかどうかはともかく動くようにするのは簡単だ。

じゃあやっぱり作るか。Rubyの実装が増えた今時に拡張ライブラリって不安があるものね。

_ [Ruby] Rubyの拡張ライブラリ

拡張ライブラリとかいったついでにRuby拡張ライブラリの今後について考える。

MRIでは拡張ライブラリはまだまだ重要なものだが、Ruby実装が増えてきた昨今では忌避されるような存在になってきた。そりゃまあCべったりですし、なによりMRIの実装を拡張ライブラリ側に見せちゃってるのでMRIべったりだ。

しかし拡張ライブラリはそう簡単に手放せない。

拡張ライブラリの用途の一つはCの豊富なライブラリを使いたいよ!なブリッジ用途。これはruby-ffiとかで動的バインディングすればいいんじゃねという話みたいね。 拡張ライブラリでのラッパよりはオーバーヘッドかかりそうだけど、それほど頻繁に呼ばれるわけでもないとかオーバーヘッドは無視できるレベルの実行時間なら問題ないんじゃないだろうか。

これならJRubyだろうとMacRubyだろうとRubiniusだろうと、ruby-ffiさえしっかり作れれば簡単に移行できる。dlがMRI標準添付だけど、これではだめなこともあるらしい。でもffiなら完璧ってわけでもないらしい。詳しくはしらべてくれ。

それ以外の用途としては、Rubyじゃ速度足らないからCで速度稼ぐよ!ってのも拡張ライブラリの出番だ。これはffiでなんとかしるってのが難しい。いやまあCで書いたdllをffiで呼び出せってのはあるかもしれんけど、オーバーヘッドが問題になりそうな場合の話なのできびしい。あとCだけでいろいろかくのめんどい。

JRubyではもはやJavaで書き直せってのが普通なようだ。まあそうか。IronRubyも拡張ライブラリなんぞ知らん状態だからC#とかで書き直すのが普通だろう。

MacRubyやRubiniusはMRIの拡張ライブラリ互換ってことになってる。当然ソース互換でリビルドは必須だろうけど。

しかしこれも難しい問題があって、それがGCとスレッド。よく調べてないんだがこの扱いがどうなってるのかよくわからん。

MRIではGCは拡張ライブラリ内のC関数実行中にGCが起きてもスタック上にあるオブジェクトっぽいのは勝手にマークしてくれるので、まあだいたいGCを気にせず作れる*1。スレッドもマルチスレッド化してもMRIでは一度に複数のスレッドはRubyレベルおよび拡張ライブラリでは動かないのでこれも気にせず作れる*2

で、その辺さっぱり気にせず作ってきた拡張ライブラリがMacRubyやRubiniusでどう動くのかってことだ。

関数のインターフェースは合ってはいるんだが、GCとマルチスレッドは謎。マルチスレッドは使う側が気をつけたとしても、GCは厳しいぞ。ソースを見てもよくわからんしなぁ。たぶんそのままでは難しいかもしれん。

あ、でもMacRubyはObj-CのGCを有効にしてるならそれがいけるのかもしれない。しかしObj-CのGCは詳しくないのでいまはわからん。ただMacRubyならJRubyやIron RubyのようにObj-Cで書くっていう方法もありはする。

Rubiniusはちょっとコードに手を入れないとだめそうな雰囲気は漂ってるがさてどうだろうね。

マルチスレッドはたぶんどっちもだめだろうな。なんとか気をつけるしかない。拡張ライブラリ内部でロックする方法もとれはするが…。

というわけで、MRI以外をつかおうとすると拡張ライブラリの先行きはけっこう不安なものである。いや先行きっていうか現状も不安か。 拡張ライブラリをこれから作ろうとする人は気をつけよう。Cのラッパならruby-ffiなんかを使ったり、そうでなくともC単体で書いてruby-ffi経由で使った方がポータブルかもしんないよ。

さて今まで気にしてこなかったMRIの話なんだが、これもちょっと拡張ライブラリは微妙なところがある。よく問題になるのはWindowsでのコンパイラによるバイナリ互換性だよね。これはコンパイラっつーかCランタイムのバイナリ互換性なんだが。

まああれだ。VC6でビルドしたRubyがVC9とかcygwinでビルドした拡張ライブラリを読み込めないってやつ。cygwinはWindows上で動くふりして実は別世界の住人なので仕方ないとしてもVC間でもバージョン違いでおきるとか困ったものだ。

しかも今よく配布されてるRubyのバイナリはVC6でビルドされてる。もうサポートされてないVC6で。もう入手も困難なVC6で。1.9はさすがにVC6じゃなくなるのかなーと思ったがそんなことなかったぜ。

そんなわけでWindows用に拡張ライブラリを作ってバイナリ配布しちゃうお!とか考えると困ったことになる。俺ならmingw32一択だけどな。

さらに言うとWindowsの64bitではそんな状況がどうなるかさっぱりわからんのだ。いやまあCランタイムの互換性問題はそのままなのはそうなんだろうけど、バイナリ配布の標準的なコンパイラってのはどうなるんでしょうね。

バイナリ互換性はこのくらいにしておこう。

それ以外にもMRIの拡張ライブラリにはMVM対応ってのが待っている。MVMってのはマルチVM。一つのプロセス内で複数のVMを立ち上げればプロセス1つで完全非同期な複数のRubyスクリプトが動かせてうまうまってやつ。

VMは複数でも読み込まれる拡張ライブラリはそれぞれ一つである。するとどうなるか。

今までInit_なんちゃらっていう関数を一回呼ばれるだけだったのが複数回呼ばれたりする。今まで定義したクラスとかグローバル変数に保持してたりしたのが複数保持しないとこまったことになる。今までシングルスレッドからしか呼ばれなかったメソッドが違うスレッドの違うVMから同時に呼ばれたりする。とかなんとか。

これでは今までの拡張ライブラリがそのまま動くことはありえないので、MVMではInitVM_なんちゃらって関数がある拡張ライブラリだけフルパワーで動くようになる。従来のInit_なんちゃらしかないものは制限つき。制限なんだっけ?一つのVMでしか読み込めないとかだったような。

対応しなくても動かなくもないのは確かだし、そもそもMVMって普段俺使わねーよて人も多いだろうが、やっぱりあるなら対応したいものである。あとサーバ用途ではMVMが使われる可能性は高いだろう。mod_rubyとか。

しかしこれが結構大変である。なにしろグローバル変数とか静的変数がそのままでは使えなくなるんだから。一応VM毎の記憶領域ってのが使えるAPIはあるようなのでそれを使えばよさげだが、なんにせよ移行する必要はあるわけだ。ああ、もちろんVMと関係ないグローバル変数とかはそのままでもいいですよ。再入可能ならね。

というように拡張ライブラリはけっこう大変なものである。できれば避けたいんだが、PureRubyで書くにはどの実装もまだまだ速さが足りないし、RubyがRubyである以上静的型付きな言語より速くなることはあんまり無さそうだ。少なくとも10年やそこらでなんとかなるものじゃないだろう。

えーと、まとめようと思ったんだが上手くまとまらなかったな。うん、つまりまだ俺の中でもまとまってないんだ。こまったものよのう。

*1  実際はいろいろ難しい所もあるようだがまあだいたいは気にせずすむ。

*2  1.9なら無理して一部本当の平行実行もできる。普通やらんけど。


ページのトップへ | トップ «前の日記(2010-01-07) 最新 次の日記(2010-01-15)» | 編集 | kumaryu.net by kumaryu