観察日記 2011-01-20

RubyVM の謎に迫る

そういえば明日、RiteVM勉強会をしようという話があるんですが、
RiteVMの情報ってどこかにあるの?・・・
例のmatzにっきだけじゃないかな
公開されてる情報は
とりあえず他は知らないですねえ。
あれってどっかの発表だっけ。だったら発表資料もあるのかな
口頭発表はそれなりにしている感
RubyConfのキーノートでしょ?
札幌でも日本語で同じ内容を...
へー
http://www.slideshare.net/yukihiro_matz/rubyconf-2010-keynote-by-matz
とりあえず。
matzにっきより詳しい気はしない。

ところで浮動小数点数をimmediateにする方法を誰か教えてください><
unak: ささやんの論文ではだめなのですか?
浮動小数点数プールを使うやつだっけ
doubleにVALUEを埋め込むやつだっけ
immediateって
http://atdot.net/~ko1/activities/rubyfp2008_PPL2008.pdf
あー、逆転の発想だ
VALUEの中身がそのまま?
doubleには無効なビット並びがたくさんあるので、
それを活用できる。
immediate って言われると、YARV の instruction sequence に double が紛れてるように聞こえる
ruby界隈でimmediate valueというと例のFixnumテクニックのようなものを指す
そこ、こんらんのものとなんだよなぁ
ささやんのは64bit VALUEに埋め込みだからまったく面白くなかった。
あの膨大な数のNaN値は、そこに何かを埋め込めと言われている気はする。 < IEEE754
しかし浮動小数レジスタとvoid*が乗るレジスタは普通違うので
そのへんのレジスタ転送ペナルティがどんくらいあるのかはきになる。
普段の性能が劇的に低下することが容易に想像できるよね...
まあでもやってみないとわかんないか
Pen4でSSEならレジスタ数が増えてかえって速い可能性もあるが。
で、えーと、RiteVMは32bit VALUEだと言い切りつつfloatをimmediateにすると言い切ってるので
いったいどういうトリックなのか非常に気になっているわけであります。
ささだ君がたしか、NaNにポインタを埋め込んでる処理系の話をしてた記憶がある
話をして色々考えた結果がさっきyuguiさんが貼ったPPLのやつでは
ruby-stdではfloatの精度はどうなってたろう
Floatがあったかどうかすら怪しい。
少なくともFixnumはない。
NumericはIntegerしか決めてなかったんじゃ
NaN に意味を与える!
いや確か他の処理系で、floatの表現に手を付けずにNaNに埋め込んでる奴があるって
浮動小数点数など無い」
あ、もしかしたらshiroさんだったかもしれないや
なにがうれしいんだそれは
>doubleのnanにfloat
何にもうれしくないな。
あ、NaNにポインタか整数を埋め込んでる
びっくりしたよw
NaN にもうれしくないな
だれがうまいことをいえと
しかし、俺も前にそのアイデア自体をささやんに聞いたことがあるような気がする。
floatだと全ビット 0 を除く 23ビットが使えて
俺は田中さんに聞いたけどね。
まとめると
32bit VALUEに「float」を埋め込む技は特に誰も思いついてない
だな。
32bit じゃムリと
「float」が実は非常に低精度
というのくらいですか。
23ビット使えるから68000なら実用的です
確かにVALUEにfloatは無理だ
逆かと思った
float に VALUE なら可能かもしれない
http://portal.acm.org/citation.cfm?id=1408687
{util_mput} Efficient floating-point number handling for dynamically typed scripting langua... http://tinyurl.com/23olc2v
floatにポインタを入れるテクニック...
これかな shiro さんの
実ポインタじゃなくてヒープインデックスとかであれば十分入るか。
遅そうだ。
僕もヒープのインデックスなら可能だろうと思っていたけど、やっぱり遅いか
遅いと言ってるけど、言うほど遅くはないかもしれない。
この辺はプロ(=研究者)に聞きたいところ。
ポインタを生で扱わない方が他のテクニックが活用できて処理系全体としてはいいかもしんないし。
mmapでMAP_FIXEDで妥当っぽいアドレスにメモリが割り当てられればインデックス==アドレスとかに最適化できるのではないかという気はする。
それはいえる。
doubleだと52ビット(-1個)か
コピーGCとか出来るように
実行するプロセスでアドレス空間共通にしないでよくなったり

