やっと書き終わった.終わり終わり.もうヤダ.
すげぇな,さくっと20席.何日もつか.
週明け.月曜日にテストがある.テストっていうのは,2年ぶりくらい? ソフトウェア技術者試験以来かもしれない.火曜日に英語の論文を読んで発表.まだ一行も読んでない.20ページくらい.再来週の月曜日までに,結構な量のレポートを書かないといけない.再来週の木曜日修論発表.ここまでくれば,学校の用事はとりあえず終わるのか.あ,あと遠隔授業の消化.
まだyarvは触れそうにない...
昨日(というか今日未明),PCつけっぱなしにして帰ったのを忘れていて,着いたら電源ボタンをおしてしまって,アボーン.なんてこった.
提出ー.色々疲れた.でも,卒論のときよりはましかな.
かけた迷惑は卒論の比じゃないな.ごめんなさい.>こころあたり
yarv に手を出そうとしたけど,眠くてやる気にならん.
素人考えなんですが,GCごとに setjmp して, jmp_buf をスキャンするようにしたらスタックに volatile で保存しとかなくてもいい,ってことはないのでしょうか.
非常に単純なので,誰も考えつかないとは思わないから,なんらかの理由でだめなんだろうけど,その理由が思いつかない.
「スタックはメモリ番地が小さくなる方向に連続して確保される」って仮定くらいは「jmp_bufにレジスタコンテキストが保存される」っていう仮定も真っぽいと思うんだけど.
なら,そういう ruby を長時間使いつづければいいのか.volatile 全部外して.今度やってみよう.でも,この問題はきっと機種を変えたときにまずいことがあるかもしれないんだな.
って,gc.c 見てたら既にやってるじゃん.ガーン.
http://i.loveruby.net/ja/rhg/gc.html の「GC対策のvolatile」より引用.
スタック上のVALUEはGCが面倒を見てくれると書いた。それならばローカル変数としてVALUEを置いておけばそのVALUEは確実にマークされるはずである。しかし現実には最適化の影響で変数が消えてしまうことがある。例えば次のような場合は消える可能性がある。
うーん.そうか.volatile の意味を勘違いしていた.
ということは,yarv のコンパイラに volatile 付けまくった意味ないな.なんてこった.
いい加減,恥さらし日記から脱却したいものだなぁ.
Apple - Hardware - Video - Virginia Tech’s Supercomputer(/.j).いや,映像を見たのは初めてだったんですが,こりゃぁたいしたもんだ.ほんとうにずらーっとならんどる.
しかし,インドの方だろうか,英語がとても聞きやすい.ドンガラさんとか聞きづらい.全部インフィニバンドで繋いでるんだな.
何時くらいに起きる?.何時くらいに起きたい? じゃないんだけどなぁ.いや,マジなのか,これが.
ケンタッキーフライドチキンをケンチキと略しているのを見てショックを受ける.ケンタなら見たことあったんだけど.
参考文献の数が50くらいにしかならなかった.サーベイを中心としているんで,少ない.
前もやった気がする.
class DoElse def self.else_ yield end def self.elsif_ cond if cond yield DontElse else DoElse end end end class DontElse def self.elsif_ cond DontElse end def self.else_ end end def if_ cond if cond yield DontElse else DoElse end end def test obj if_(obj){ p 'true' }.else_{ p 'false' } end def test2 o1, o2 if_(o1){ p 'o1' }.elsif_(o2){ p 'o2' }.else_{ p 'none' } end test true test false test2 true, true test2 true, false test2 false, true test2 false, false
もちろん値は返らない.
class DoCatch def initialize e @e = e end def catch_(*ec) if ec.size == 0 yield(@e) return DontCatch.new end ec.each{|e| if @e.kind_of? e yield(@e) return DontCatch.new end } self end end class DontCatch def catch_(*ec) self end end def try_ begin yield rescue Object => e return DoCatch.new(e) end DontCatch.new end class E1 < Exception end class E2 < Exception end def test obj try_{ raise obj }.catch_(E1){|e| p e }.catch_(E2){|e| p e }.catch_{|e| p e } end test(E1.new) test(E2.new) test(Exception)
なんか抜けてる気がしないでも無いが.raise の連鎖が出来ないのかな.
いやー,やっぱり shiroさんのお名前は凄いな.
class DoElse def self.else yield end def self.elsif cond if cond yield DontElse else DoElse end end end class DontElse def self.elsif cond DontElse end def self.else end end def self.if cond if cond yield DontElse else DoElse end end def test obj self.if(obj){ p 'true' }.else{ p 'false' } end def test2 o1, o2 self.if(o1){ p 'o1' }.elsif(o2){ p 'o2' }.else{ p 'none' } end test true test false test2 true, true test2 true, false test2 false, true test2 false, false
奇妙だ.
五十嵐先生の日記が凄い.
あかん,プロキシ通してると思って通してなかった.失敗.
バカが征くより引用.
オレが嫌うのは、まさに創造の余地のないプログラミングだ。分析も設計も全 部終わってて、指図されたとおりにコードを埋めていくなんて、まっぴらゴメ ンだ。そんなものは断じてプログラミングではない。
テンプレになりそう.
もしrubyにマクロが使えたら,と考えてみる.まず,どんな文法なんだろう.
参考文献を60本に増量.自分たちの論文を参照してみたり.人数が多いと,これだけで凄いことに.
see RHG p.162-163
ガーン,恥ずかしいので消そうと思ったら見られていた.家に帰らないとRHG読めないのですよ.帰りたい.
というか,読んだ記憶が蘇ってきた.
関係ありそうでなさそうなCheney on the M.T.A
どのへんが関係あるかわかんなかったんですが,非常に面白く読みました.
ChickenというScheme処理系が、Cheney on the M.T.Aを実装していますね。
ヤバイ,なにやってんだ俺は.
何時くらいに寝る?.わかりやすい.
修士論文の発表会の日程が告示されました.2/12(木) ということで,13日の金曜日にならずに済んだようです.発表が20分,質疑応答20分.
時間を長く取った卒論発表,ちょっと新しくした SACSIS 発表,って感じだろうか.どうしたもんかな.
その前に修論・・・.
visibility のために,recv のありなしを分けなきゃいけないのを忘れていた.
recv を undef にするかなぁとも思ったけど気持ち悪いのでやめ.send のオペランドに一個追加するか.send id, argc, visibility,chache.
う,「表」で見事に腐ってるらしい・・・.
頑張ってゴタクを並べる.
何か足りないと思っていたら,ブラックブラックを買っていなかった.去年の卒論では何個消費したんだろう.一晩で3袋くらい食ってた気がする.
ガムは食う,でいいんだろうか.
世間知らずということを再認識したんですが,Linux Conference 2001 ですでに VM 作るぞ,とか paper とか出してたんですね.佐原 大輔さんという方も知りませんでした.でも,この方のfull paper の著者名が木山さん.世の中は難しい.
しかし,この仕様のVMじゃまずいんちゃうかな.いろいろと.たとえば,setpool って要るんかなぁ.クラス名って文字列だったのかな,この頃は,とか.
ipa の未踏んときのVMってこれ? それとも別物なんかな.
前田さんの論文を読みながら,プロファイリングどうやって取ろうかと考えて見る.とりあえずどっか飛ぶ命令までを基本ブロックにして,部分命令列の統計取るか.でも,ちょっとやっただけでも統計データ,相当おっきくなりそう.
「何時くらいに寝る?」へのリンクが違います
ありゃ.
□setpool
コンパイル結果が
[定数1, 定数2, ...] [命令コード1, 命令コード2, ...]
の組になっているわけですよね。Emacsの.elcファイルみたく。 メソッド<->定数表が1対1ならsetpool命令は要らないかもね。 メソッドに入ったときに自動的に定数表を切替えれば良いから。 佐原さんのVMは、複数のメソッドをまとめたコンパイル単位ごとに定数表が1つという 設計なのでしょう。まあ、それでもinvokevirtualが自動的に切替えちゃうという選択肢も あるだろうけど。
□プロファイル
私はラベルごとにカウンタを設けて、基本ブロックの実行回数を測り、 次にそれぞれの基本ブロックの部分列をつくり、部分列パターンの合計の 重みを求め…とやったんだけど、実は
Greedyな命令融合手順の1ステップでは、2命令→1命令の融合しか起きない
(2命令より長い部分列よりも、頻度が同等以上の2命令の列が必ず存在する)ので、 実は命令の動的なbigramを記録するだけで良いかも。つまり、
(命令1, 命令2)→頻度
のハッシュ表(バイトコードならただの2次元配列でも可)を作れば良いかも。 オペランドの融合まで考えるとちょい面倒だけど。
納得しました>ラベル〜,部分列〜
融合する命令列を求めた後,その融合は自動で全部やられたんでしょうか.それとも,手で書かれたんでしょうか.
あと,そもそも定数表っているんだろうか,ってのがyarvでの実験の一つです.命令列の利用メモリは4倍ほど増えるとは思うんですが,それが何か? って感じで.
実際どうなんでしょうね.
定数表がないとすると、GCで命令列をスキャンする必要が出てきてしまうような。
融合操作自体は手でやりました(ださ)。
GCのためには、(GCのためだけの)定数表、あるいは命令列中の定数参照の位置が分かるしくみが必要ですね。特に、コピーGCだと後者が必須。
定数表をスキャンするのと,命令列をスキャンするの,あんまり手間は変わんないと思うんですが,どうでしょうか.・・・そうでもないかな.
一個,定数をリンクする配列を持っておけばいいような気がしてきた.
命令中の定数参照場所へのポインタ配列なんてのが素直でしょうね。ところで命令列もGCするのかな?
現状だとGCします(いいか悪いかは別).で,現状では命令列を全部スキャンしてます.
class C def m p 1 end end CC = C.dup class CC def m p 2 end end C.new.m CC.new.m
sum ってこんな感じなんだろうか.
module M1 def m1 p 1 end end module M2 def m2 p 2 end end def sum m1, m2 mod = m1.dup mod.module_eval{ include m2.dup } mod end M3 = sum(M1, M2) include M3 m1 m2 #=> 1 2
acm の論文はオンラインで見れても,情報処理学会の論文はオンラインでは見れない(まぁ,紙では見れるんだけれども).なんとなくダメな気がする.
すみません,調べなおしました.
電子図書館 を見ると,研究会報告,および研究会での論文誌(トランザクション)以外は個人会員でも見れるのですね.
でも,見たいのは多分トランザクションな気がします.
やっぱり,大学単位で契約,とか用意してもらいたいです.学部生に,もっと論文に親しくなってもらいたい,とか.
・・・みねーだろうなぁ,こんなサービスやっても.だから問題になってないのか.
ずっと考えてたんだけど(考えるなよ),send はこんな感じか.super, yield(block抜き) も同様.
send id, num, cache id : method id num: arguments size which are on stack. If this is negative, the top argument is array and this is expanded. If block is not false, this is iterator invocation. cache: secret :X stack: arg1 arg2 ... argN recv block => return_val DEFINE_INSN send (ID id, ulong num) (..., VALUE recv, VALUE block) (val) { ... }
block と recv の順番が微妙.そもそも,わけるべきだとか.でも,分けだすと面倒くさいので分けない.これで fix かなー.negative とかやると,自動で命令わけるのが大変そうだよなぁ・・・.でも,命令一個増やすのも面倒なんだよなぁ.これ用の命令一個増やすと,super, yield もそれぞれ増やさないといけない.これは是非自動でやるようにしたい.
putnil とか消したのも,全部自動最適化器を見込んでのことなんだが,putnil くらい残しておいたほうが良かったかもしれない.出現頻度多すぎなので.
で,その自動最適化器を誰がいつどうやって作るかが問題だな.
具体的にはパターンをちょろっと突っ込んでやると,命令合成とコンパイラの最適化器の生成を勝手に作ってくれるやつを考えてるんだけど.オペランドの値の属性(kind_of? Fixnum だとか positive だとか)までパターンで記述できるようにすると・・・,どうなるんだ.greedy match でいいんだけど.検索は素人なので,よくわからない.
vmgen はきっと命令列に対してパターンマッチかけてsuper instruction 作るんだよな.オペランドとか,パターンでかけるようにするにはどうやったら綺麗にいくんだろう.単純なものなら思いつくんだが.
コンパイラでしこしこ一個ずつ作ったほうが早かったりして.
全然関係ないけど,super って何回も呼べるんだな.いや,initialize の context だと奇妙に見えたんで.
class C def initialize yield end end class CC<C def initialize super super{ p 1 } super() end end CC.new{ p 2 } #=> 2 1 2
super() ではエラーになるかな?(ブロックが伝播しないため)と思ったけどエラーにならなかった.
list と dev,悩んだ.どっちに投げるべきだったんだろう.
specialization: putliteral false, send :+, 1 => opt_plus putliteral false, send :-, 1 => opt_minus putliteral false, send :*, 1 => opt_mult putliteral false, send :/, 1 => opt_div putliteral false, send :<, 1 => opt_cmp_lt putliteral false, send :>, 1 => opt_cmp_gt putliteral false, send :<=, 1 => opt_cmp_le putliteral false, send :>=, 1 => opt_cmp_ge putliteral false, send :==, 1 => opt_cmp_eq putliteral false, send :===, 1 => opt_cmp_eqq putliteral false, send :<=>, 1 => opt_cmp_cmp putliteral false, send :[], 1 => opt_ahref composition: putliteral nil, (send|super) <ID>, <+UL> putliteral nil, (send|super) <ID>, <-UL> yield <ID>, <+UL> yield <ID>, <-UL> putliteral nil putliteral true putliteral false
こんな感じの記述になるんだろうか.いい加減にやってると,パーサがえらく大変になりそうだ.
まずは統計とってみないとなんとも言えんか.
どうでもいいんですけど,伝搬と伝播,どっちを使うべきなんでしょうか. goo 国語辞書ではどちらも使ってよさげに見えました.
別に特別扱いしないで,super のときはフレームにブロックの情報をコピーすればいいだけか.
def m(a) p a end m(*(1)) #=> 1 obj = {1=>2,3=>4} def m(a,b) p a,b end m(*obj) #=> [1, 2], [3, 4] def m(*a) p a end obj = {1=>2,3=>4} m(*obj) #=> [[1, 2], [3, 4]]
知らなかった.enumerable ならいいんだろうか.
def m(*a) p a end m(*(1..4)) #=> [1, 2, 3, 4]
いいらしい.うひ.
暴君ハバネロたん,初めて見かけたので買ってみる.後からくる辛さだなぁ.
ガガーン,眼鏡が壊れとる.まだなんとかかけられるが,いつポキっといくか.なんか故障とかパンクとかいっぺんに来るな.
とても思うね.もう,これでもかってくらい.
株式会社 東ハト/商品紹介/暴君ハバネロ.歌付きか・・・.最近のお菓子は凄いんだな.
なんとなく,Interactive Architecture Lab. を見ていたんだけど,SMTはやらないのかな.マルチスレッドアーキテクチャの中で,断然楽しいと思うんだけど.こちらはデータ駆動が基本なのかな.
「逐次プログラムの投機実行を行う中間コードインタプリタの構成法」を見て,この話が今どれくらい進んでるのかな,と思ってみてたんですけどね.調べてもわからなかった.
再来年度はこの続きみたいなことをやりたいと思ってるんだけど.
うーん,筑波か.いいなぁ.留学はありですか(マテ).
尊敬する(略)青木さんが何やらをブレンドしていたので,わたしも何かないか探してみる.
ふと,大学の机を眺めてみると,「紅茶(色々)」「ワイン(赤・白)」「梅酒」を発見した!
どうしてくれよう.
おうちの最大電力が20A から 30A になりました.いままで 20A でサーバ動かしてたっていうのがなかなか.
3年生のシステム製作実験というものが,今年からデモ展示形式に変更した.これはなかなか良い.
いつも突っ込まれてる立場なので,突っ込みまくり.
全然関係ないんですが,mput さんの日記のテーマ感動しました.
そうだよなぁ,yarv とか作ってるよりももっと創造的な仕事を・・・.なんて書くと,VM作りが創造的じゃないような感じだ.
CONST = 1 class C def m p CONST end end obj = C.new obj.m class C CONST = 2 end obj.m
定数探索が定数時間じゃないのは直感的じゃない気がするのは気のせいですか,そうですか.
最内,つまり C に CONST が定義されていたら,探索場所は決定するのか.でも,それで特殊化したって,線形探索の一番最初の部分がそこなんだから,意味ないよな.うーん.
if DEBUG_NANTOKA ... end
に時間がかかってしまうのが心情的に嫌.前回の結果とキャッシュ? うーん.
スラッシングって thrashing って書くのか.この単語を知らなかった.slashing だと思ってた.
thrashdot.org は誰も取ってないんだな.取っちゃおうかな.
dup の話.aa じゃなかった,baa, abb.あ,そうすると,すぐに aa というパターンは出てくるか.aab も,aabb なんてのもあるか.
さて,命令記述から,すべてのパターンを自動的に生成することは可能か.
putliteral obj のすべてのパターンを列挙して見るテスト.
null: a = obj -> a a: b = obj -> ab b: a = obj -> ba ab: push(a); a = obj -> ba ba: push(b); b = obj -> ab baa: push(b); b = obj -> aab abb: push(a); a = obj -> bba aab: push(a); push(a); a = obj; -> ba bba: push(b); push(b); b = obj; -> ab aa: b = obj; -> aab bb: a = obj; -> bba
まぁ,これくらい単純ならいいんだけど.
aab とか bba とか頻出すると,このパターン作る意味ないな.多分,頻出するような気がする.だが,局所的な最適化にはなるか.パターン数を倍化するほどのペイはあるのか.
setlocal idx; 'val => ' をやってみるテスト.
null: val = pop(); local(idx) = val; -> null a: val = a; local(idx) = val; -> null b: val = b; local(idx) = val; -> null ab: val = b; local(idx) = val; -> a ba: val = a; local(idx) = val; -> b aab: val = b; local(idx) = val; -> aa bba: val = a; local(idx) = val; -> bb baa: val = a; local(idx) = val; -> ba abb: val = b; local(idx) = val; -> ab aa: val = a; local(idx) = val; -> a bb: val = b; local(idx) = val; -> b
11状態はやっぱ多いかしらん.40命令あったとして,440命令.手では書きたくない量だ.
pop が一箇所でしか出てこないな.
dup 'v => v v'
null: val = pop(); a = val; -> aa a: -> aa b: -> bb ab: -> abb ba: -> baa aab: push(a) -> abb bba: push(b) -> baa abb: push(a); push(b); -> bb baa: push(b); push(a); -> aa aa: push(a); -> aa bb: push(b); -> bb
aa, bb だけにするって妥協案もあるな.
実は aa, bb って結構あるような気がするので,有効っぽ.
swap 'x y => y x' をやってみるテスト.
null: y = pop(); x = pop(); b = x; a = y; -> ab a: y = pop(); x = a; a = x; b = y; -> ab b: y = pop(); x = b; b = x; a = y; -> ba ab: y = b; x = a; b = x; a = y -> ba ba: y = a; x = b; a = x; b = y -> ab aa: y = a; x = a; a = x; b = y -> aa bb: y = b; x = b; a = x; b = y -> bb
まぁ,無駄なことやってんのはご愛嬌.機械的に書くならこうするかなって感じで.最適化してくれるでしょう,多分.勝手に.
うーん,なんとか機械的に全部いけそうかな.書いてみないとわからないが.dup だけは手で書かないとだめかなー.
それよりも問題になるのは,メソッド呼び出しか.そもそも send をもっとしっかり考えないとな.
いろいろ考えたんだが(考えるなよ),やっぱり今の send はダメダメだなぁ.self はスタックトップにあるべきである.となると,どこに置くべきか.
現状: self arg1 arg2 ... argN l1 l2 ... lM FRAME
しかし,ちょうどフレームへのアクセスが大変っぽ,という問題があった.だから,
fp arg1 arg2 ... argN l1 l2 ... lM FRAME ^ ^ lfp fp fp: フレームへのポインタ
にして,FRAME に self を突っ込んでしまうか.
self をレジスタとして持つ,というのはまつもとさんのVMだったが,なんとなく self ってそんなに使うのかなぁ,というのがあるので,躊躇.使うような気もするけれど.ブロックとかのとき,いちいち入れたり戻したりしなきゃいけないのがどうも.うーむ.やっぱり self はレジスタかなぁ.一緒だとつまんないんだよなぁ(本音).
この,一個空けとく,っていう動作もダサイんだよな.
arg1 arg2 ... argN l1 l2 ... lM FRAME ^ ^ lfp fp
こんな感じだろうか.こんなことやってると,fp, lfp, dfp と,3つもフレーム用レジスタが必要ってことになっている.うーむ.
前田さんのいうとおり,dfp なんてダサイんだろうか.
デュアルスタックにしてしまえば綺麗にいくかなぁ・・・.
VC6 でダメダメな理由がわかった.変数のスコープが広すぎるだけか.各スコープごとに変数を宣言することにしよう.それを解析しちゃった gcc3.3.1 も凄いな.
mput さんの日記の最後,
どのような形の削除依頼であれ公開させていただきます。
というのを発見した.
ということは,適当なことを書いて,
当社の製品は云々で素晴らしく,なんとかでこんなに効果が(略)
のような SPAM っぽいものを100行くらい書いて,末尾に削除依頼,たとえば「間違って書いちゃったんで消してください」とか書けば,こういう広告を公開してもらえるわけなのだろうか.
おうちの samba がマウントできるっていいなぁ.幸せだ.
Smalltalk があるのなら,tinytalk とか bigtalk,hugetalk はあるんだろうか.
YUNO: Yet another rUby vm is Not Orange.
これでいこう.(何を
外向きのDNSがひけなくなっている.はて? こういうDNS障害ってどこを調べていいのかわからんなぁ.
primary/secondary dns ともに ping が飛んでないだけか.なおった.
まつもとさんの日記を見て,そういえばそんなのがあったなぁと思って,眺めてみる.
acm の論文ページ.
Peer to Peer - Readers of this Article have also read:
スゲー,かっこいい.
MJ: a rational module system for Java and its applications
を見て,mix juiece かと思った.でも,人は違うようだ.
しかし,acm 論文見放題ってのは素晴らしいね.農工大万歳.(他の大学では常識だったりして.よく知らない)
SoftEtherというのもありますよ。楽。ブロードキャスト素通しなので気をつけんと危ないですが。
さすがに知っとりますが,ファイルサーバが Linuxなのです.そのために Winに移行するのはちょっと.
あ、そうかプロシンにいたんだもんね。すいません。早くLinux版とかJava版とかRuby版とか出ると良いですね。
ちなみに tinytalk.
論文を書くことに体が拒否反応を示している。
なぜここまで嫌いなんだろう。
eclipse のリファクタリング機能はとても便利だと思う。クラス名やメソッド名なんか、失敗したなー、っていうのがよくあるけど、簡単に修正可能っていうのは幸せ。
yarv だったら、BytecodeSequence クラスを作ったけど、バイトコードじゃねーので、変えたいと思っていたり。誰もつっこんでくれなかったな、そういえば。InstructionSequence クラスかな。長いけど。
ほか、いろいろ。
Apple - QuickTime - Movie Trailers.ここスゲー.映像も音も綺麗.学校だと,とくにキャッシュしなくても見れた.QuickTime スゲー.
ますます手がつかなくなる.
やはり yarv を作ったのは失敗だった.ふと気づくとこれのことばかり考えてしまう.まさに寝ても覚めてもあの人のことだけを,ってやつだ(人かよ).yarvたんじゃやっぱりダメなので名前変えないとな.
しかし,これが「失敗」だと思ってしまう現状はどうか.
いや,俺が頭を切り替えて色々と出来る人間だったら問題ないんだけど.はぁ〜・・・.
NetBIOS over SSH port forwarding.ブラボー.出来たー.
さっそくおうちのサーバの,とりあえず動画でも見てみるか,とやってみたら見れたもんじゃなかった(ぶつぶる切れる).じゃぁ,っていうことで wav ファイルを,と思ったら,やっぱり聞けたもんじゃなかった.mp3 は聞けた.ということで,当初の目的は完遂.さすがにでかいファイルの編集とかはきついかな.でも,ftp 使わないで色々とバックアップをぽいっと置ける.素晴らしい.
stone の常駐が,コマンドラインで起動しとくとうざったいな.どうしたもんか.
んー,ふぉわーでぃんぐ関係は全部zebedeeに移行してしまうかなぁ.暗号認証系が2種類になるのが嫌なんだけど.
・・・何やってんだ,俺.
3段のスタックキャッシングを考える.
push a # s0 = a push b # s1 = b push c # s2 = c push d # PUSH(s0); s0 = s1; s1 = s2; s2 = d push e # PUSH(s0); s0 = s1; s1 = s2; s2 = e push f # PUSH(s0); s0 = s1; s1 = s2; s2 = f
見るからに効率が悪そうである.
最適解.
push a # PUSH(a) push b # PUSH(b) push c # PUSH(c) push d # s0 = d push e # s1 = e push f # s2 = f
もちろん,場合場合によると思うし,殆どの場合,これは意味がないような気もするが.
たとえば,
push a # PUSH(a) push b # PUSH(b) push c # PUSH(c) push d # PUSH(d) push e # PUSH(e) push f # PUSH(f) send :m, 6 # m は ruby method であるとする.
となる.あまり嬉しくない.要するに後続の命令がスタックを消費するか否か,が問題になるのか.
となると,キャッシュサイズのほかに,push するか,とかの情報も必要なのかpush.n.push / push.n.cache みたいな.
純粋な命令数 * (スタックキャッシュサイズ + 1) * 2 の命令数が必要になるんだな.(*1)64個あったとしたら,512命令.現状で40くらい.複合命令を(自動で?)追加していったらすぐに512個とかになりそうだ.まぁ,1024命令くらいが目安か.
うーん,3段は多すぎか.1段で十分な気もするが,それはそれで寂しい気もする.1+1をメモリアクセスなしで行いたい,という理由で2段にするか.まぁ,これは実験次第ということで.やっぱり,自動的に作らないとやってられないな.
あはは,これで同時にinstruction (static) replication の効果も得られるかも.
キャッシュはqueue にはしないのか.でもそれだと状態爆発するよな・・・.2キャッシュで,null, a, b, ab, ba の5状態か.2状態だと ba が増えるだけでいいのか.これで行くか.うーん,ますます shuJIT っぽくなってしまうな.
3キャッシュで・・・.a,b,c,n,n,n の順列で重複部分を削ればいいのか.って,単純な順列じゃないな.やってらんねー,こんな計算.でも,できそうにない数字だということはわかった.
やっぱ2くらいがちょうどいいのね.
3個以上なら,なんとなくレジスタマシンにしたほうがいいような気がするな.命令セットからレジスタを意識した何か.
dup することで,aa,bb っていう状態が出来る可能性があるのか.計7個.うーむむ.
で,aot compile(手作業)で予備評価としてやってしまった.結果は,しないときの3倍くらい.例によって非常に無理やり感のあるテストですが.
i = 0 while i<10000000 i+=1 end => == disasm: <BS:<YARVCore#parse>>======================================== local scope table(size: 2) [1] prog [2] i 0000 putliteral 0 <YARVCore#parse>:1 0002 setlocal 2 0004 getlocal 2 <YARVCore#parse>:2 0006 putliteral 10000000 0008 opt_lt 0009 unless 20 0011 getlocal 2 <YARVCore#parse>:3 0013 putliteral 1 0015 opt_plus 0016 setlocal 2 0018 jump 4 0020 putliteral nil 0022 end ------------------------------------------------------------------------ user system total real 素ruby 11.016000 0.000000 11.016000 ( 11.203000) 素yarv 2.859000 0.000000 2.859000 ( 2.906000) aot yarv real 0m0.901s user 0m0.031s sys 0m0.000s 素C real 0m0.070s user 0m0.015s sys 0m0.031s c_func(){ volatile int i=0; for(i=0;i<10000000;i++){ /* */ } }
11倍くらい? んー.素C にまであと13倍か・・・.これくらいが限界かなぁ・・・.AOTなのに.
もちろん,メソッド呼び出しが入れば,またガクっと遅くなるんだろうけどね.
間違えてた.リテラルに INT2NUM 使ってたのでメソッド呼び出しのオーバーヘッドが.
訂正分 aot compiled ruby real 0m0.668s user 0m0.030s sys 0m0.000s
おお,10倍を切ったな.
ちなみに,どれも VC6.0 で,-O2b2xg- -G6 オプション(mkmf.rb そのまま)ね.
えー,VC6.0 って,定数伝播をきちんと見てくれないのー?
{ idx = 2; val = a; { lfp[idx] = val; }}
っていうのを
; Line 62 mov DWORD PTR _idx$[ebp], 2 ; Line 63 mov edx, DWORD PTR _a$[ebp] mov DWORD PTR _val$[ebp], edx ; Line 66 mov eax, DWORD PTR _idx$[ebp] mov ecx, DWORD PTR _lfp$[ebp] mov edx, DWORD PTR _val$[ebp] mov DWORD PTR [ecx+eax*4], edx
って,馬鹿正直にやっとりやがる.ナンテコッタ.ブロック分けてるからかなぁ・・・.一緒のブロックにしても変わらなかった.ウーム.
というわけで,gcc 3.3.1 on cygwin でやってみた.
yarv aot compile with cygwin gcc -O2 real 0m0.131s user 0m0.124s sys 0m0.015s
なんかちょっぱや.
素C with cygwin gcc -O2 real 0m0.106s user 0m0.093s sys 0m0.015s
おお,なんか肉薄してるぞ! オー.素晴らしい.aot compiler は結構有望かも.素rubyの100倍か.(*2)
しかし,gcc って強かったんだな.
もちろん100倍ってのは広告用の数字であって,現実はそんなにあまくねーことはわかっちょります.多分.まぁ,最速値だよね.
って,何やってんだ俺は・・・.うー・・・.
アセンブラを見てると,gcc なるほどこりゃはえーやって感じ.
たとえば,putliteral(INT2FIX(1000000)) は,きちんと定数で解釈してもらってて.compare 部分でってことね.
貼ってしまえ.
/* 0000 putliteral 0 <YARVCore#parse>:1 0002 setlocal 2 0004 getlocal 2 <YARVCore#parse>:2 0006 putliteral 10000000 0008 opt_lt 0009 unless 20 0011 getlocal 2 <YARVCore#parse>:3 0013 putliteral 1 0015 opt_plus 0016 setlocal 2 0018 jump 4 0020 putliteral nil 0022 end */ #include <ruby.h> #include "../insnhelper.h" typedef unsigned long ulong; int compiled_method(){ int error_code = 0; /* error code */ VALUE stack[0x100]; VALUE *pc; VALUE *sp; VALUE *lfp; VALUE *dfp; VALUE tos = Qundef; VALUE a; VALUE b; /* cache */ ID id; VALUE klass; VALUE mod; VALUE obj; VALUE super; VALUE val; long dst; ulong idx; ulong len; ulong num; lfp= &stack[0]; //0000 putliteral 0 <YARVCore#parse>:1 L0000: //INSN_ENTRY(putliteral) { val = INT2FIX(0); DEBUG_PRINT("putliteral"); { /* */ /* footer */ a = val; }} // 0002 setlocal 2 //INSN_ENTRY(setlocal) { idx = 2; val = a; DEBUG_PRINT("setlocal"); { SET_LOCAL(idx, val); }} L0004: // 0004 getlocal 2 <YARVCore#parse>:2 //INSN_ENTRY(getlocal) { idx = 2; DEBUG_PRINT("getlocal"); { val = GET_LOCAL(idx); /* footer */ a = val; }} // 0006 putliteral 10000000 //INSN_ENTRY(putliteral) { val = INT2FIX(10000000); DEBUG_PRINT("putliteral"); { /* */ /* footer */ b = val; }} // 0008 opt_lt //INSN_ENTRY(opt_lt) { VALUE recv = a; obj = b; DEBUG_PRINT("opt_lt"); { if(FIXNUM_P(recv) && FIXNUM_P(obj)){ long a = FIX2LONG(recv), b = FIX2LONG(obj); if (a < b){ val = Qtrue; } else{ val = Qfalse; } } else{ /* other */ rb_bug("unsupport '<' method"); } /* footer */ a = val; }} // 0009 unless 20 //INSN_ENTRY(unless) { val = a; DEBUG_PRINT("unless"); { if(IS_FALSE(val)){ // JUMP(dst); goto L0020; } }} // 0011 getlocal 2 <YARVCore#parse>:3 //INSN_ENTRY(getlocal) { idx = 2; DEBUG_PRINT("getlocal"); { val = GET_LOCAL(idx); /* footer */ a = val; }} // 0013 putliteral 1 //INSN_ENTRY(putliteral) { val = INT2FIX(1); DEBUG_PRINT("putliteral"); { /* */ /* footer */ b = val; }} // 0015 opt_plus //INSN_ENTRY(opt_plus) { VALUE recv = a; obj = b; DEBUG_PRINT("opt_plus"); { if(recv & obj & 1){ /* fixnum + fixnum */ val = (recv + (obj & (~1))); if((~(recv^obj)&(recv^val))&0x80000000){ val = rb_big_plus(rb_int2big(INT2FIX(recv)), rb_int2big(INT2FIX(obj))); } } else{ /* others */ rb_bug("unsupport + method"); } /* footer */ a = val; }} // 0016 setlocal 2 //INSN_ENTRY(setlocal) { idx = 2; val = a; DEBUG_PRINT("setlocal"); { SET_LOCAL(idx, val); /* footer */ }} //0018 jump 4 // INSN_ENTRY(jump) { //dst = GET_OPERAND(1); DEBUG_PRINT("jump"); { goto L0004; }} L0020: return 0; } c_func(){ volatile int i=0; for(i=0;i<10000000;i++){ } } main(){ //c_func(); compiled_method(); return 0; }
天才チューリングも論文を書くのが苦手だったそうですね。でも、苦労して書いたその論文には独自な味わいがあるそうですが。
名前はMIRVというのはどうでしょう。「もっともイケてるRubyVM」
mirvたん? なんて発音するんだろう.
読みは「マーヴ」ですかね。弾道ミサイルの弾頭の複数個別誘導再突入体(MIRV)からとりましたか。
三浦さんのおっしゃるとおりです。物騒な名前の平和的利用。
こんなものを見つけました>The MIRV Compiler
やっぱりスタックをガソっとコピーするしかないんかなぁ。ふーむ。
ネイティブスレッドを使う、、、とそれはそれで。
おお、結城さんだ。おお、さすがだなぁ。
「科学者にはクリスチャンが多い」からのくだりは、ちょっとよくわからないが。
しかし、毎回インタビュー記事を綺麗に作るね、オブジェクトの広場は。
なんとなく、他の方のインタビューも眺めてしまった。今眺めると、前読んだときと、また違う感じもする。時代の変化を感じてみたり、未来予想があたったり外れてたり(笑)。
SLT と見て STL と思ったのは私だけじゃないはずだ!
・・・多分。
いや、SLT って略語を見たのは初めてだったので。ある人から薦められてただけだから、情報とかよく知らないんですけど。
先日の Orthogonal は2次元だったが、3次元、・・・、n次元計算機を考えてみる。(言語と計算機の話をごっちゃにしてるけど)
n = 3 で考える。
状態に方向が入る。PC=(x,y,z)。方向レジスタがある。DR=(dx, dy, dz)。d は difference じゃなくて direction。difference なプロセッサって見たことないな。
フェッチが大変そうだ。効率的なパイプライン作れないね。
それこそ、プロセッサ移ればいいのか? 隣の(物理、論理)プロセッサに spawn するってのはどっかで読んだ気がするな。SuperThread だったか。あれは一方向限定だけど。
モジュールの集まりとしてグリッドを構成したら、できなくもないのか? 何が嬉しいかよくわからないが。
もっとでかい範囲だと嬉しかったりしないのか? それこそ GRID で d? は difference で。
サービスの記述として利用できないか? ディレクトリよりは綺麗にいったり・・・うーん。初期値があてられないな。
やっぱダメダメ。
GoogleAPI が変だったみたいで、それを使った何かができなくなっていたようでした。ウェブページインターフェース部分の不調じゃないので、影響はそんなでもないのかな。将来的にはもっと辛くなるんだろう。
Seezleが今どうなっているのかよくわかりませんが、リアルタイムデモとかしてるときにこういう事態になったら大変ですね。
今、Googleがなくなったら困る人はえらい数になりそう。いきなり有料化しても、たとえば月100円とかなら、きっとみんな使うんだろうな。
vi で Java の編集って鬼。
有料化したら、使わないという人もいるようで。goo とか使う、と。
俺はある程度だったら払ってしまうなぁ。
yarv.org は空いてるか。うーん。どうしようかな。
ガーン、NODE_NEWLINE なくなったったんですか・・・。ドウシヨウ・・・。
そういえば、結局バイクはパンクだったのでした。
バイク修理もろもろで一万飛んだ。
うちの家族の一人は枕を使わない。なんでだろう。
YARVでの末尾再帰。いつのまにか、 YARV は 酒井さんの玩具。
ソース見てて思ったんだけど、NODE_NEWLINE の修正もあわせて、もっと整理しないとダメだね、これは。
stack gc を考えてみたんだけど、フレームの終端を格納する領域が必要だなぁ。また増えてしまう。
うーん、現状だと(将来的には)スタックにリンクを張ってしまうので無理かも。うーん、困ったもんだなぁ。いや、でも他でも張らないと無理だよな。あ、問題ないか。自己完結。
うーむ、やっぱり tail recursion は ruby には合わないのかなぁ。コスト対効果が合わないかなぁ。
スレッド切り替え考えてみると、無理だな、これ。ガーン。どうしたもんかなぁ。
私が今使ってるのは赤帽九ですが,vi が vim で色が色々付いて結構快適です.Java とか XML とか.
viみたいな癖のあるキー操作をしなくて済むeedit、結構いいよ
bash: eedit: command not found
public class Test { void foo() { ... } void bar() { ... } }
みたいなスタイルで書けば...ってそういう問題じゃないのか。
ソースはここ http://www.users.qwest.net/~hmahon/ Solarisでコンパイル通るかな?
すでにある奴の編集なもので。ただ単に私が vi に馴れてないだけな気がしますが。
新しいもの入れるなら、emacs 入れてもらっちゃうかも。
GoogleWebAPIの不安定さには長いこと辟易してました。結局Googleを使わないという結論になりました。
実験用に Sparcマシンへログインさせてもらう。さて、何しよう。(仕事シロヨ)
ガーン、ruby が入っていない。
ガーン、emacs が入っていない。
バイクの前輪がべこべこに空気が抜けていたので焦る。ガソリンスタンドの店員さんの対応が良かった。感謝。
さっさとメンテ出さないとなぁ・・・。
貼っとこう。RubyVM - A library of components for Ruby Virtual Machines in Ruby。詳しくはまだ読んでない。MRIとかMNGとか、なんか別なものを想像してしまうな。
簡単だった・・・。
これから面接なのに、この緊張感の無さは何。
なんか、同じ面子に同じ話をしてた。うーん。次もまったく同じ話をするぞ、多分。うーん、
えーっと、問題は、「名簿に人名が沢山並んでおり、ある名前 Ni を検索する確率が Pi だとする。名簿の探索は上からの線形探索であるとすると、Pi が大きい順に名前を並べておくのがもっとも効率が良いことを証明せよ」って話でした。
そもそも線形探索かよ、って話もありますが。
C の feof と ruby の IO#eof? は別物らしい。
情報関係基礎を解く。ダメ過ぎ。落第。
eclipse を 128MB のノートで動かすのって苦行だな。
\forall i [1 <= ai <= n \and 1 <= bi <= n]? もしくは f(i) がほんとは [1, n] 上の関数? ....等と書いてる間に問題が消えてるし.
shuJIT はマシンスタックを利用するようにコードを吐くが、一般的にこれは可能か。
気づいてませんでした>るるりん。
うささん、Felioさん、ご協力ありがとうございました。3人同時喋りは結構笑えました。
とりあえず音声は結構いけたので、あとは映像部分が必要、なんだろうか。たとえば、遠隔コードレビューなんかをしようとするとき、別に相手の顔は見なくていいような気がするので、VNCで十分? となると、一つ共用VNCをたてておいて、そいつでなんかするって感じで。
共用VNCってのは結構危険な気がするなぁ。なんかいい手はないものか。信頼できるひとたちならいいのだけれど、たとえば不特定多数とコラボレーションするような場合だと。
sobalipse はeclipseを共用するのでまずい気がする。
SOBAを利用することは可能か? SOBAの説明を見たけどよくわからない。jailした XWindow + VNC ?
うーん、SOBA って Java なのか。トップらへんには全然書いてないような気がするな。Javaアプリケーションに対して、こういうことができますよって、ことなのかな。それだとちょっと狭いような気がする。たとえば MS Office は今後会議システムを前面に押していくそうだけれど、それに勝てるのか?
なんか、お題目は綺麗にならんでるんだが、技術的な部分が書いてないな、ページ。ちゃんとダウンロードしないと見れないのか。
なんか、読んでみると、やっぱり共有できる子OSって感じだな。たとえば、emacs を共有したい! って要求には、やっぱり使えないっぽい。いや、ぱっと見ただけだから、違うかもしれん。
共有できる仮想空間を提供する高価なGUIシステムって認識でいいんだろうか。無茶苦茶な纏め方だと自分でも思うが。
たとえば VMWare で一個子OS作って、そいつで VNC 動かして、勝手にログインしてもらうのとどう違うんだろうか。セッションというか、場の提供の概念というか、その辺だろうか。なら、場ごとに子OS作って(略)。
わかりませんが。
ちょっと使ってみた。なんとなく OpenDoc を思い出した。いやー、でも実際凄いな、これ。
うがー、眠すぎ。
課題のためにダイクストラ法を解くプログラムを書く。眠くて適当だけど。解き方全然覚えてなかった。ガーン。
ふと気が付くと雪が降ってる。これは学校に泊まって正解だったかな。学校に来なくていい生活が正解な気はしなくもないが。
chatソフト、某社からつなげないらしい。なんでー? UDPを途中で落とされちゃってるのかな。
あー、CLI楽しげだ。いいなぁ。
だいたい、甘いものが嫌いな人はいないらしい。
そうか、作った、って言ってさらしてなかったか。
require 'resolv-replace' require 'uri' require 'iconv' require 'open-uri' require 'rexml/document' def euctou8 str Iconv.iconv('utf-8', 'euc-jp', str)[0] end def u8toeuc str Iconv.iconv('euc-jp', 'utf-8', str)[0] end key = ARGV.shift || exit t = 'webservices-20' devt = 'xxx' page = 1 mode = 'books' key = URI.encode(euctou8(key)) u = "http://xml.amazon.com/onca/xml3?t=#{t}&dev-t=#{devt}&" + "type=lite&mode=#{mode}&page=#{page}&f=xml&KeywordSearch=#{key}&locale=jp" begin doc = REXML::Document.new open(u) num = doc.root.elements['TotalResults'].text item = doc.root.elements['Details'] uri = item.attributes['url'] name = u8toeuc(item.elements['ProductName'].text) puts "#{name}( #{uri} ) [and #{num} items]" rescue Exception => e puts "not found or error is occured." end
えらい単純ですが、bot の機能としては、十分。多分。
というか、JITコンパイラってより、AOTコンパイラだよな。とりあえず、それでどこまで高速化できるか確かめてみるか。
PA-RISCでは、マシンスタックがアドレスの正方向に成長するらしいゾ! …割とどうでもいいか。
うーん、気軽に利用できるオープンソースな会議システムってないもんかなぁ。NetMeeting は結局Nat越えが非常に大変そうだ。
skype を試す。非常にシンプルで楽で。
多人数同時通話は・・・やっぱり出来ないのかな。
TeamSpeak を教えてもらう。
これは良さそうだ!
IrcNet #yarv に居ます、ってページに書いといたら、ドイツの学生が来てくれた。なんか、むちゃくちゃアクションゲーム/格闘ゲームマニアだった。基板持ってるってすげー。
そんな彼は IrcNet #yarv に居るんで、興味のある方はぜひ。
ちなみに、上記チャットソフトはその彼から教えてもらった。
某大百科外伝のムービーを見る。あれぇ、昔ののりがない。残念。
その彼に「つきのはしずく」を教えたら、Newgrounds Presents: Xiao Xiao を教えてもらう。わはは。
eclipse をせっかく使ってみたので lisp 関係を使う方法を誰かが考えているはずだ! って思ったんだけど、あんまりないなぁ。
eclipse をせっかく使ってみたので、バーディー君 を入れてみた。
・・・。
いや、なんというか。
mr と方向性は同じ、なんだろうか(絶対違う)。
うーん、誰かこのメッセージと絵を変えようって人は居ないんだろうか。きっと居るな。
ahiru氏に協力してもらってTeamSpeak経由の音を聞いてみる。うーん、やっぱり微妙。ほんとうは仕事で使えるかなって思ったんだけど、このノイズは微妙・・・。
ハウリング起こしてるのでノイズキャンセラーみたいなのが欲しいけど、GENTNER / VTC AccuMic。約6万。手が出ない。
で、2人通話はやってみたんだけど、多人数ではやっていないので、誰か暇な人、いっしょに通話実験してくれませんか。
やってもいいという人が居れば、ご連絡くださいませ。
しかし、学校で一人喋っている姿は間抜け、というか怖い。ノートPC内蔵マイクなので、ハンズフリーだし。怖すぎ。
私的最強ランチャーは WinKey + R なんですけど・・・。ダメ?
スレッド切り替えを考慮したmain loopの。VMループを2種類用意して、SIGALRM が起こったら切り替えを行うloopに遷移。誰か考えてるかな。
こっちにも書いておこう。さかいさんの興味深い実験 によって、命令ディスパッチの効率化による速度向上は ?0% くらいが限界だと思われる。もちろん、スタック操作をそのままやっているので、その辺を変えると、また話は違うようになると思う。
tak のほうが速度向上率がでかいのは、、、うーん、なんでだろう。opt_plus とか有効にしたのかな。
ああ、もっとyarvに色々したい。したい。したい。
Intel系のCPUのキャッシュってwrite through だっけ、write back だっけ・・・。
Celeron は through なのか。書き込み時の遅延ってメモリアクセス分だけかかるんだろうか。それだと現状のスタック操作、非常にアレだな・・・。
eclipse、依存したプロジェクトを作っておくと、そいつも開いておかないとダメらしい。なんてこった。クラスパスの参照だけお願いしたかっただけなのに。
メモリ 256MB では足りないな、全然。
DDE通信すると、Den8異様にメモリ食うな・・・。
xyzzy の changelog.l を試して見る。編集中のファイル名と時間などを、同じディレクトリの ChangeLog ファイルに自動的に挿入してくれるようだ。
深い階層構造があるような場合、ChangeLogはいくつか上の階層にあるのは珍しくないと思うんだが、どうやって対処するんだろう。emacsのはなんか違うのかな。
xyzzy の cvs-mode を(やっと)試して見る。ファイルごとの ci 以外、cvs コマンド直打ちしたほうが早いなぁ。多分。というか、キーバインディングが覚えられないので。
ChangeLog mode との連携ができると非常にいいと思うんだけど、世の中そんなに簡単にはできてないか。
cvs2cl.pl ってのは便利そうだなぁ。利用されてるのかしら。
sicp-reading ml で紹介されていた Structure and Interpretation of Computer Programs, Video Lectures。ファイルデカー。こういうのこそ winny とかで流すべきだよな。多分。
エコーキャンセラについて色々調べてしまったのだけれど、ヘッドセットを人数分用意したほうが安い、とか言われてしまった。うーむ。
http://sobalipse.sourceforge.net/japanese/pukiwiki/pukiwiki.php
パソコンに語りかける ko1。パソコンに微笑みかける ko1。誰も部屋に入ってこないのは(以下略
ローエンド製品Celeronだからってまさかwrite throughってこたあないだろう、と調べたら、どっかにMendocino(プロセスルール0.25μm)はwrite throughで、Coppermine(0.18μm)はwrite backって書いてあった。最近のP4アーキのCeleronもwrite backなんじゃないでしょうか?
「命令ディスパッチの効率化による速度向上は ?0% くらいが限界」他のオーバーヘッドがでかすぎるということですな。メソッド呼び出しがどのくらいの割合か、割と簡単に測れそうに思うのだけど。他の命令(putlocalとか)と比べて桁違いに遅かったりするんでは。
だと思います>shudoさん、maedaさん ともかく、プロファイルできる環境を作らないと。
cvs2cl.pl ってのが commit log を ChangeLog 形式にしてくれるものだとすると、 CVS のおまけに付いてくる rcs2log ならたまに使ってますね。そして commit log にろくなことが書いてないということに気付いてみると :-P
そもそも、commit って1ファイルずつしますか? 複数の変更をいっぺんにciするから、log がぐちゃぐちゃで。
プロファイルとかしなくても、単に「メソッド呼び出し1個だけ違う2つのループ」の時間を比べてみるとか…
とりあえずrdtsc でもしてみますかね。でも、yarv に何かするの、2月以降になりそう。
一まとまりの変更をまとめて commit するように心がけたいっていう感じですね. 「たい」っていうあたりに何かを感じとって頂ければ幸い :-) 現実にはついでに 直した typo の修正が混ざったり,commit し忘れてファイル一つだけ別になっ ちゃったり.
そうですよねぇ。なんとかならないものか。
opt_plusとかはいじっていないので、条件は同じはずです
c だと opt_* はコンパイル時にスキップするようにしてた気がするんだけど,どうだろう.
また日付が変わってしまった。
なんとなく、ずっとJavaJavaしてると、型いいなぁ、とか、そういう気分になってきた。大きな変更には強いよな。今更ですが。
Io を使ってるーとかいうドイツの人の話を聞く。へぇ。
Size。こんな比較があるのか。面白いなー。さすがにCLispでかいな。
The Carbone Ruby VM。知らんかった。
vmgen でやった人いるんだなぁ。うーん、多分現状では負けてそう。
compiler 作ったから(と言っても、まぁちょこっとだけど)、yarvのほうがましかな。
7倍速くなりました、って・・・。すげーなぁ。
世の中にはすでにいろいろ、RubyVMあるんだなぁ。
しまった。寝過ごした・・・。
センター試験中なので、午前中しか入れなかったらしいんだが、寝過ごした。ガーン。
頭がボケボケで何も考えられない。ので、「女の子の名前辞書」計画 を参考に、YARV の代替名を考える。
うーん。YA で R で V って、無理だな。
MYAR: Yet Another Ruvyvm Mitainamono。イマイチ。そもそも私は猫より犬のほうが好き。
RYAR: (ry。だめぽ。新撰組は面白かったんだけど。
KORYA: 怒られてる気分だ。
今日初めてノートPCにマイクが内臓ゾウされているのを知る。マイク買う必要なかったじゃん・・・。ガーン。
TIM -> 自宅(gate keeper) <-> 外 <-> 誰ぞ
どうやら、とても無理っぽそうかもしれない。OpenVPN でも通すか、やっぱり。
Linkavailable diary が移行して、見づらくなったようなきがする。そのため、日記を巡回する頻度が下がった。
これはいいことなのかもしれないなぁ。
内臓→内蔵
またいつのまにか日が替わっていた・・・。コメントを挟んだ継続行について、考えてなかったので対処。
ぐぅ、enddo キター。忘れてたのに。
Linkavailable Ruby Diary には大変お世話になりました。
さて、これからどこを見ればいいんだ。
某を聞く。教育テレビ風OP曲から、一般的な曲になった。それじゃあかんと思うんだが。
うーん、とても版権が気になる。うーん。
やばい、爆笑。なんで昼にケーキ買っていったら夜なんだ。すげえ、これスゲエ。
あー、なるほど、リングってそういう意味か。
というわけで、Ant をインストールしてみた。ANT_HOME の末尾に backslash を入れた(私はWindowsユーザ)ら、-Dant.home="directory<backslash>" class となって、Java がきちんと起動しねーでやんの。これから評価。
うーん、日記のシステム、backslash 書くと落ちるな。ダメ過ぎ。なんでだろう。
で、Ant ですが、イイですね。もっと前からつかっておけばよかった。make より、ちょっと遅い気がするのが気になるが、やってることも多いだろうからしょうがない。
static final な値の変更は、無理みたいっすね。そうか、コンパイル時に決め打ちしてしまうんだ。それは Java の思想からしてだめな気がするんだが、いいんだろうか。
Ant を起動する Makefile を作っておこうかなぁ。ファイルに変更が無い場合、Ant を起動する意味ないんだよな。テストプログラムも Ant で起動するようにしたけれど、コンパイルパスを通ると遅い。変更が無い場合でも遅い。
あと、外部プロセスとの通信が使い物にならない気がした。process arg < input > output 2> erroutput
みたいなことが出来ない。output 属性では 1> と 2> を混ぜやがってはまった。input は対応してないみたい。なので、しょうがないからシェルスクリプト一つ挟んだ。CMD じゃ動かないなぁ、これ。
Efficeon大研究 〜新しくなったCMSを徹底チェック。トランスメタがアプリケーションサーバ分野に進出? と読んだ私は CMS 素人。
Rubyの本を全然読んだことがないことに気づく。うーん。入門書薦めてって言われても、コレって言えるほど読んでないんだよな。
eclipse はリファクタリングのために使ってるような気がする。
eclipse上で Ant 使いづれーとか思ったけど、別に一緒に使う必要もなかった。
コンパイル時に決め打ちぢゃありません.宣言には初期化子を付けず,コンストラクタの中での代入まで遅らせることができます(というか,初期化しないとおこられます)
...って,static か.「static {} 」の中で初期化するまで遅らせることができます.
static final
ぃゃその,12:42:18 が final の話で,12:46:52 が static final の話なんですが... static final なフィールドは,宣言では初期化子なしで,「static{}」ブロックで初期化,というふうにすると,コンパイル時以降での変更もできなくはない,と
あー、いや。static{} で出来るのはわかるんだけど、ここでの話はそう「書ける」ってのは関係ないでっせ。
あー、ごめん。「無理みたい」ってのは、依存関係の把握について、static final な値の変更はクラス間のリンクからは(その情報が消されるので)無理みたい、ってこと。
私もそっちのCMSかと思いますた
入門なら『たのしいRuby』かなあ。プログラミング経験者ならPickaxeかRuby Way
思わず Pickaxe をぐーぐってしまいました。
で、結局やってみたけどうまくいかなかった。ガーン。
というわけで、失意のうちに帰宅。
と、帰ろうと思ったらなんとなくさくっと積み残したものが終わりそうだったんで、実装してしまえ。ということで、complex な sin とかに対応。
今度こそ帰るぞ。
RHG を眺めていたら、悩んでいたところはちょうど先月読んだところではないか・・・。やっぱり、目的をもって読まないとダメだな。あの場所では細かいところしか読めん。
パース時にわかりそうなもんだから、cref 要らんのじゃないかなぁ、とか思ってたのの反例。
class C CONST = 10 eval %q{ class CC class CCC def m p CONST end end end } end C::CC::CCC.new.m
いや、でも別にこれでも eval 時のところからパース時にわかりそうなもんか?
まだ色々と足りない。とりあえず、配列をスタック上に展開する奴とか足りない。
ブロックをがこっと置く奴も足りないかもしれない。
static stack caching をするとして、何段やるべきか考えてみる。なんとなく、現在の命令セットだと、1段か多くて2段で十分な気がする。
すぐに send で consume されてしまうから。
浮動小数点なんかはGC関係あると思いますが。
まだまだ頑張れば速くなるような気だけするので、遅いと判断するのはもうちょっと待って頂けませんか。
遅いままの可能性も十分あるけど・・・。
def nil.nil? false end p nil.nil?
うがー、8時には研究室に戻りたかったのに10時かよ。
しかし、あれだ。正直下らん話をしていたかと思えば コンパイラの話になると、やっぱスゲーなー。というか、そういう話があんまりなくてアレ。
YARV は YAML と紛らわしい。機会があれば捨てよう。
そういえば、相変わらずケーキを食わせてもらう。2個。
現状は、rubyインタプリタにべったりで、極力現状を利用しているが、それをやめたとき、更なる高速化はできるだろうか。
たとえば、定数畳み込みくらい、許してやろうと、とか、そういうことができるだろうか。
「ちょっと速くすればよさそう」(笹田調査)ので、そんなに頑張らなくてもいいのかなぁ、とか。
論文送れてなかったらしい・・・。再送するために学校に行かなくては・・・。
R:O:S - Ruby Operating System。参考になる。/. とか ruby-talk で話題になっていたやつ。想像していたのとは違ったが。
ビデオ配信な講義を見るのに一苦労。やってらんね。
ruby-talk で The LLVM Compiler Infrastructure というのを知る。すげえ命令セットちいせえ。どこまでできてるんだろう。
定数の定義と取得に4命令もあるのは気に食わない。rubyには2つあるけど。
なら、どうするべきか。つまり、 C と ::C を区別できないといけない。
{set|get}constant(ID id)(VALUE klass) にまとめたとき、klass の扱いが問題か。
klass が Qnil なら ::C、klass が Qfalse だったら C で・・・。うーん、微妙だけど、これでいっかぁ。
クラス変数は、クラスインスタンスのインスタンス変数ってわけにはいかないのかな。いかないんだろうなぁ。難しいことはよくわかりません。
で、{set|get}dynamic と {set|get}local ですが。
うーん、どうなんだろうなぁ。まさにデザインの肝ですよね、きっと。
BLAST というののスクリーンショットを見る。へー。おもしれ。
暴君ハバネロたんっていうのが大人気なんですね。食べたことないですが。URLはあまりにアレなんで貼らない。
実は ChangeLog は苦手で取っていない。その時点で駄目駄目なんだが。きちんと取ってる人は、emacs の ChangeLog モード(だっけ?)とかを利用してるんだろうか。なんとなく手書きでやるのは嫌だなぁ、と思って書いてないんだけど。
g77 しかちゃんとした fortran 環境が無いと、動作検証するときに困るな。
文字連結の関数・・・。うへ、配列を要求しますか、あなたは。
そこで、「ロケットの夏」とか送ったらどうなるんだろう。驚くだろうなぁ(爆)。
いや、楽しかったんだけどね。まさにあそこの夏の作品。
ということを考えた人は、3人くらいいるに違いない。
g77 では
subroutine subr2(str1, str2) character*(*) str1, str2 print *, str1 // str2 end
をはねた。これは仕様か。
subroutine subr2(str1, str2) character*(*) str1, str2, str*(100) str = str1 // str2 # OK! print *, str1 // str2 # NG! end
いや、気持ちはわかるんだけど、仕様的にどうなんだろうな。仕様にはとくに書いてない気がする。うーん。とりあえずはねるか。
というわけで、文字列の concat 終わり。
っと、代入時に特殊化して、本当に終わりっと。
class C def self.get @cv end def getcv @@rcv end def getcv2 self.instance_eval{p self; @cv} end @@rcv = 'real class variable' end C.instance_eval{ @cv = 'uso cv' } class C1 < C end p C.new.getcv p C1.new.getcv p C.new.getcv2 p C1.new.getcv2 p C.get p C1.get #=> "real class variable" "real class variable" #<C:0x2ab7348> nil #<C1:0x2ab7240> nil "uso cv" nil
やまださんの日記のケーキの絵を見たら激しく腹がへってきた。なので、飯を食いに帰ろう・・・。
と思って帰ろうと思ったらまだ終わってなかったことに気づく。ガーン。で、考えてたら日が変わってら。
クラス変数は、クラスインスタンスのインスタンス変数ってわけにはいかないのかな。
その構図はきれいなので個人的には好きです。ただしメタクラスが必要になるという罠が。メタクラスなしで実現する方法ってあるのかな…
クラス変数は実装レベルではまさにクラスのインスタンス変数です
ガーン。すみません、勘違いしていました。継承の関係とか。
place holder としてクラスのインスタンス変数だけど、アクセス方法が違うって感じなのかな。RHG読み返そう。
思ってしまいましたすみません<ロケットの夏
あと一人。
ええと... ISBN4-16-318020-6 を送るの?
違うと思う。
case [式] [when 式 [, 式] ... [then] 式..].. [else 式..] end case は一つの式に対する一致判定による分岐を行います。when 節で 指定された値と最初の式を評価した結果とを演算子 === を用いて比較 して、一致する場合には when 節の本体を実行します。 つまり、 case 式0 when 式1, 式2 stmt1 when 式3, 式4 stmt2 else stmt3 end は以下の if 式とほぼ等価です。 _tmp = 式0 if 式1 === _tmp or 式2 === _tmp stmt1 elsif 式3 === _tmp or 式4 === _tmp stmt2 else stmt3 end
(Ruby リファレンスマニュアルより)
ほぼ、って等価じゃないときもあるのかな?
さて、特殊ケースとして when 命令とか認めるべきか、if の等価な形に置き換えてしまうべきか。うーん。=== 呼ぶような命令を一個用意してやればいいのかなぁ。
忘れないうちに書いておこう。
どの命令セットを最適化すればいいのか、ってのは非常にアプリケーションに依存する話なのは周知のとおり。たとえば、JITコンパイラについても、それが問題になっていた。
ならば、命令セットも外から弄れるようにしたらどうだろうか。ある最適化が十分効率がいいのなら、ある程度オーバーヘッドも許容可ってことで。
というか、ダイレクトスレッデッドコードにしたってはやくなんねーことがわかったので、結局 while にしてしまう、とか。いっそ、call threading にしてしまうとか(こいつの評価は必要/重要。きちんとやらないと)。考えてはいなかったのだけど、今の調子だとあんまり遅くなさそう。それか、基本命令セットの幅を決めておき、それ以外の部分を自由に使わせるとか。
ここで必要になるインターフェースは次のとおり。
最適化する部分は、もともと外に(ruby でできるように)しようと思っていたので問題なし。
命令を追加する部分は、命令を実行する関数ポインタの登録と、その命令番号(?)の取得。その命令番号によって、その登録した最適化器の動作を変えてもらうようにすれば、複数の最適化手法が利用できますわな。
たとえば、Hoe#hue っていうメソッドをなぜかガンガン使うようなアプリケーションがあった場合、それに最適な命令列を生成するようにするとかね。(opt_hoe みたいな)メソッドキャッシュのもうちょっとがんばるやつ、みたいな。アセンブラまで手を出せれば、結構いけそうだけどな。環境/コンパイラ依存でめんどうくさそー。
基本的なのは、ある程度パラメータ化して簡単に追加できるようになる、かな? わからんけど。
マイグレーションとかのためには、基本命令セットのみのバージョンを強制すれば問題ないね。多分。富豪的だ。
うーん、しかしどっかできっと同じようなことは考えられてんだろうなぁ。
こんなもんよりも、速くしたいんなら拡張ライブラリ作れよ! って突っ込みはありそうだなぁ。
いや、まさに JIT コンパイルのインターフェースにならないかなぁ、って思うんだけど。
うーん、profiler でごにょごにょってのにも、使えたりするのかな。
OpenJIT はメソッドを置き換えてたけど、こいつは命令を置き換えるって感じで。
ぐぐったらこんなのくらいしか見つからなかった。
ソフトウェアなんだから、もっと動的にって感じで。
extensible instruction set でぐぐったら
おー、Forth だー。
うーん、デュアルスタックにするべきなのかな・・・。
おもしろそうなんだけど、よめねー。何語だ、これ。
えいやっと open/close statement 対応。
でも、err には未対応。面倒だしなぁ。うーん。
inquire 追加。地獄を見た気がするが、気にしないでおこう。
ついでに backspace/endfile/rewind 対応。てすとしてないけど、多分大丈夫なんだろう。多分、誰も使わないだろうしな(ぉ。
case expr; when ... の場合。
NODE_CASE head: expr next: 空 body: NODE_WHEN: head: NODE_ARRAY: ... body: 当たったときの処理 next: 次の NODE_WHEN: or else な奴。
NODE_CASE には nd_next はないのかな。
しかし、こりゃ大変だな・・・。
ちなみに、case ; when ... だと、いきなり NODE_WHEN が来る。これも(これこそ)大変だ。どうしよう。つまり、再起で解けない。
べたにぐるぐる回せばいいのか。
ふと気が付いたこと。
case else 1 end #=> ok case 1 else 1 end #=> syntax error
前者も syntax error のほうがいいような。
う、はじめて swap が必要になった。なーんか javavm っぽくていやだな。
2個下を複製、ってのがあると出来るが、なんかこのために加えるのは癪だ。
case V when A1, A2 bodyA when B1, B2 bodyB else bodyELSE end => put V # V dup # V V put A1 # V V A1 swap # V A1 V send :===, 1 # V T/F if bodyAStart # V dup # V V put A2 ... swap send :===, 1 if bodyAStart dup put B1 swap send :===, 1 if bodyBStart dup put B2 swap send :===, 1 if bodyBStart [bodyELSE] jump END bodyAStart: [bodyA] jump END bodyBStart: [bodyB] END:
こんな感じかな。
case/when ... の場合、send と dup/swap がなくなるのか。
とりあえず case/when に対応。swap の実体をまだ作ってないけど。
がんばって授業にきたら、休講だった。
授業の課題がかなり溜まっていることに今更気づく。うーん、どうしたものか。
ソフトウェアの信頼性、安全性についてちょっと考えて見る。
結論、眠くて頭が回らない。こんな状態でソフトウェアを作っちゃあかん。
dev に書いて見たけど、そんなのどーでもいいじゃん、という話かもしれない。うーん。
論文のごたごたの話、まだ返信がこない。うーん。
Psyco ってのは寡聞にして知りませんでした。
うーん、少なくとも 50倍にしなくちゃいけんのか・・・。うーむむ・・・。
写真をアップ、と思ったらUSBケーブルが無い。ガーン。
というわけで、python/ceval.c を見たんですが、ひっじょーに素直なインタプリタなんですね。うーむ。
YARV: Yet another RubyVM。一応ページを作った。地味。
「ほぼ」ってのは変数_tmpを導入するかどうかってことです
ありがとうございます。納得しました。
いろいろ突っ込みたい。とりあえず自動命令複合。でもErtlの例のやつはこれも含んでいると思う。
以前ご紹介いただいた、前者がラベルでネイティブコードを切り貼りする奴、後者が同じ命令を複数もたせて投機ミスを減らそうってやつですよね。rubyってそのへん頑張ってもはやくなんねーんじゃねーのかなぁ、とか、ちょっと思って、上の話。メソッドキャッシュがうまく行かない限り、何やっても無駄。なら、それをもっと推し進めるのはどうしたらいいのかな、って考えました。いや、まだわかんねっすけど。きちんとスタックに関する最適化してないから、そこがボトルネックなだけかも。
そうね。いろいろ最適化していって、最後に残る困難なとこが命令ディスパッチとか分岐予測ミスとかの話になる、ってことでしょうね。
知ってるかもしれないけど、PsycoについてのdWの記事。
しりませんでした。楽しい。
いろいろ突っ込みたいが、ちょとだけ。
swap; send :===, 1; if label; (dup)
までは、どうせ複合命令にすることになりそうね。するとswapが単独で現れることは無くなったりして。 つか、getdynamicだけじゃだめなんでしょうか。 yarvのページですが、
いつもありがとうございます。制御用スタックはなんとなく便利そうだから(あと、末尾再起)。$_/$~ はローカル変数部分に置くべきか。PCが絶対アドレス(マシンアドレス)ならbs要らないんですが、相対アドレスだとどうしても必要に。
ドイツ語です > Virtuelle Maschinen mit erweiterbarem Befehlssatz
その調子で日本語にして〜。
Wikiの文法の標準化に関するWiki。素晴らしい。こういう比較表作ろうと去年くらいにしていたんだよな。
標準化できるとは思わないが、こういう努力があるのは素晴らしい。
メタ文法が一個決まればいいんだろうけど。XMLになるのかなぁ。
メタ文法Mと、ある Wiki A があったとき、A -> M と M -> A の変換ルールさえ、各 Wiki制作者がきっちり定義してやれば、オッケーとか。
まぁ、Wiki って単純なマークアップだけじゃないけどな。目次って何さ、みたいな。
CLASS_OF(obj) を早くする方法を考えてみる。というのも、インラインキャッシュした場合、recv と method body を保存するか、CLASS_OF(recv) と method body 、どちらの対を保存するかってことになるから。
多分、CLASS_OF(recv) にしないと、なかなかヒットしない気がする。
今の実装では CLASS_OF(obj) の実態、rb_class_of(obj) は結構コストがかかる。通常のオブジェクトの場合(多分、圧倒的にこっちのほうが多いと思うが)、分岐5回くらいかかる。もちっとなんとかならないものか。
static inline VALUE rb_class_of(VALUE obj) { if(SPECIAL_CONST_P(obj)){ if (FIXNUM_P(obj)) return rb_cFixnum; if (obj == Qnil) return rb_cNilClass; if (obj == Qfalse) return rb_cFalseClass; if (obj == Qtrue) return rb_cTrueClass; if (SYMBOL_P(obj)) return rb_cSymbol; } else{ return RBASIC(obj)->klass; } }
うーん、1回。その中の演算で、SPECIAL_CONST_P の中で 1回 or がある。
分岐予測あたるだろうから、って理由で、別にここを凝らなくてもいいのかなぁ。
評価結果。
rb_class_of my_class_of my_class_of2 String 2938 1593 1828 Fixnum 1218 1953 1593 Qnil 1719 2204 2204 Qfalse 2078 2203 1953 Qtrue 2078 2578 2078 Symbol 2329 2719 2203 (ave) 2060 2208.33 1976.5 (単位は clock の返り値)
評価プログラム。
#include <ruby.h> static inline VALUE my_class_of(VALUE obj) { if(SPECIAL_CONST_P(obj)){ if (FIXNUM_P(obj)) return rb_cFixnum; if (obj == Qnil) return rb_cNilClass; if (obj == Qfalse) return rb_cFalseClass; if (obj == Qtrue) return rb_cTrueClass; if (SYMBOL_P(obj)) return rb_cSymbol; } else{ return RBASIC(obj)->klass; } } static inline VALUE my_class_of2(VALUE obj) { if(IMMEDIATE_P(obj)){ if (FIXNUM_P(obj)) return rb_cFixnum; if (obj == Qtrue) return rb_cTrueClass; if (SYMBOL_P(obj)) return rb_cSymbol; } else if(!RTEST(obj)){ if (obj == Qnil) return rb_cNilClass; if (obj == Qfalse) return rb_cFalseClass; } else{ return RBASIC(obj)->klass; } } #define MAX 0xa000000 #define TS(some) \ start = clock(); \ for(i=0;i<MAX;i++){ some; } \ printf("%8d\n", clock() - start); \ VALUE test1(VALUE self){ volatile VALUE obj = rb_str_new2(""); volatile VALUE sym = ID2SYM(rb_intern("hoe")); volatile int i, ret; clock_t start; printf("--\n"); TS(ret = rb_class_of(obj)); obj = 1; TS(ret = rb_class_of(obj)); obj = Qnil; TS(ret = rb_class_of(obj)); obj = Qfalse; TS(ret = rb_class_of(obj)); obj = Qtrue; TS(ret = rb_class_of(obj)); TS(ret = rb_class_of(sym)); return self; } VALUE test2(VALUE self){ volatile VALUE obj = rb_str_new2(""); volatile VALUE sym = ID2SYM(rb_intern("hoe")); volatile int i, ret; clock_t start; printf("--\n"); TS(ret = my_class_of(obj)); obj = 1; TS(ret = my_class_of(obj)); obj = Qnil; TS(ret = my_class_of(obj)); obj = Qfalse; TS(ret = my_class_of(obj)); obj = Qtrue; TS(ret = my_class_of(obj)); TS(ret = my_class_of(sym)); return self; } VALUE test3(VALUE self){ volatile VALUE obj = rb_str_new2(""); volatile VALUE sym = ID2SYM(rb_intern("hoe")); volatile int i, ret; clock_t start; printf("--\n"); TS(ret = my_class_of2(obj)); obj = 1; TS(ret = my_class_of2(obj)); obj = Qnil; TS(ret = my_class_of2(obj)); obj = Qfalse; TS(ret = my_class_of2(obj)); obj = Qtrue; TS(ret = my_class_of2(obj)); TS(ret = my_class_of2(sym)); return self; } void Init_test(){ test1(0); test2(0); test3(0); test1(0); test2(0); test3(0); }
やっぱり、現状はちょっと遅い気がする。my_class_of のがいいなぁ。などと呟いてみるテスト。
うーん、マシンによっちゃうかなぁ。うちのは Cel 1.4GHz だから。
「無限の暗殺者」。映画で見たいな。
あなたにとって、現在のRubyインタプリタの実行速度は。Ruby環境は「ちょっと速くすれば」実に 76% の人を幸せにできるらしい。
というわけで、グレッグ・イーガンの「祈りの海」読了。「貸金庫」も「祈りの海」もどちらも同じ構造なんですね。でも、後者のほうがよかった。前者はやっぱり短すぎる気がする。
L'eclat des joursより。スペリングのミスばっかりだよな。自分。
BitChannel。また新しいWiki文法が。
w 一文字だと、(笑)の略に見えてしまって。私はチャットで w 使うのは大嫌いなんだけど。
そういえば、YAMAHA のなんてスピーカーがいいって言ってらっしゃいましたっけ。
gcc だとまた違った。gcc3.3.1/cygwin
rb_class_of my_class_of my_class_of2 String 1516 1282 1265 Fixnum 875 1015 1000 Qnil 890 1516 1390 Qfalse 1016 1781 1391 Qtrue 1141 1906 1640 Symbol 1390 1782 1141 (ave) 1138 1547 1304.5
うーん。
よく知らんのですが、CLASS_OF(obj)をキャッシュした場合、特異メソッドを付けたオブジェクトはちゃんと別クラスの扱いになるんでしょうか?
ああ、そうか。なるほど。うーん、どうするのが効率がいいのかなぁ。
「YAMAHAの…」5.1chの話ならTSS-10です。でも「いい」じゃなくて「安い」「軽い」「その割に音もよい」と言ったんですけど。
ありがとうございます。やっぱり「安くて」「いい」って都合のいいもんは無いですか。
特異メソッドのあるオブジェクトは別クラスになりますが、逆にヒット率は下がるかも
inline cache するとき、たとえば reciever と method body を保存するが、この保存領域は 2word になる。ネイティブスレッドでズギャー、っとやってしまうと、不可分な操作にならない。ヤヴァイ。ロック入れると途端に効率が悪くなるのでやらないほうがまし。
さて、どうしたもんか。
不可分な 2 word access をがんばって考えるか、情報を 1 word に抑えるか。
前者はロック入れないとまずいよな。アーキテクチャ依存の方法を使えば数命令で出来るが、やはりロード、ストア一回入ってしまう。ちょっぴり遅い。ってのと、アーキテクチャ依存性が高まる。
後者は。。。うーん。なんかあるかな。情報へのポインタにしてもいいけど、それだとまた微妙に・・・。うーん。
3つの情報単位のリングにして2個ずつ使うようにしてまわしていく、とか・・・。更新時にはやっぱりロックが必要になるか。これはしょうがないかな。
今からそんなこと考えんなよ! って話もあるが。
ネイティブスレッド対応は、なんか微妙な気がしなくもない。dRubyでがんばってもらうほうがいいんじゃなかろうか。
学校にてたまったメールの処理。
たとえば yarv をどっかで晒して開発するとしたら、どこがいいんだろう。選択肢は sf.net / sf.jp / ruby-forge くらいか。
さて、あとは cron が正しく動いてくれれば(正しく設定できていれば)オッケー。
よし、なんとなく動いた。
SoftEther 、使って見たいけど使う環境がないので使えません。Windowsサーバをそのために用意するのは嫌だ。
はやく VPN ソフト入れたいのぅ。やろうかな、っておもってたのが OpenVPN。
そうか、別に不可分でなくてもいいんだ。2 word あったとき、先にどちらかを zero クリアする。この zero状態では、キャッシュしていない状態、ということにしておけば・・・。って、結局書き込み時に同様の問題が起こるか。書き込み時にはジャイアントロックでいいんかなぁ。
一応、yarv-0.0.0です。
色々と追加したり、減らしたり。
putnil とか命令作ってたんですが、前田さんがそんなもんいらねー、とか言ってたから外しました。いや、あとできちんと数えるため、とかね。
puttrue/false は外してもいいけど、putnil はガンガン使いそう。
ただ、 +/-/< とかの最適化は無効にしちゃってます。compiler.c の該当部分のコメントを外せば最適化してくれます。
やっぱりML作りたいな。どこがいいんだろう。
VPN 云々だけど、私 ssh-port forwarding で殆ど困ってないんだよな。唯一 samba をつなげたいって欲求だけなんだよな。cvs も pserver でつなげ放題だし。
うーん、これだけ、なんとかならないかな。
学校のネットワークが普通になった。よかったよかった。
akrさんのメールアドレスを調べようと akr でググったら(略)。
本当にこれでいいのか自信がないが、1000個の配列でもオッケーだったので、大丈夫なんだろう。
定数個のテンポラリしかない場合、どのようにローテートするか。効率のいいアルゴリズムを求めよって問題。
class Array # try def rrotate k ar = self.dup sz = ar.size k %= sz tmp = nil n = 0 k.times{|start| i = start tmp = ar[i] ar[i] = nil i = (i+k) % sz while i != start tmp2 = ar[i] ar[i] = tmp # p ar tmp = tmp2 i = (i+k) % sz n += 1 end ar[i] = tmp n += 1 #p ar if n >= sz - 1 break end } ar end # exact def rrotate_e k ar = self.dup k.times{ ar.unshift ar.pop } ar end end require 'test/unit' require 'test/unit/ui/console/testrunner' class TC < Test::Unit::TestCase size = 200 size.times{|j| j.times{|i| eval %Q( def test_rt#{j}_#{i} ar = (1..#{j}).to_a assert_equal ar.rrotate_e(#{i}), ar.rrotate(#{i}) end ) } } end
うーん、どうやって証明書こうかな。
IBMの(東京基礎研で作られた)Java JITコンパイラが コード中の2-5バイトを書き換える際にどうしているか:
Subject: Atomicity of memory accesses
http://www.egroups.co.jp/message/jvm-talk/26
って、S田くん、知ってたっけ?
一応、XCHG も LL/SC も知ってはいますが(日記中、アーキテクチャ依存の部分、というのはこれらです)、それを使わないでなんとかならないかな、と。結局ロック用にメモリアクセスが一回(一対)増えるのは、嬉しくない気がして。そもそも ruby ならSMP対応しねーぞ、というのも十分ありだと思うんだけどなぁ。ロックとかなにやら、面倒なことが色々増えそうで。(ちなみにS田って私ですか?)
スピンウェイトする命令に書き換えてしまうってのは面白いですね。
threaded codeのポインタワードの書き込みはアトミックと思ってよいんでないかなあ。ところで「先頭を、スピンウェイトする命令に書き換える」としても、「先頭はすでに読んだが、後続ワードをまだ読んでない」状態で寝ているスレッドが他にないことをどう保証するのか、昔から疑問です。
ほんとだ。どうするんだろう。こないだの PRO の論文では、強制的にPCをそのアクセス前に戻すって手法を IBM の人が言ってましたね。
今日は14時まで寝てしまった。21時には寝ていたので、17時間寝?
日記について考える。あまりに更新をちょびちょびするので、表での更新をやめたったんだけど、それも微妙かもしれない。毎日0時に cron で更新するようにしようかなぁ。
表には、一番新しい日記へのリンクを貼っておく、とか・・・?
VMのアイデアなどを話し合う場について考えてみる。ruby-dev だと、なんか ruby開発のほかの発言を邪魔してしまうようで申し訳ない気がする。
なんか ML 作るにも、どこが適当なんだろう。
newsgroupe はよく知らない。
そういえば、和田先生にSICP読書会についてお話を伺いました。さすがに二度目は、って仰ってましたが、ぜひまた来てもらいたいものです。飲み会だけでも。
resolve-replace.rb を使って逆引きが全然はやくなった。なぜー?
まつもとゆきひろの「プログラミング言語論」【前編】(1) より
さて,プログラミング言語はコンピュータ・サイエンスの総合芸術です。
うーん、総合?
ラムダ計算ABC。λ算法、λ計算、よくわかっていない。ダメダメ。うーん。
Lisp は λ計算、なのかな。よくわからないな。λ記法を応用したもの、だと思ってたんだけど、同じものなんだろうか。eager でもいいんだろうか。関係ないか。ダメだ。やっぱり理解できてない。
「総合」は私も全く賛成です。G・J・マイヤーズという人が「OS屋、言語屋、アプリのプログラマの中で、アーキテクチャの設計に一番適しているのは言語屋」と著書で書いてました。ちょっと古い本ですが。Lispは「λ計算にヒントを得て記法を借りた」くらいでしょうね。Schemeはかなりλ計算に近づいたと思います。
λ計算は計算順序を限定していません。というか、どういう順序でリダクションしても、必ず同じ形に合流できるというのがかの有名な「Church-Rosserの定理」です(ちょっと書き方がいいかげんですが)。
というのはさておき、やっぱりRuby HotLinksから辿りやすいように、トップページに日記が書かれていたほうががいいです。固定URL重要。
関係ないけど、HHKは和田先生が開発したんですよ〜。
あー、個人的にすげー辛い。
というわけで、プログラミングシンポジウムへ行ってきました。お手伝いで、前日から行ってました。予想外に疲れた。
忘れないうちに感想文。
■非意識的な操作や文章入力からのアノテーションデータ自動生成とその応用
前田さん(座長)の隣で聞いていたが、よくわからなかった。
■パスを利用したRDF問い合わせ言語の提案
何が凄いのかよくわからなかった。
■Webグループウェアにおける同期型メッセージング処理とその開発支援ツールの設計
JavaScriptで仮想push型ウェブサービス構築フレームワークの構想。できたものを見ないとなんとも。
■論理式の充足可能性問題(SAT)の分散環境での実行について
マイクもちで走り回った。
SATを速く解くための並列アルゴリズムの話だと思うんだが詳しくないんでよくわからず。
■組込みJava実行環境向け高速化方式の開発
threaded code にすると、バイトコード部分にアドレス4バイトを詰め込むことになり、(組み込みなどでは)メモリ消費量的に不利である。そこで、次の命令アドレスへの差分を格納することにより、2バイトに抑えることができた、って話。SH だと、相対ジャンプがあるから、1命令でこれも出来るね、ってこと。
まぁ、組み込み向けでは、なるほど、って感じ。
デスクトップ向けではこれが有効に働くか、というと・・・。うーん、どうなんでしょうか。たしかにサイズは小さくなるが、キャッシュ事態に命令列入りそうだしなぁ。
■オン・チップ・マルチスレッドアーキテクチャ向けシステムソフトウェア
私は共著者なのでノーコメント。いや、すみません、会場でコメントしてしまった。
■ポスターセッション
湯浅先生のデモを見逃してしまったのが痛い・・・。
前田さんと福盛さんとずっと YARV の話をしてました。
■Information Collection System Using Sensu Project Shunsuke Soeda, Rie Shigetomi, Yoshiki Hayashi, Kiminori Matsuzaki
マイクもち。
未踏のあれ。匿名+認証 を解決するにはどうするか、というためのソフトを作りました。こんなのです、という発表。原理じゃなくて、営業だけだった気がする。
あと、チャットで永遠とこのシステムの不具合をしてるのは正直言って鬱陶しかった。ほかでやって欲しい。発表について議論する場でしょう、あれは。
■書籍検索システムにおけるGUIの研究
マイクもち。
書籍検索に視覚的に本棚のメタファーを利用するのが面白いと思った。
■魚釣りメタファによる半受動情報検索システム
デモに失敗したのが痛かった。そのため、何がやりたいのかよくわかんなかった。
■鉄道における最新情報技術
マイクもち。
面白くなかった。
■人間参加型の震災対応シミュレーション
座長隣。
研究の視点がどっち(ロボカップか震災対応か)ってのがよくわからなかった。
■自動検証機能を備えたゲームシナリオ記述用開発環境
実現可能性、有用性に疑問。とても興味のある話なんですが。未踏はどうやってまとめるのかな。
■子どもの造形表現を支援する新しい「お絵かきソフト」の開発
マイクもち。
いったい何が目的なのか、ぼやけていた。面白いと思うんだけどなぁ。
■Viscuit: 柔らかい書き換えによるエンドユーザ向けアニメーション記述言語
画像によるプログラミング。自分の子のために作ったってのがすごい。10年の集大成だそうで。
■MTA でできる spam 撃退術
マイクもち。
よく聞いてなかったけど、spam 防止方法として、結局ホワイトリストを編集する、とかなんとかだったきが。
あれの返答期間によって、勝手に更新されるって意味だったのかなあ。
■SoftEther による Ethernet の仮想化とトンネリング通信
まぁ、あの話。大学一年生には思えない発表。
彼の凄いところは知識量やらテクニックやら、そういうのもさることながら、それらを利用して完成度の高いものをまとめあげることだと思う。
■主メモリ活用型ストレージシステム
よくわからなかったけど、主メモリを中心とすることで、分散ストレージがこれだけ凄いのができるんですよ、っていうことなんだろうか。
■ユーザ単位での共有ポリシを反映するファイルシステム
ひとつのマウントポイントにローカルストレージ、共有ストレージの両方をマウントできるようにしようって話。まぁ、簡単じゃないだろうけど、もうちょっと工夫が必要か。複数のファイルシステムが使えると面白いよね、やっぱり。
飲み会ですが、やっぱり知人同士で固まってるよね。人付き合いが苦手な私では、なかなかそのクラスタに入れず。一人で行ったようなものだし。結局知ってる人としか話してなかった気がする。
これは問題。
今年は若手の会とか行って、その輪を広げてみたいなあ。
ちなみに、その私が共著の発表、結構叩かれてたんだけど、その後で一っ言も聞かれなかった。まぁこんなもんか。飲み会とかではこういう話やらなんやら、したかったんだが、そういう話ははっきり言ってほとんどなかった。技術的な濃い話ができるもんだと思ってたんで、ガックシ。
RHG /SICP 読書会飲み会のほうが濃い。まぁ、あれは分野を限定してるから、それが可能ってのもあると思うんだけど。前田さんとかの話は濃かったんだけど。
新年会なら、そういうもんなんかな。
で、1時まで飲んで(片付けて)、3時半までYARVハックして、8時には起きて9時からマイクもちとかで走り回って、日記はほとんど読まないという健康的な生活をしていたので辛いのです。
あと、FGCSに投稿した論文、うけとってねー、とか言われてむちゃくちゃあせってたりする。無事受け取ってもらえるんだろうか。
からい?
つらかですよ。
個人的には、木山君と将棋が出来なかったのが残念です。
10年前にアメリカに2ヶ月ほど行ったときに最も感心したのが、彼らの自己紹介ならぬ、他己紹介のうまさでした。さすがに今回は(まだ)知り合いの数が少なくて、実践できなかったのが残念ではあります。ささださん←→たつみさんくらいだったか…
事態→自体 永遠と→延々と
前田さんに教わった高速化で素ruby より4倍くらいはやくなりました。
fib(32) ruby: 24.95 yarv/dt/no opt: 16.08 yarv/dt/opt: 7.35 yarv/no opt: 16.50 yarv/opt: 8.00
この例だと3倍か。
というわけで、眠いのですよ・・・。
putnil/true/false は、putliteral nil/true/false で代用可能である。というわけで、命令セットを減らしシンプルにするためにはこれを省いてみよう、という話。
やった最適化は単純で、+/-/< 用命令を追加したってことで。
/** a + b */ DEFINE_INSN opt_plus () (VALUE recv, VALUE obj) (val) { if(FIXNUM_P(recv) && FIXNUM_P(obj)){ /* ex: 1+1 */ long a, b, c; a = FIX2LONG(recv); b = FIX2LONG(obj); c = a + b; val = LONG2FIX(c); if (FIX2LONG(val) != c) { val = rb_big_plus(rb_int2big(a), rb_int2big(b)); } } else{ /* other */ rb_bug("unsupport + method"); } }
とりあえずこんな命令。ruby本体に NODE_OPT_PLUS みたいなものを付けても(VMなんて作らないでも)十分速くなると思うんですが、どうでしょうか。
あ、メソッド再定義のチェックをしてないですね。
if(FIXNUM_P(recv) && FIXNUM_P(obj))
は if(recv & obj & 1)|| かなぁ。
if(recv & obj & 1){ // fixnum + fixnum val = (recv + (obj & (~1))); if((~(recv^obj)&(recv^val))&0x80000000){ val = rb_big_plus(rb_int2big(INT2FIX(recv)), rb_int2big(INT2FIX(obj))); } } else{ /* other */ rb_bug("unsupport + method"); }
こんな感じですかね。
座長の横でハックしてたらベル鳴らすの一個忘れてしまった・・・。マズー。
FIX2LONG等はSHIFTが必要ですが,単にオーバフローをチェックするだけならもっと速く書けますね.
long a,b,c; c=a+b;
でオーボーフローが生じたというのは, ・ a>0かつb>0でc<0 ・ a<0かつb<0でc>=0 という場合です.この条件は,
((〜(a^b)&(a^c))&0x80000000)!=0
となります(キャストが必要かもしれません).
先日のPTTのお話を覚えていたので、できそうだよなとは思ったのですが、眠かったのでrubyのをコピペしました。
rubyのコピペですか.なるほど,シンプルでポータビリティも高そうですが,効率は悪そうですね. そもそも,
val=recv+(obj&〜1); if((〜(recv^obj)&(recv^val))&0x80000000)!=0){ ... }
でも良い気がします.また,
if(FIXNUM_P(recv) && FIXNUM_P(obj)){
も,2回比較するので,
if(((recv&obj)&1)!=0){
にしたい感じですね.
「Fixnum#+が再定義されていたら、通常のメソッド検索を行う」処理も必要ですよね。説明のために省略したのかな?
説明のためと実装してない(再定義チェック)ため省略しました。
温泉2日目。温泉と言っても、そんなに素敵な温泉があるわけではない。でもご飯はお いしい。
threaded code の実装が遅い。なんでだ。ということで、direct threaded code に変
更。前者: goto *table[insn];
、後者 goto *insn;
用語は例によって間違え
てる気がしなくもない。
で、やってみたら、遅かった。ガーン。いや、速くはなったんですよ。0.5秒くらい。 でも、13秒が12.5秒になってもあまり嬉しくない。
もちろん、マシン(CPU)について、効率的な実装って変わってくると思います。
不思議だったのが、
first: goto *insn; while(1){ case insn1: ... case insnN: goto first; //(a) goto *insn; //(b) }
(a) のほうが速くなること。もうちょっと調査が必要です。あ、全部の命令を、じゃな くてただ一つの命令を、ですけど。
こっちに書いてなかったんですが、 yarv0.0.0-。
やっとメソッドがまともに動いた・・・。
でもオソー。ショボーン。
というわけで YARV: Yet another RubyVM です。なんか、全然ですが、とりあえず。
なんか、rubyの実装をずいぶん眺めた気がする。いや、全部RHGに書いてあったはずなんだがなぁ。やっぱり本で見てるだけじゃ、身につかないな、私は。
で、今日から温泉行きなんですが、なんでこんな時間まで起きてるのかな、私は・・・。まぁそういうことなんで、4日ほど温泉。
あー、しまった。やっぱり [ANN] なものは list だったかなぁ。先に謝っときます。ごめんなさい。
YARV日記は嘘です。
というわけで行って来ます。うがー、眠い。
TOS レジスタをつけるの難しい・・・。
いや、べたに書けばできるんだろうけど、TOSレジスタなしでもできるように書こうとしたら。どうしたもんかな。
問題は、TOS が valid だったり、invalid だったりすることだな。これをきちんと制御するように各命令を書けば・・・。
空の関数を呼んでるところくらい、最適化してくれっだろー、とか思ったらしてくれねーでやんの。
そういえば、昨日、床屋に行ったらバリカンで髭を剃られた。うーん、こういうこともあるんだなぁ。無精ひげぼうぼうだったけど。
先にスタックフレームを積んでおく方法にしようと思ってたんだけど、次の理由から断念。
さて、ならば制御用フレームスタックをもう一個持ってしまおうか。
これに伴い、スタックトレース情報も色々変わるな・・・。
メソッドコールを、VMループ関数の再帰でやるか。
メリット。
デメリット。
主にスタックトレースの問題で、再帰しないようにしましょう。
・・・ほんとにいいんだろうか。
a = b = c = 1 、というのを処理するためのオペコードを考える(スタックマシン上)。まあ、1 を置くのは要るだろう。スタック上のものを変数に代入するというのも要るだろう。さて、その代入する命令の帰り値が問題になる。
* set は set した値をまた乗せる命令である put 1 set c set b set a pop * javavm っぽい put 1 dup set b set a * set は何も乗せない。dup もない。 put 1 set b get b set a
dup が一番効率がよさそうな気がするな。ほとんどの場合、こういったぶらさがりってやらないだろうしな。複合命令にする、ってのもあるが、まぁそれは除外。
簡単にコンパイルするんだったら、set X; get X; を dup; set X; って最適化かけるんだろうな。あと、put X; pop ; を除去したり。
というわけで、べたなのは、set X; get X; とコンパイルしておこう。
ruby の場合、いろんなものが値を持つのは周知のとおり。
if a b = 1 end ... #=> get a unless L1 put 1 set b get b jump L2 L1: put nil L2: pop ...
さて、この pop は削除できるか。この場合、最適解は次のとおり。
get a unless L1 put 1 set b L1:
pop へくる直前二つの命令が判らなければならない。飛び先を見るのは簡単でも、飛び元を探すのは苦労するような気がする。
こんなとき、先に、「その if の値はpopしちゃうよ」フラグをコンパイル時に渡してしまえば問題ないかもしんれない。うーん、どうなんだろうな。これをやると、次の最適化の話がえらく簡単になるような気がするな。
「popしちゃうよ」が true なのは、NODE_BLOCK の nd_next != 0 な場合。if の then、when の body なんかは、このフラグを伝播。
うーん、簡単でよさそうな気がするな。
最適化の話。
put 1 pop #=> 除去してOK! put local_var pop #=> 除去してOK! put C pop #=> 除去しちゃダメ!(エラーを発生させる可能性がある)
なんつうか、さびしいね・・・。
同様にクラス変数もダメ。$g、@i 警告のみだから、いいっかなー・・・?
こんなのもあるな。
cond = false # or false if cond def m end end m
さて、NODE_ARRAY は除去できるか、
[1,2,3] ...
なんかは除去しちゃっていいような気がする。だけど、NODE_ARRAY の中に副作用があった場合、ダメだな。
まぁ、こんなパターンなんて、滅多にあらわれなさそうだから、いっかぁ。
やってみた。
if true 400 end if false 500 end #=> 0000 puttrue 0001 unless 5 0003 jump 5 0005 putfalse 0006 unless 12 0008 putliteral 500 0010 jump 13 0012 putnil 0013 end
わはは、unless と jump しかのこってねーの。これは、後での除去対象だな・・・。
frame挿入を send 時にしたら、1割早くなった。全部で3割。
・・・3割かよ!
スタック操作を律儀にやっているから、しょうがないかもしれない。やっぱり少なくともTOSレジスタは必須か・・・。うーん。腹を決める必要があるなぁ。
うわ、GCされちゃってるよ・・・。
直った。
あかん、memset の仕様間違えとった・・・。
memset(ptr, 4, 4); #-> 想像 ptr[0] == 4 #-> 実際 ptr[0] == 0x040400404
threaded code の実験 with gcc 3.3.1 on cygwin 。
えーと、全然速くならなかった。ガックシ。
goto *table[insn]; が、やっぱり遅いんだろう。早くしたければ goto *pc; じゃないと。
さすがに2段間接だと・・・投機実行が・・・って関係ないか。
ガーン。表を更新しないんで、誰も見ないと思ったのに。
rb_gc_mark はやたらめったらつけてはいけないらしい。
ガックシ。
rb_gc_mark_locations でさくっと解決。やれやれ。
3時間くらいこれにかかりきりになってた気がする。
うーん、ruby_scope が取れない。困ったもんだ。これではトップレベルのローカル変数とかの情報が得られない。うーん。
なんとかならないかな・・・。うーん・・・。
制御スタック分けるかわけないか問題。
うーむむ。
ruby_eval_tree はとれるのに、なんで ruby_scope は取れないんだろう。
制御スタックを分けるメリット。
制御スタックを分けるデメリット。
ほかは、どっちでもかわらんか? ほんとか?
肝心なことを忘れていた。TOSレジスタみたいなものを使わない場合、値の入れ替えがリターンするときにちょっと発生。
ruby,h の MEMCOPY の順番にはまる。というか、またかって感じ。src,dst か dst, src か、ようわからん。p1, p2 じゃわかりません。
とりあえず、コンパイラ終わり。これでいいんか、って気もするが、とりあえず終わり。
おわってなかった。NODE_ARGS 忘れてた。
nd_rest ってなんだろう? んー? nd_opts になんか入ってるもんなんだろうけど。
なぜか、nd_rest は -1 しか入っていないような気がする。
やっと意味がわかった。NodeDump のほうが間違ってるな、これ。
ruby_scope 無理やりとった。
なんとなく、一段落した気がするので、終わりにしましょう。
いや、おわらない、これからが本番だった・・・。
ガーン。素なやつより遅くなった。なんてこった。
拡張ライブラリって、gprof かけられないんだろうか。-pg つけても何も出てこない。
間接参照をやめたらちょっと早くなった。・・・ちょっとか。
TOSレジスタを使うようにするのと、スレッデッドコードにするの、どっちが速くなるだろうか。
acc 問題をまた考えてみる。つまり、acc レジスタが必要かどうか。
なんとなく、学術な人は acc が嫌いって雰囲気がした。
けど、なんというか、どう考えてもあったほうが楽っぽい。うーん、どうしたもんか・・・。
つまり、「その値を捨てるかどうか」って判断が要るか要らないか、って話。
やばい、コンパイラ楽しい。
あけましておめでとうございますな看板はいつまで表示しとくべきか。とりあえず5日までつけとくか。
あり、トップレベルのローカル変数スコープってどうやって取得すんだろ・・・。
うーんー? NODE_SCOPE 無いなぁ・・・。わからぬ・・・。
def m eval 'return' p 'not through' end m
うーん。これも対応しなきゃいけんのかなぁ・・・。
うーーん。
ruby_scope に直接書いてしまうのね、こいつら。うひゃー。
あーー、なまえがー、名前がおもいつかないー。
call/invoke/send/combination/...
前田建設 ファンタジー営業部。凄いなぁ。けど、絵で書いてるのはちょっと・・・。
* メソッド定義 NODE_DEFN NODE_SCOPE NODE_BLOCK NODE_ARGS method body * 空メソッド定義 NODE_DEFN NODE_SCOPE NODE_ARGS * シングルトンメソッド定義 NODE_DEFS recv: ... NODE_SCOPE ... * クラス定義 NODE_CLASS NODE_SCOPE class body * モジュール定義 NODE_MODULE NODE_SCOPE module body
こんな感じだろうか。ほかにスコープ変わっちゃう何かってあったかな・・・。
うーー。GC で SEGV。うひー。
うーー、例外処理を考えると、やっぱり全部 ruby 書き直し! が必要な気がする。拡張ライブラリ作者にやさしい現状、これを壊すのはきっとダメ。青木さんなんかは、「いまさらもっと速く動かす意味あんの?」という話だったが、利便性を犠牲に高速化、は無意味だろうな。
さーて、どうしたもんか。
やっぱり、アンテナに更新されないと、アクセス全然ないな。へへへ。
せめて gdb の使える環境でやってればよかった、と思う最近・・・。
なんか、Cのマクロ大好きっ子になってる気がするな。これくらい関数化しろよって感じのまで。
なぜか、*nantoka* っていうので、*nantoka と書いてしまう。
腹が減る・・・。
scheme 、というか Lisp って記号処理用なんだなぁ、と今更ながらに実感。
というわけで、帰ろう。
のりつぐさんの pdf-writer/日本語化が凄い。あとで見ておこう。
なぜか cvs に詳しくなる。
というわけで、明けました。ことしもよろしくおねがいします。
さて、新年なんで抱負など。
とくに最後のは無理そうだな。
そういえば去年の目標は... できたのもあったし、できなかったのもあったなぁ。
今年も、今年は、今年こそは、がんばろー。
初ruby。
$ ruby -rmathn -e 'p 2004.prime_division' [[2, 2], [3, 1], [167, 1]]
うーん、微妙。もっと割り切れるかと思った。
ありぃ? 1.9 から、DESTDIR ってのが余計になったのか。なんか変なところに入ってあせった。
ガーン、raise ってばメソッド。
class Object def raise end end raise #=> しかし何もおこらなかった。
ガーン。
C <-> Bytecode Interpreter でのエラーのやり取りって、どう考えても遅いから、NODE_RAISE が欲しい。
Kernel#raise にしている強い動機ってなんだろう。
フロー解析がどれだけ静的にできるか、とかもあるよなぁ。うーん。
for i in [1,2,3] p i end p i [1,2,3].each{|j| p j } p j
うーん。まぁ、これはどうにでもやりようはあるか。
1.9 で rough/ext/NodeDump で ruby extconf.rb で失敗(こんなバージョン、面倒ミキレネーヨ! ってエラー)するので、無理やり通した。とりあえず使えてる。全部が全部見えるわけじゃないんだろうけど。
class C def m mm{ p 'in block' return } p 'not reached' end def mm begin yield ensure p 'ensure' end p 'not reached' end end C.new.m #=> "block" "ensure"
律儀なものである。
おみくじ。大吉。誠を通せ、と書いてあった。通しましょう。
ユニクロの福袋。年に一度の衣料品購入。結構つまってた。
グハ。ファイル消えた。正月からついてないなー・・・。
うう、コンパイラが頭痛の種だな・・・。
factor というコマンドは知りませんでした。へぇ。
いや、トリビアの泉を見てたもんで。ばかだなー。楽しい。
うー、コンパイラウザ。
raiseを再定義できる (Window#raiseとか) 昔は予約語と同名のメソッドは定義できなかったし
おつかれさまー>しゅうろん
ありがとうございます.