人が X を使うのをやめる時。
このところ、ひたすらカーネルをコンパイルしてるような気がする。1日4回くらい。
そしたら、カーネルコンパイルに襲われる夢を見た。意味わからんけど。
で、コンパイルしてる間、バックグラウンドで作業しようと思うんだけど、 どうも、スワップが生じまくって、まともに作業できない。「まあ、32Mじゃ仕方ないか…」 と思ったんだけど、なんとなく、emacs と X を終了させてコンパイルしたところ、 gccが使うメモリ量は10-15MBくらい(topによる)、カーネルが使うメモリがキャッシュとかバッファとか入れて 15-20MBくらい… ぎりぎりスワップ生じるか生じないかの くらいで動かせるらしいことが発覚。
これは、どうしたものか。余っているメモリ量もまた微妙だ。shell + vi + etc. とかだったら数MBあれば 十分。けど、emacsを動かすわけにはいかない… ちょうど emacs 止めたいと思ってたところだし… しばらくこの環境で試すのもいいかもしれない。
メモリ増やすのがいい、という意見もあるかもしれない。けど、なんていうか、 ギリギリメモリ一杯使ってるというのはなかなか快感ものだ。 貧乏症の僕にとって512MBあるうちの150MBしか使ってないというのは耐えられないものがある。 けど、32MBメモリがあって、自分の工夫で32MBギリギリ使ってる状況っていうのは top起動させて見てるだけで至福の瞬間だ。
こういう小さな楽しみは Windows とかでは得ることはできない。 だから、僕はずっと Linux 使ってると思う。
ゲームしてるわけでも本読んでるわけでもテレビ見てるわけでも 授業真面目に受けてるわけでもないのに、一日が終わる… なんか最近一日が縮んでるような気がする。
RTTIは必要か。
僕はいらないと思ってる。RTTI。なぜなら、記憶に残るほど使ったことが無いから。
それでも各種言語でなんらかの形で実装されてるのは RTTI が無いと不可能なことが存在するからなんだろうか。よくわからん。
そもそも言語仕様にしなくとも、RTTIみたいなのを書くことは十分可能だ。
enum CLASS_ID { ID_FOO, ID_BAR, }; struct nanika { enum CLASS_ID id; .... };
けど、この方法だと、IDが衝突しないことは保証されないから、 そのへんをなんとかするために言語仕様になるわけなんだろうとは 思うんだけど、全然関係無い class foo と class hoge の ID が同じにならないことを保証する必要はあるんだろうか。
あと、ID を仮想関数テーブルに入れておくことによって、 オブジェクトを小さくできるっていうのもある。
enum を使った場合だと、各オブジェクトがvtableへのポインタと ID を 持つことになるんだけど、言語がRTTI実装してたら、それが vtableへのポインタだけで済むようになる。この利点は IDが衝突するとかしないとかの利点よりも大きいのかもしれない。 数バイトのオブジェクトを何千、何万と 作る場合これの影響はそれなりにある。ただ、小さなオブジェクトがvtableとかRTTIとか 必要とする場面がどのくらいあるのかはわからないけど。
多分、RTTIは実装したところで得られるものも少ないけど、 失うものも少ないから実装されてんだと思う。 クラス一個につき、数十バイト。クラス百個作っても、 数KB。ランタイムライブラリもそんなに大きくないと思う。 dynamic_cast のCPUオーバーヘッドは若干大きいと思うけど、 そんなに問題になるほどでもないと思うし。
ていうわけで、 RTTIは実装されててもされてなくてもなんとでもなるもののような気がした。
コメント付けられるようにしたのはいいけど、ログ化するのが面倒だ…
右上。「逃げるわにには」→「逃げるわけには」
あと、アリナミンVの間違い。
GNU Screenを使わない
まず、事の発端は昨日だ。昨日なんとなく、UNIX USERを買いに行こうと思って、本屋 行ったはいいけど、8日発売だったので、12月分しか置いてなかった。 で、仕方無いので、それ読んでたら、次回は screen についてとか書いてあって、 ちょうど、「あーそういえば、vi使ってたら screen は便利かもしれない」 と思ってたところだったので、「こりゃ丁度いい」と思って、 今日はUNIX USERを買いに行った次第。
で、適当にLinux magazineとか立ち読みして、「あー今週のガベコレはおもろい」とか 思ったんだけど、Linux magazineはガベコレ以外読まんので、その辺で読み終えて、 UNIX USER買おうと思ったんだけど、ちょっと読んでみたら、他の記事があんまり 興味わかなかったので、「あー、もうやっぱいいや、はやくGCC プログラミング工房単行本 出ないかなぁ…」とか思って、やっぱり買うのを止めた。 UNIX USERは毎回買おうと思うんだけど、最初の特集が僕の興味無い話ばっかなので、 結局いつも買わない。あと、「GCC プログラミング工房」は GCC と銘打っておきながら、 DOS上からキーボードとかCRTとかのコントローラのレジスタ叩いたりとかする非常に楽しい話満載なので、 是非とも読んでみるべきだと思う。(参考: Wataru's memo(著者西田氏のサイト))
で、結局何も買わないで、本屋うろついてたら、「もえたん」発見。 「あー、実物見るの始めてだな…」とか思って、少し見てみたらやたら面白かって、 「こりゃあかん、まじおもろい」とか思って、衝動買いしそうになったんだけど、 あんまりそういう本を家に持って帰ったりすると姉から変態ロリコン扱いされるので、 やっぱ買って帰るわけにもいかず、「あー、記憶するのはインパクトが大事だから、 こういうのんだったら覚えやすいかもしれないし、覚えにくいかもしれない」とか 適当に結論を出して、家に帰った。最近ワンダースワンを380円で発見したので、なんか買いそう。 GUNPEYが100円。あわせても480円。
まあ、クリスなんとかは25日でスパッと終わるけど、正月はだらだら1月中 続いてるようなものなので、公平といえば公平なんだけど。
ああ、そういえば、昼食をグリーンシティーでクリスマスの残りものの試食で 過ごした日もあったなぁ…2年前の26日か…
--
やっぱタテハよりもアゲハのほうがいいのか…でもクリア時スコアは一緒だったんだよな… でもアゲハは慣れてないわけで、そういうの考えたらやっぱアゲハのほうがいいかもしれない。 ノーミスだったら4000万いけんだけど。ラスボスで4回やられた。なんじゃそりゃ。
#! /usr/bin/perl -w srand (time ^ $$); print "Content-Type: text/html; charset=EUC-JP\r\n\r\n"; print "<html><head><title>カレー占い</title></head><body><p>\n"; sub getr { if ( (rand 2)<1 ) { return "カレー"; } else { return "うんこ"; } } print getr . "味の" .getr; print "</p></body></html>";
聖霊石10個とかで弾消しする技術が無いんだったら、 ラスボスは赤弾でやったほうが稼げることに気付いた。 どうせ、クリア時金塊殆ど残らないんだからオートバリア出ても殆ど問題無いし。 むしろ早く倒せてミスが減るからいいかもしれない。4000万はいけるはず。
--
なんていうか、まあ、もう全部どうでもいいから、ずーっとゲームしてたいなぁ… っていう現実逃避駄目人間に近付いてるような気がする。 さすがにそういうのになっては駄目だとは思うんだけど、 なんかなぁ…
「火星探査機"のぞみ"は220億円をドブに捨てた」とか思ってた人(僕も含む)は これ を読むといいらしいです。
--
JavaScript でHTML弄るっていうのは結構良い感じだと思う. 送信するのは生データだけにして、文書構造とかは JavaScript で 作ったりするのだ。利点はあるかどうかは知らないけど。 まあ、なんとなく楽しそうな気がする。
けど、そういうのは JavaScript を disable しちゃってる人が存在するっていう 究極の問題があって、実用には問題がある。JavaScript有とり無しの両方を 管理するのは個人には少し厳しい。
と、いうわけで、JavaScriptで何かやってるサイトっていうのは殆ど見かけない。 別にどうでもいいんだけど。
--
過去ログに移す時、手動でやってる部分が多過ぎる…。 システム一新とかするかなぁ… でも、月一回だから、やっぱいいかと思ってしまう。
立派な人は実在する。
昨日は11時くらいに寝てしまった。
歯を磨かずに寝たので、なんとなく虫歯が気になって適当にググったら、 歯磨きの話 を見つけた。色々役立ちそうなこと書いてあるので、読んでみるのがいいと思う。 あと、これ書いてるほんだ歯科は 東大阪市なのか。わほーい(市民なので…)。歯ブラシのブラシの部分シェアNo.1も東大阪なようで。 そういえば、そんな話ほんわかテレビでやってたような。 あと、ほんだ歯科のサイト、恐しいコンテンツ量だな…さらに、 インターネットの歯医者さんっていうのがあって、これの管理してる人の名前が「本田俊一」ってなってて、 ほんだ歯科の院長っぽいんだけど、個人で歯科医やってて、これだけコンテンツ作ったりしたら作業量って とんでもないんじゃないだろうか。掲示板もレス付けてるし…専門的な話ばっかになるから、 他人に頼んでるわけでもないだろうし…あー、口臭の権威とかって書いてあるっていうことは、 論文書いたりとかも凄い量なんだろうな…どういう人なんだろう…
--
ガルーダ、ラスボス最終形態で3650万。クリアボーナス最低でも400万(箱50万x6+ライフ100万x1) 入るわけだから、4000万はいけるはず…ラスボス倒せなかったんだけど…
あのゲーム、スタッフロール最初にプログラマがでてくるんだよな…珍しい。
--
JavaアプレットはJavaScriptよりも酷い立場にあるのかもしれない。 その起動の遅さからある意味邪魔物扱いである。
そのせいで、Javaアプレットはコンテンツとかデザインの一部にはなれずに、 単体のコンテンツとしてしか働かなくなってしまった。
さらに、起動が早くかつ製作も簡単なFlashとカバーしてる領域が重なってて、 なんか出番は皆無になってしまった。
まあ、僕には全然関係無い話なんだけど。 あと、やっぱviよりもemacs使うことにした。 なんていうか、使いにくいとかじゃなくて、なんかプログラム書いてても 楽しくないような感じがしたので。
おいおい
4000万いった。4100万くらいだったような。今のパターンもうちょっと詰めて ノーミスだったら5000万いけるか?いけないか?
--
GCCフロントエンドを書く、書けない
適当に中間コード生成して出来上がり…のはずが、 全然そんなうまくいかなくて、わからないことだらけだ。
中間コードがかなり抽象的なものになってて、 それを表現する為に知っておかないといけないことが多過ぎる。 まあ、強力な最適化を行う為には仕方ないことだと思うけど。
とりあえず、
まず、GCCのソース読んでて、何なのか全然わからないのが GTY(()) という謎のマクロだ。 大量に存在するんだけど、何かにdefineされているわけでも無い。
これ、GCC internalに Type Information とかっていうふうに型情報って書いてあるんだけど、型情報というよりも、GCC内で使ってる ガーベジコレクタの為の情報といった感じで、これをうまく書いておくと、GC が効率良く使えて 便利。という代物だ。gengtype というプログラム(gengtype*.c 参照)が C ソース中の構造体と GTY(())マクロを理解してGC用のCソースを生成してるのである。
まあ、要するにソース読むだけならGTY(())は全部無視して構わないということだ。
続いて、GCCのソースの特徴に、やたらマクロが存在する。というのがある。 適当にGCCからソース引っこ抜いてきても、
c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE); TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE); TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0); TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node; TYPE_PRECISION (c_bool_type_node) = 1; pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"), c_bool_type_node));
こんな感じで、とにかくマクロが目に付く。
こういう場合、マクロは大体tree.hで定義されてあんだけど、眠いので続きは次回。
ケツイうまい人初めて見た。2-3ボスまで行ってた。 いや、僕も2-3ボスまで行ったことあるけど、パターンの綺麗さとか。 2-3ボスはなんか、最初のウネウネってしてるの見て笑うしかなくなったような記憶がある。
なんか眠い。あと、全然関係無いけど学校行くまでの道に ふくちぁん が4軒もある。
--
GCCのソース片手に読んでください。あと、あんまGCCとか興味無い人は読んでもつまらないと思う。
GCCのソースの中でとにかく頻繁に表われるのがtree型変数だ。 中間コードとかrtlとかは全部tree型で表現されている。 つまり、tree型がなんなのか理解しないと、他のソースは何やってるか 殆どわからないのである。
まず、config.h(無い場合はconfigureを実行)に
union tree_node; typedef union tree_node *tree;
っていうのがあって、それから、tree.hに
union tree_node GTY ((ptr_alias (union lang_tree_node), desc ("tree_node_structure (&%h)"))) { struct tree_common GTY ((tag ("TS_COMMON"))) common; struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst; struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst; struct tree_vector GTY ((tag ("TS_VECTOR"))) vector; struct tree_string GTY ((tag ("TS_STRING"))) string; struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex; struct tree_identifier GTY ((tag ("TS_IDENTIFIER"))) identifier; struct tree_decl GTY ((tag ("TS_DECL"))) decl; struct tree_type GTY ((tag ("TS_TYPE"))) type; struct tree_list GTY ((tag ("TS_LIST"))) list; struct tree_vec GTY ((tag ("TS_VEC"))) vec; struct tree_exp GTY ((tag ("TS_EXP"))) exp; struct tree_block GTY ((tag ("TS_BLOCK"))) block; };
ていうのが書いてある。Cではよく見るコードだろう。GTYは今は無視して、
union tree_node { struct tree_common common; struct tree_int_cst int_cst; struct tree_real_cst real_cst; struct tree_vector vector; struct tree_string string; struct tree_complex complex; struct tree_identifier identifier; struct tree_decl decl; struct tree_type type; struct tree_list list; struct tree_vec vec; struct tree_exp exp; struct tree_block block; };
こんなん。で、ここでまず重要なのはtree_commonの存在である。 少しtree.hを読んでみればわかるが、struct tree_int_cst 、 struct tree_real_cst 及びその他の物全て struct tree_* 構造体はその先頭に struct tree_common common を持っているのである。だから、tree型変数 hoge の実際の型なんで あったとしても、hoge->common は常に存在するわけだ。
で、tree_commonは
struct tree_common { tree chain; tree type; ENUM_BITFIELD(tree_code) code : 8; unsigned side_effects_flag : 1; unsigned constant_flag : 1; unsigned addressable_flag : 1; ... (フラグがいっぱい) unsigned unused_1 : 1; };
こんな感じになっている。で、この中で最もよく使うのが code だろう。 code はその tree が実際は何の木なのかを示すものである。 tree が整数定数を表わす木だったら、code は INTEGER_CST になるし、 加算の式だったら、code は PLUS_EXPR になる。
このcodeの定義がどうなってるかっていうのは、tree.defとその トリックを理解しないといけないんだけど、まあ、その辺の話はまた気が向いた時に。 とにかく、このcodeを使って、
switch ( t->common.code ) { case INTEGER_CST: ... // 整数定数の処理 break; case REAL_CST: ... // 実数定数の処理 break; }
ていうふうになる… けど、tree code を参照するのはTREE_CODE っていうマクロが用意されてるので、
switch ( TREE_CODE(t) ) { case INTEGER_CST: ... // 整数定数の処理 break; case REAL_CST: ... // 実数定数の処理 break; }
こっちのほうがいいだろう。 とにかく、「treeは大事だよ〜」という話だ。続く。
U.S.A.はさすがに卑怯か。思ったよりも難しくならなかった…
皆考えたと思うけど、 かな文字が50文字だとして、50^5=312500000。 20年は630720000秒。630720000/312500000 = 2.018304。 妥当な数字か?濁点とか入れると厳しい。 別にいいけど。
4500万いった。1ミスでこれだけなので、5000万は厳しいかも。 +100万くらいは大丈夫と思うけど+400万は厳しい…
エスプガルーダの人のプレイを見て、なんとなく 「僕の手を出せる領域じゃない」 とか思った。スコアラー向けゲームはやるもんじゃない。 ガルーダやめてケツイか大往生かALLしよう…生きてるうちに。
色々めげそう。寝すぎ。ゲーム屋行ってゲーム見てたら 3Dアクション系と3Dレース系はどれも同じゲームに見えてくる。 あー、でもシューティングやらん人から見たらシューティングなんて全部 同じに見えるのかもしれない。
"Portable JAVA Guide"みたいな感じのがあればいいけど。 JREがバージョンいっぱいあるのと、MSのVMのバージョンが古いとかいう問題とか、 そういうのをなんか、こう。
とりあえず、MSのVMで動作確認しとけば大丈夫だとは思うけど。
getWidth()直したけど、なんかクラスファイルが見つからんとか言われた。 SunのVMではIEでも正しく動いてました。教えて、ゲイツさん。
ゲーム、というか、ガンパレにはまって無駄に時間を過ごす、というか、他に何もしてない。 漫画買いに行ったけど。色々終わってる。 そんなに暇じゃないのに。困った。
げんしけん3巻読んでて、「僕の周りって語り出す人って少ないなぁ。」 とか思った。高専って若干特殊かもしれない(大阪だけかもしれないけど)。 オタは多いけど、漫研の類いは存在しない。
--
「次回へ続く」って書いてあるけど続いてない話は書く気が失せているので 続く可能性は低いです。
--
ガベージコレクタ、という読み方が主流らしい
僕はずっとガーベジって読んでたんだけど。
DのGCの話 を読んだときに気になってたことがあって、 昨日は寝るとき睡眠薬代わりにGCの本を読んでた。
気になってたこと、というのは、「GCしたほうが高速」という話の部分だ。 でも、本読んでても、僕が求める答えは書いてなかった。 以下、それに付随して考えたこととか。今日一日考えただけなんで間違いもあるかと。
まず、GCの効率の根本的な問題にアロケータがある。 GCを使えば、アロケータのアルゴリズムが固定されてしまうことになる。
デフォルトのアロケータが非常に効率が悪い、というのは有名な話だと思う。 まあ、メモリの使用量を抑えつつ、断片化もしないで、 アロケートされるオブジェクトの大きさも変えないといけないとなると、速度が 犠牲になるのは仕方ないんだけど。 とりあえず、GCを使えば、その効率の悪いデフォルトアロケータを使う以外方法が無くなるのである。 これはGCのアルゴリズムの種類とかそういう問題ではない。 GCを使用するならば避けられない問題だ。
次に、本当に世代別GCはそんなにも効率がいいのか、という問題もある。 まず、参照の問題だ。複雑なアルゴリズムのGCは 参照先が移動するかもしれない問題から2回参照を行う必要がでてくる。
C的に書くと、常に "**p" て書いてるような感じ。 これ、一回のオーバーヘッドは小さいんだけど、参照を行う度に かかってくるので、回数も尋常じゃなくなってくる。キャッシュも倍使う。
まあ、この2重参照の方法(正式名称は知らん)を使えば、コンパクション(断片化を無くすやつね) 可能になるんだけど、殆どのオブジェクトは寿命が短いことを考えれば 生きているオブジェクトがコンパクションされる意義っていうのは少ないように感じる。
あと、メモリ使用量っていうのも気になる。 ただの Mark & Sweep だったらオブジェクト一個につき 1bit。 でも、世代別 だったらハンドル一個分、多分ポインタ32bit + 世代データ 少々。で、アラインメント入って、 64bit は使うだろう。64倍。これは少ないか、多いか。
まあ、要するに 「GCした方が速いしバグも減る」 なんていう夢のような話は ありえないんじゃないか。って思っただけ。あと、GCの効率が問題になる状況なんて 限られてくるし、まあ、つまるところどうでもいんだと思う。
Dはカスタムアロケータ使えるようになってるし、GCの挙動もそれなりに制御できるし、 全然問題無いかもしれない。あと、グラフ構造とか出てきて死ぬ程メモリ管理が複雑に なった時はGCあったほうが効率良いっていうのは考えられるかもしれない。 僕はこんがらがったグラフ構造なんて使ったことないからわからんけど。
あー、なんか大往生もケツイもエスプも駄目だ。 ケツイstage2もクリアできねぇ。 ガンパレなんてゲームやってるからだ。やっぱ、勘とかは すぐ駄目になる。あと、すぐ隣で子供に見られてて緊張した。 ずっとギャラリーいないところで練習してるから、見られてると 緊張しすぎ。前はなんか汗出まくって指滑らせて死んだし。 あー、善行司令に弁当もらって幸福状態になってやる。
ガーベージかガーベジかガベージか迷って結局、全部GCと書く。 でもGCって書くと画像弄るときのGCと区別が付かないので困る。 Garbage Collection か Garbage Collector かわからんようになるっていうのもあるし。
あと、UMLとかXPとか。
--
まねーじどぽいんた
で、GCの存在を前提とした言語になったらそれ相応に効率が犠牲に なってしまうわけだ。それはまあ、トレードオフだから仕方ない。
でも、効率を求める言語であったとしても GC の存在を全く無視して いいものだろうか。
GCがある局面で非常に役立つことはわざわざ説明するまでもないだろう。 で、そういうときに、OS/ハードウェアとかコンパイラのサポートとか無しだと 効率を上げるのが厳しくなってくるのである。
例えば C のような言語で GC を使おうと思ったら、Boehm GCのように、保守的な (conservative)GCになってしまうことが避けられなくなる。 (保守的なGCはBoehm GCを使おうの「Boehm GCの原理」 に少しだけ書いてある。日本語の良い資料が無い…) 保守的GCになれば、効率は悪くなってしまう。 あと、生ポインタを使う限り単純なMark&Sweep以外のアルゴリズムを使うのが難しくなってしまう、というのもある。
だから、効率を求める言語だったとしても、それなりにGCのことを考慮するのは有りなんじゃないかと思う。 例えば、RTTIにどのメンバが参照になりうるか、みたいな情報を載せとくとか。
それで、managed pointer みたいなのがあったらどうだろうか。という話だ。
void func() { Nanika *n1 = new Nanika(); Nanika +n2 = managed_new Nanika(); // + はmanaged pointer型を示す ... delete n1; // n1 は delete しないといけない。 // n2 は delete しなくてもいい }
こんな感じ。 managed pointerはJavaの参照みたいな感じで、何かオブジェクト以外にはNULLを指すことしか許されてない。 それと、そこのスコープに入った時に、GC の root に追加されて、 スコープから抜けるときに root から削除されるみたいな感じ、C++のクラス風に書くと、
templateclass managed_pointer { T *raw_p_; managed_pointer( T *p = NULL ) { raw_p_ = p; GC::add_root(this); } ~managed_pointer( ) { GC::remove_root(this); } };
こんな感じ。ただ、C++で書くのとは違って、それぞれの型にはGC用の型情報も含まれているので、 保守的GCにならなくて済む。 さらに、参照するときに生ポインタ参照とコンパイラが区別できるので、Copy GCとかその気になればincremental GCに してしまうことだって可能だろう。 まあ、配列どーすんねん、とか、スレッドどーすんねん、とか、ややこしい話は色々あるんだけど。
あと、生ポインタだけを使えばGCなんか全く無視したプログラムにすることも可能にするとか そういうふうなのがあれば、僕は満足だ。
from 昨日のコメント
いわゆるスマートポインタでいい気がする
スマートポインタ、参照カウントは循環参照の問題とかでどんな状況でも使えるわけでは無いので、 言語の機能の一部として実装するのはちょっとよろしくない、というのと、 参照カウントはコンパイラのサポート無しで実装してもあんまり問題無い(多分)ので、 ライブラリで実装したらいい、というような感じで。
スマートポインタで済むんだったらスマートポインタでやったらいいけど、 そうじゃない時は別のアルゴリズムを使う必要があって、で、Mark&Sweepする時とかは やっぱコンパイラサポートがあったほうがええよねぇ。ていう話。
あと、GC付き言語が明示的解放手段を持たないのは、GCのポリシー的によろしくないからだとか そんな話を聞いたことがあるような。「GCはどんな時でも利用者の気付かない所で動作しないといけない。」 とかそんな感じで。実装が難しいという話は聞いたこと無い。
適当
最近、html-helper-mode起動中たまにSegfaultする。
ジオシティーズのメールは終了したらしいので、cpajk121@hct.zaq.ne.jpか mori_oto@hotmail.com使ってください。Aboutも修正。
お、なんか今見てるテレビがおもろいのでそっち見る