VALUEが32ビットなのにFloatをimmediateにできるんか、というのが元の話題でしたっけ
はい。
先生どうぞ
RiteVMの謎に迫る。第一弾
みたいな。
一昨年くらいに言ってたVALUEをdoubleに埋め込むってやつ
俺が言ってたのは double を VALUE に埋め込むんだけど
VALUE が 32bit,でもCPUは64bit
(駄目か
どっかに説明があるんですか
VALUE(ポインタ等)をNaN に埋め込む
軽くまとめると
* RiteVMについてのmatzの説明の中にある「VALUEが32bit」「floatはimmediate」というのはどういう技なのか
* 一般的に浮動小数点数をimmediateにするにはどういう技があるか(double based、float in 64bit VALUE)
という話題がありました。
というわけで、その辺通過したので、
がーん
元に戻って、で、RiteVMはどーやる気なんだ誰かしらねーか
周回遅れ
というところでございます。
http://www.rubyist.net/~matz/20101114.html
これね<説明
{util_mput} Matzにっき(2010-11-14) http://tinyurl.com/26mjwhb
VMは32bitワードでレジスタベース
と書いてあるが
VALUEが32bitとは一言も言ってない!
なので、VALUEは128bitくらいです^^
レジスタベースVMで、レジスタが32ビットで
そこが甘い。
VALUEは64ビット?
レジスタが32bitではない(または、32bitじゃないレジスタもある)のではないか。
8080の子孫を扱ってる皆さんには常識的な嫌な構成
AレジBレジとあって、ABレジを対象として操作できると
まあ、別に結合できなくてもいいけど。
お隣のレジへ並んでください
アキュムレータとフラグレジスタをくっつける狂気の発想
どちらも演算結果と見れば素直
ポインタは32ビットだけどVALUEは64ビット。意味ないな
Lua は tag byte が付いてたと思うんだけど
あれどうなんだろうな
{unak} たとえば浮動小数点数をdoubleにするかfloatにするか
これを選べる時点でもうVALUEは32bitじゃないじゃん
VALUEでもたないという選択肢も。
もしくは可変長
可変長ポインタ!
そもそもポインタだとは言っていない気がする
うん
...
VALUEにこだわる必要全然ないのか。
{tal0} ・浮動小数点数はimmediate(shootout対策w)。
shootout対策ってどういうこと?
ベンチマークでスコアを稼ぐぜへっへっへ
g:> language shootout
{ko1_ndk} google web bot:: Computer Language Benchmarks Game - http://shootout.alioth.debian.org/ (and 189,000 hits)
こんなのがあったのか。
RiteVMはまつもとさん設計,福岡の人実装だと思ってたんだけど
まつもとさんが設計,実装らしい
というか実装してるのは知ってるけど
設計ってやってんのかな...
福岡の人はなに担当?
まつもとさんに1億払ってRubyを再実装してもらう
意外といいかもしれない
まつもとさんが福岡に行ったり行かなかったりしながら実装しているので。
いろいろ考えたがやっぱりよくわからないなimmediate。
実装見たら納得するんだろうか。
Float 用のヒープが分かれてるとか
間接参照した時点でimmediateって言わないんじゃない?
というあたりで悶々としてます。
そうかぁ
ほとんどの Float は immediate,というのは割と楽そうな
そうですね
んー
でもdoubleを組み立てるコストは掛かるんだな
コード埋め込みかなぁやっぱ
iseq相当に。
http://alohakun.blog7.fc2.com/blog-entry-907.html あろはくんが書いていた
{util_mput} ホワット・ア・ワンダフル・ワールド NaN の話 http://tinyurl.com/2wohqvr
ただね、単体の浮動小数点数を最適化しても Ruby では嬉しくないと思う
shootout対策だから、いいんじゃね
浮動小数点数については、NArray を飲み込む方向が良いと思うなぁ
言語拡張ですね
全部long doubleで扱う必殺技
数値屋さんにとっては、浮動小数点数1個の演算なんてゴミみたいなもんでしょう
つか,別に飲み込まなくても
普通に NArray 使えでいいんでないの
えぇ、普通に NArray 使えで良いです
組込クラスにするのには抵抗があるんだよな
標準添付は,現状ではちょっとネガティブだけど強い反論が出来ない
作者の田中さんが入れたくないらしいというのが一番強そうか < NArray 反論
田中さんは入れたくないっぽい雰囲気でしたよね
それだとそれで終了ですな
もうちょっとうまい作りになると思う
もうすこしブラッシュアップしたいらしいですよ
NArrayそのままだとデファクトだからこれででいけるけど、
ブラッシュアップするともっと他の人がいいの作るかもとなって、入らなくなる
互換APIがあればいいんじゃねという気はする。
まぁ、それはたしかに
Hashieなんてものが
Hashie::Mash は、再帰 OpenStruct ってところですか

unionを値渡し
これでサイズに関係なくimmediate感が得られるな
Hashェ...
ポインタとdoubleって区別できないパターンがない? 64bitだと
ポインタ64bitはむしむし
むしむしQ
IA-64アドレス空間64ビットですが
x86-64は48ビットだったりしますねぇ
doubleは即値だが
ポインタは間接参照です(キリッ
というわけで解決した。
それを頼るとあとがこわいけど
つーかrubyで試せばいいんだけどな。
どれくらい性能が変わるか。
すくなくともmatzの手元ではfibがうごいているんだよなぁ
fib に浮動小数点数使うとは
黄金比な奴じゃ
slapだってfibくらい動くからなあ。
動いてなくても設計は終わってるのではという意味で。
設計しなくてもfibくらいまでは数日で実装できる
VALUEが3wordなのか
それ、全体的に遅くなってね?
1word何ビット?
3wordってえーと?
同じことをw
48bitか96bitか
http://twitter.com/yukihiro_matz/status/23280495450132480
{util_mput} Twitter / Yukihiro Matsumoto: @taru そこは基本的にLuaと同じです。..
floatの指すものが単精度か倍精度かで
あれ,3word も要る?
32bitだと明言してたので、96bitです。
64bitまるまる入れる前提?
で、trick使わないと3word必要なのかね
そういうことになるのかな。
で、Luaの実装知らないんだけど
union値渡し?
本質的には70bitくらいあれば十分なはずだが
Lua は 1byte + union
doubleならそういうことになるな
70bitと96bitは速度変わらないというか
あろはくんのによれば、doubleのNaNのビットパターンに32ビットなものをいろいろ詰めているということだけど
Lua
パディングすると同じサイズになったりして
それは新しい版
というか,今の最新はどっち使ってるんだろうな
パディングで 3 word というのはありそう
どうせキャッシュラインに乗れば1wordも8wordも関係ねえよというのはありうるか?
96ビットあれば80ビット型が入るな
long double
ロードストアがwordからずれると遅くなるから
http://www.tom.sfc.keio.ac.jp/~fjedi/wiki/index.php?Lua#u9f199a3
{util_mput} Lua - 自分用メモとか
じっと読む
外部に内部型を見せてないぽい?
http://www.lua.org/source/5.1/lobject.h.html
{util_mput} Lua: 5.1 source code - lobject.h http://tinyurl.com/2e9g3yz
Union of all Lua values
とりあえずこれはint=32bit?
lua_Numberは、と
double
ふむ。
というか実際の使われ方だ
GCObjectは一体何者
即値じゃないオブジェクト
のうち、GC管理下にあるもの
この間、ささださん所で、Squirrelの本を読んでいてLuaには数値型は浮動小数点オンリーという話を初めて知った
JavaScriptがそうでしたっけ?
そういえばそんなことが
JSもそうですね
JavaScriptJavaScriptのレイヤーに見えているのは浮動小数点数だけだがだからといって概念に整数がないわけではない
たとえば配列のインデックスとかは整数
そうか
うーん
普通にTValueのポインタを回していて、別に楽しくなかった。
http://www.lua.org/source/5.1/lstate.h.html ここか
{util_mput} Lua: 5.1 source code - lstate.h http://tinyurl.com/33cu5nj
TValueが本体か、なんだつまらん(おいついた
RubyのVALUEのほうがつおいじゃん
それ、VALUEとRVALUEじゃん
全然面白くない。
要するに全てが間接参照になっただけと言える。
つまり、「VALUE相当が構造体(3ワード)」が誤解を招く情報だったと
いやいや
そこはやっぱり3word値渡しを・・・
え,3 word 値渡しじゃないの?
あれ,Lua って値渡しじゃなかったっけ
ポインタ回すのか
勘違いしてたな
俺の目にはそう見えた。
読み間違えてるかもしれないので確認してね。
うい
lobject.hとlstate.hでする
96bit値渡しだと性能どうなんでしょうね
実はそんなに悪くならないんじゃないかと思うんだがどうかな。
値渡しだと思っていて,それで速いって凄いね,とまつもとさんと話をした記憶が
やっぱりTValue*だね。
あ、いや
違うか。
スタックがTValueの配列として事前にどっかーんと確保されている?
45個の配列をどっかーんと確保していた。
ほー
どういう用語を使えばいいのかよくわからないが、
rubyでいうところのCメソッドみたいなものは、それぞれが直接スタックを覗くので、TValueやTValue*が引数で来るわけじゃない。
だから値渡しもクソもねーよという結論
Cコードも直接そこを覗くのか
わかりやすい所でmathライブラリを見ましょうか
http://www.lua.org/source/5.1/lmathlib.c.html
{util_mput} Lua: 5.1 source code - lmathlib.c
冒頭のmath_absLuaabsの実装なんだけど
ご覧の通りさ。
引数はどうやって渡してるんだ。。
ん?
スタックに積むんじゃない?
なる
俺が気になるのは、「さて問題です。このC実装メソッドは引数を何個取るでしょう?」というのが
どこにもなさそうに見えるということだ。
まあいいのか。
しかし、そうか。最初からこういう実装だったらいろんなことが簡単になるな。
VMレベルなら無くても、問題なさそう
srand で checkint してるね
Luaスタック上にあるものと別途登録されたもの(グローバルなオブジェクト)以外は全部GCしていいぜヒャッハー
とか。
状態オブジェクトが全部持ってるわけね
ほんとかな。
まあ、すごく参考になった。