この日記の URL がネットランナーに載るらしい。 どうせみこみこの影響だろうなあ。 あんな一過性のもので判断するとは、甘いぜネトラン。
うぷぷ、ここぞとばかりに Alpha とか Haskell とか Ruby の内部構造とかの 濃いネタばっかり載せてみようっと。
net/smtp, pop を大改造してみた。
今度は HDD を買ってきた。Seagate の ST36530W (UltraWide)。 ASt500 は SCSI-2 だけどそれは忘れておくことにする。
何事もなく動いた。互換性があるってすばらしい。
ま、どうせ無駄だろうなーとか思いつつ useradd --help と打ってみた。 やっぱり無駄だったんだけどそれはいいとして、 パスワードデータベースのロックをかけたまま exit してくれたもんだから useradd できなくなってしまった。困った。 エラーメッセージを Google すると、 同じことをして困ってる人が一人。 次に NetBSD のソースコードの CVSweb が数ページ。終わり。
どうしろと…… (泣)
結局ソースコードを読むことにした。 usr.sbin/user/user.c → lib/libutil/passwd.c → include/pwd.h とたどって _PATH_MASTERPASSWD_LOCK が目的のブツと判明。 この /etc/ptmp を消せばいいのかな? お、直ったよ。
http://pc.2ch.net/test/read.cgi/network/1044631609/
1 気がつくと、相手の反応を見ずに、喋りまくってるボク。 相手が呆れて、初めて気付く。 9 UDP→TCP昇格のコツを教えてください 10 >>9 >UDP→TCP昇格のコツを教えてください まずは握手から。礼儀を覚えなあかんです。
読書会の前に ruby の最新版をコンパイルしとこうと思って make したら OS を道連れに DOS 窓があぼーん。 しかたないので Cygwin をアップデートして、も一回 make。
ううう、何十分かかってんだよ。 今回こそ余裕をもって到着するはずだったのにぃ!
■ たむら [藁た。ICMPの扱いはどうなんでしょう?]
■
nori [あおきさんに聞きたいことがあるんですがいいでしょうか?
それは、Linux Assembly Language Programming
という本を読んだ感想はどうでしょうか?
6月中のあおき日記に買ってきたーって書いてあったので感想とかを聞きたいのですが、この本の英語は難しいのでしょうか?英語の本を直接読むのははじめてのことでして。
いい感じの本だったら夏休みの課題図書(自分の中で)にしようかなと思っています。
こういうツッコミはなしですか?
ではでは m(__)m]
■ nobu_toyofuku [RHG読書会夜の部で今まで見たことのないエラーが出たrubyプログラムってなんでしたっけ。]
■
nobu_toyofuku [切符問題プログラムできますた。
http://www.geocities.co.jp/SiliconValley-Oakland/4477/misc/]
■ ささだ [Kernel で super するやつだったかと。]
すでに一昨日のことですが、RHG 読書会の一巡目が終了しました。 お疲れさまでした。この後どうなるかはまだ決まってないのですが、 とりあえず次は 8/30 ってことになってます。 LL saturday に来る人も多いようなので、 そのあたりで何か決まるかもしれません。
しかし、前も書きましたが、まさか読書会まで始まるとは思いませんでした。 途中で次々と新たな間違いが発見されるという悲惨な場面もありましたが、 非常に楽しかったです。読書会を運営してくださった高橋さんと、 毎回面倒を見てくださった山下さん、参加してくださった皆さんに感謝します。
あとはここまでのフィードバックをもとにウェブ版の修正をなんとか…… しないとねえ……いや、ほんとに……。
そういえば、原稿を CVS で公開してみんなで編集、という話がありましたが、 これはさすがにぼくの一存では決められないので出版社に交渉してみます。
ちなみに「Rite 出たら第二版」「1.8 出たら第二版」「どうでもいいから第二版」 などなどいろいろな意見を伺っておりますが、この機会にはっきり言っておきます!
第二版どころか第二刷も出せるのか怪しすぎ。
つーか、いったい何部売れてるのかなあ。 ついでに聞いてみよっと。
別にいいですよー。 と言っても実はまだちゃんと読んでないので、 これを機会に流し読みして書いてみます。 こういうチャンスに読まないとなかなか読めないですからね。
"Linux Assembly Language Programming" Bob Neveln, Prentice Hall PTR, 2000 (B5変 254ページ)
[英語]
普通。特に難解な言い回しをしたりすることはありません。 ruby-talk の平均よりちょっと上 (丁寧に近いほう)、 くらいだと思います。
[概要]
Linux でアセンブラってのは嘘じゃないんですが、 まず前半 1/3 は Linux とほぼ無関係です。 i386 の一般的な話とか 16 進数とか flip flop とかの話が続きます。
やっとアセンブリが来たぜー! と思ったら今度はアセンブリ言語の文法の話になります。 さらにエンディアンとアラインメントとレジスタの話があって、 なかなかプログラムを書かせてくれません。泣けます。
そしてスタック。引数渡しプロトコルとか。 この辺で、どれがLinux特有の規約か、なんて話があるといいのにな。
386 な雰囲気。マルチタスク。Task State Segment。 ページングと仮想メモリ。アドレス変換。でもって ELF。ELF?! うーん、まあ、わからんでもないが……。
割り込みだ。ようやく Linux してくるかなあ。 ISA バス。INT80 (システムコール)。 このへんはレジスタやスタックの使いかた (規約) が細かく書いてあるから お役立ち度が高そうだ。
なぜいまさらビット演算? 短い。
なんでドライバなんだよ。 しかも対象バージョンが書いてないじゃん。前書きにでもあるのかな。ないな。 ドライバなんてカーネルのバージョンが違ったら別物だぞ。 いずれにしろこの章だけでデバイスドライバが書けるとも思えず。 "Linux Device Drivers" 2nd でいいような気がするな。 あれは原書でも読みやすくていい本ですね。
え。なんだこのキャプション。ああ、セグメントの話ですか。うわ、違った。 本当に DOS だ。VGA 直接叩いてるし! キーボードバッファに手ぇ出してるし! つかリアルモードだし! うわ、うわー!
むー。今度はブートシーケンスか。 これって実はカーネルの本?
唐突に終わった。
nasm と、あと edlinas っていう GUI な 86 エミュレータが付いてます。 えっ、DOS プログラムなの?! 一緒についてる dosemu を使えってことか? 気に食わんなあ……。気に食わんが、動かしてみたら意外と面白かった。 (CD-ROM に入ってる dosemu は古いので Linux 2.4 ではコンパイルできなかった。 最新版のバイナリを落とせば OK)
readelf (GNU) / elfdump (Solaris) の機能縮小版みたいなのが付いてるけど、 これのソースコードは酷い。まず行末が CR。この筆者、林檎派か? そういえば前書きに PowerPC なんたらって書いてあったな。 さらに C のフォーマットが糞。 main のみのプログラムで 450 行。 変数は int c, d, i, j, k を関数先頭で定義し、使いまわす。 なぜか i++ を i = i + 1 と書く。 なぜか for 文を使わず全部 while で書く。 エラーの時は return 0。 エラーメッセージを平気で stdout に吐く。 などなど。最大限好意的に解釈するなら、 アセンブリに落としたときに見やすいように書いてる可能性はあるでしょう。
[評価]
概要で文句を結構書いたのでできるだけ良い点を書きます。
最終的に落ちる機械語 (のバイト列) がどうなって、 レジスタとメモリがどういう状態になるのかというのを 逐一説明してくれるのはなかなかよいと思いました。 マシンの生の姿がとてもよく見えます。
最初に書きましたが、文章の質はよいですね。 下手なジョークもないので、我々が読んでも普通に読めます。
なかなか面白くならない点に関しては、 『はじめて読む8086』あたりを読んで基礎知識を先に入れちゃって、 適当にすっとばしながら読んでいけば補えるでしょう。
もうちょっと読み込むと評価が変わりそうですが、 とりあえず「値段とページ数なり」という評価です。 A-E の 5 段階で内容を評価するなら B。でも B- に近い B。
ああでも、『はじめて読む8086』『はじめて読む486』 "Linux Device Drivers" を持ってたら必要ないかも。 カバーする範囲としてはこんな感じだと思いますね。
←初歩、汎用、ハードウェア、asm Linux特化、ソフトウェア、C → はじめて読む 8086 <------------------> ※ 「....」は「内容が薄い」の意。 はじめて読む 486 <------------------------> Linux Assembly Language Programming <-----------..--..--..--..--..----------> Linux Device Drivers <-------------------------------------------->
逆に言うと、前記の三冊を持ってなければ役に立つということかな。 でも、初心者に勧めるとしたらやっぱり『はじめて読む……』か。 ドライバ書くなら Linux Device Drivers だろうな。 それではこの本の存在価値は、というか対象読者は誰なんだろう。
そもそも目的がよくわかんないんだよな。 PC アーキテクチャ (ハードウェア) について話したいのか、 アセンブラを使ったプログラミング (ソフトウェア) について話したいのか、 Linux カーネルについて話したいのか、 Linux のドライバが書きたいのか、 Linux のユーザモードプロセスをアセンブラで書きたいのか、 何が最大の目的なのかよくわからない。
それから、話がカーネル側に寄りすぎているのはいただけません。 少なからずユーザレベルの話を想像していただけに、そこのところは期待外れでした。 ダイナミックリンク、インラインアセンブラなどの話をしてほしかったと思います。 もっとも、この点に限ってはぼくの期待から外れていたというだけなので この本の責任ではないでしょう。 でも、題名からそっちの話を期待してしまう人もいそうなんで書いときます。
結局、題名がよくないのかもしれません。 "Linux Kernel Assembly Programming on i386 platform" だったら問題ないでしょうね。
見直してみると結局ぜんぜんほめてないですね。 特にダメな本ではないのですが、
の二点でウマが合わなかったということで。 ここんとこは悪い評者にあたったということで勘弁してください。
■ nobu_toyofuku [「Kernel で super」。def foo; super; end; foo じゃありがちなエラーメッセージしかでないです。どういうスクリプトでしたっけ。]
■
あおき [[ruby-dev:20519] で聞いてみました。
module Kernel
def m() super end
end
Object.new.m
です。]
■
あおき [やっぱりまずかった模様。
eval.c rev1.475 で修正が入りました。]
■ nori [レビューを読みました。色々と詳しく書かれていたのでとても参考になりました。ありがとうございました。もう少し日本語で書かれた本を読んで基礎知識みたいなものを吸収しようかと思うので「はじめて読む8086」を買って、そして、Linuxデバイスドライバ第2版を買おうかと思います。]
■ arton [NETRubyがmakeできないのって、jayの問題ですよね? とあまりやる気も無いのに確認。]
■
あおき [あ、そうです。その件です。
でも確か生成後のファイルがついてるんですよね。
もう一回試してみます。]
たまにはパソコンの電源を入れない一日もいいなあ。
これ↓
にインストールを試みる。
うまくいったら今月の SICP 読書会から使おう。
……FDD からブートできない。FDD が死んでる模様。 しかたないので HDD に直接入れることにする。
2.5" HDD → 3.5" 変換アダプタでメインマシンにつなぎ、 現在の環境から直接ファイルをコピーしてしまおう。 HDD の構成はこうなる。
IDE0 master (/dev/hda): main HDD 1 slave (/dev/hdb): main HDD 2 IDE1 master (/dev/hdc): HiNote の HDD slave (/dev/hdd): CD-ROM Drive
まず cp -a でまるごと移し、目で見ていらないものをバサバサと消す。 chroot してみるとちゃんとシェルは動いた。
が、lilo できないことに気付く。/dev/hda からロードするという設定で /dev/hdd の MBR に書き込みたいのだが、そういうオプションはなさそうだ。 多少近いのが lilo -r rootdir だが、これでは書き込むデバイスが変わらない。 また、boot = /dev/hdd にしてしまうと 本番環境で /dev/hdd を探しにいってしまうことになる。
そこで lilo のソースコードを見てみることにした。 うまくするとちょっと書き換えるだけで出力先を変えられるかもしれない。 まずコンパイルに as86, ld86 (bin86 package), nasm などが必要だったのでこれを入れる。
……
飽きた (おい)。
やっぱり物理的につなぎなおすほうが早いな。 メインマシンの IDE ケーブルをつなぎかえて
IDE0 master: HiNote の HDD slave: CD-ROM Drive IDE1 master: main HDD 1 slave: main HDD 2
とする。この状態で Plamo の CD-ROM からブートし、lilo だけやる。 と思ったら、Plamo の ramdisk 環境には lilo が入ってなかった。 うわあ。
が、本番環境に lilo もコピーしていたので、 /dev/hda をマウントしてそこから取ることができた。 (追記:改めて考えると、パッケージのどれかに入ってたんだろうな)
よしっ、HiNote につなぎ直してブート! LILO Loading Linux.........................
勝手にリブート。
うわっ。 しくじってる、しくじってるよ……。
ああっ、そうか! メインマシンのカーネルって P6 に最適化されてるんだった! 原因は十中八九これだな。 (HiNoteUltraIIはPentium150MHzです)
うーむ、メインマシンでコンパイルしなおすか、 それともおとなしく Plamo の CD-ROM から入れるか。 どっちが面倒かなあ。環境を作り直す手間を考えると、 カーネルだけ作りなおすほうがいいか?
つづく
ソースツリーからシンボルとか文字列を探すことはよくある。 真面目にやるなら global とか使えばいいのだけど、 面倒なときは全部 grep てのも楽でよいもんだ。
が、一つ問題がある。 Ruby くらいなら zsh 使って grep '^rb_define_method' **/*.[ch] とでもすればいいが、Linux とか glibc だとソースツリーがでかすぎて、 引数の数の限界を越えてしまう。かと言って for 文使って
for f (**/*.[chS]) { grep 'sys_ioctl' $f }
とすると、
~/s/src/linux-2.4.20 % time zsh t > /dev/null zsh t > /dev/null 36.48s user 9.31s system 100% cpu 45.781 total
こんなに遅くなってしまう。プロセス起こしすぎですな。
そこでこんな Ruby スクリプトを書いてみた。
#!/usr/bin/ruby # # search.rb # require 'find' require 'getopts' def usage( status ) (status == 0 ? $stdout : $stderr).print(<<EOS) Usage: #{File.basename($0)} [-f function] [-c function] [-m macro] [-g pattern] -f func search definition of function FUNC. -c func search function call of FUNC. -m macro search definition of macro MACRO. -d sym search definition of function or macro, SYM. -g pattern search PATTERN. EOS end def main getopts(nil, 'c:' , 'd:', 'f:', 'g:', 'm:', 'help') or usage(1) usage(0) if $OPT_help case when $OPT_c then find_pattern(/\b#{$OPT_c}\(/) when $OPT_f then find_pattern(/(?:^|[^=\s] )#{$OPT_f}\(\w/) when $OPT_m then find_pattern(/^\#\s*define\s+#{$OPT_m}[\(\s]/) when $OPT_d then find_pattern(/^\#\s*define\s+#{$OPT_m}[\(\s]|(?:\A|[^=\s] )#{$OPT_f}\(\w/) when $OPT_g then find_pattern Regexp.compile($OPT_g) end end def find_pattern( re ) Find.find('.') do |path| next unless /\.[chsS]/ === path File.open(path) {|f| f.each do |line| if re === line puts path.sub(%r<\A\./>, '') + ":#{f.lineno}" puts ' ' + line.strip break end end } end end main
ようするに単なる力任せ検索。 最近のマシンにかかるとこんなおバカなプログラムでも結構速くて、 Linux 2.4.20 のソースツリー (170MB) 全体でも
~/s/src/linux-2.4.20 % time ruby search.rb -f 'sys_ioctl' > /dev/null 9.04s user 0.33s system 98% cpu 9.485 total
こんなに速い。びっくりだ。
だけど、やっぱりもうちょっと速いと嬉しいな。 検索サーバをたててファイルを常に全部オンメモリにしておいたら 速くなるんじゃないかと思いついたので、次にこれを実装してみた。
まずサーバ。
#!/usr/bin/ruby # # searchserver.rb # require 'socket' require 'find' DEFAULT_PORT = 6668 def main daemon { cache = read_cache('.') $stderr.puts 'ready' if $DEBUG server = TCPServer.open(DEFAULT_PORT) while true sock = server.accept len = sock.gets.to_i re = Marshal.load(sock.read(len)) search cache, re, sock sock.puts '.' sock.close end } end def read_cache( dir ) cache = {} Find.find(dir) do |path| next unless /\.[chsS]/ === path #cache[path.sub(%r<\A#{Regexp.escape(dir)}/>, '')] = File.readlines(path) cache[path.sub(%r<\A#{Regexp.escape(dir)}/>, '')] = File.read(path) end cache end def search( cache, re, sock ) cache.each do |path, lines| #lines.each_with_index do |line, lineno| if re === lines #sock.puts path + ":#{lineno}" #sock.puts ' ' + line.strip sock.puts path #break end #end end end def daemon return yield if $DEBUG fork { Process.setsid fork { Dir.chdir '/' $stdin.close $stdout.close $stderr.close return yield } exit! } exit! end main
次にクライアント。
#!/usr/bin/ruby # # searchclient.rb # require 'socket' require 'getopts' DEFAULT_PORT = 6668 def usage( status ) (status == 0 ? $stdout : $stderr).print(<<EOS) Usage: #{File.basename($0)} [-f function] [-c function] [-m macro] [-g pattern] -f func search definition of function FUNC. -c func search function call of FUNC. -m macro search definition of macro MACRO. -d sym search definition of function or macro, SYM. -g pattern search PATTERN. EOS end def main getopts(nil, 'c:' , 'd:', 'f:', 'g:', 'm:', 'help') or usage(1) usage(0) if $OPT_help case when $OPT_c then find_pattern(/\b#{$OPT_c}\(/) when $OPT_f then find_pattern(/(?:\A|[^=\s] )#{$OPT_f}\(\w/) when $OPT_m then find_pattern(/\A\#\s*define\s+#{$OPT_m}[\(\s]/) when $OPT_d then find_pattern(/\A\#\s*define\s+#{$OPT_m}[\(\s]|(?:\A|[^=\s] )#{$OPT_f}\(\w/) when $OPT_g then find_pattern Regexp.compile($OPT_g) end end def find_pattern( re ) sock = TCPSocket.open('localhost', DEFAULT_PORT) data = Marshal.dump(re) sock.puts data.length sock.print data sock.flush while (line = sock.gets) != ".\n" print line end sock.close end main
で、以下が Linux 2.4.20 のソースツリーでの実験結果。
~/s/src/linux-2.4.20 % time ruby search.rb -f 'sys_ioctl' > /dev/null 9.04s user 0.33s system 98% cpu 9.485 total ~/s/src/linux-2.4.20 % time ruby searchclient.rb -f 'sys_ioctl' > /dev/null 0.00s user 0.00s system 0% cpu 10.468 total
なんと、遅くなってしまった。 原因はなんだろう。
まず、オンメモリにするという点に元々あまり意味がなかった。 なぜなら Linux のソースツリー全体よりも物理メモリのほうが圧倒的に大きいので、 一度読んだらその後は全て OS にキャッシュされていると考えられるからである。 従ってコストの最も大きいディスク I/O が速度に影響しない。
そうなると検索サーバが有利なのは
という程度に限られる。 検索対象データが多くなればこの程度のコストは無いに等しくなってしまうだろう。 前者二点は力任せ検索のベンチマークが 0.33s system となっていることから裏付けられる。 おそらく検索プロセスの実行時間のほとんどは正規表現マッチに使われているんだろう。
しかし、毎回ファイルから読むほうが速いのはどうしてだろう。 ここまでの考察では「少ししか速くならない」ことは説明できても 「遅くなる」説明にはなっていない。
これには、プロセスサイズが関係しているのではないかと予想する。 力任せ検索プロセスの RSS は一貫して約 2.4 MB 程度であった。 ハードウェアのキャッシュは L1 8KB, L2 512KB なので、 このプロセスサイズなら大部分がキャッシュに乗ってしまうはずだ。 一方、検索サーバプロセスの RSS は 800 MB 程度であり、 しかも検索のときはその全体をなめることになる。 つまり非常にキャッシュが効きにくくなる。 これによって速度差が出たのではないだろうか。
※ 全然関係ないけど、x86 システムの L2 って意外に小さいのな。 Alpha は 96 年のマシンでも 8MB 積んでるのに。
もう一つ別の方法を考えた。 いままでは file.each を使って行ごとにマッチしていたが、 まずファイル全体を読みこんで正規表現マッチを試し、 マッチするファイルに対してだけ各行に対してマッチを行ってみる。 つまりこう。
#!/usr/bin/ruby # # search2.rb # require 'find' require 'getopts' def usage( status ) (status == 0 ? $stdout : $stderr).print(<<EOS) Usage: #{File.basename($0)} [-f function] [-c function] [-m macro] [-g pattern] -f func search definition of function FUNC. -c func search function call of FUNC. -m macro search definition of macro MACRO. -d sym search definition of function or macro, SYM. -g pattern search PATTERN. EOS end def main getopts(nil, 'c:' , 'd:', 'f:', 'g:', 'm:', 'help') or usage(1) usage(0) if $OPT_help case when $OPT_c then find_pattern(/\b#{$OPT_c}\(/) when $OPT_f then find_pattern(/(?:^|[^=\s] )#{$OPT_f}\(\w/) when $OPT_m then find_pattern(/^\#\s*define\s+#{$OPT_m}[\(\s]/) when $OPT_d then find_pattern(/^\#\s*define\s+#{$OPT_m}[\(\s]|(?:\A|[^=\s] )#{$OPT_f}\(\w/) when $OPT_g then find_pattern Regexp.compile($OPT_g) end end def find_pattern( re ) Find.find('.') do |path| next unless /\.[chsS]/ === path lines = File.read(path) #### if re === lines #### 問題はこの 3 行 lines.each_with_index do |line, idx| #### if re === line puts path.sub(%r<\A\./>, '') + ":#{idx + 1}" puts ' ' + line.strip break end end end end end main
そうしたら、
~/s/src/linux-2.4.20 % time ruby search_eachline.rb -f 'sys_ioctl' > /dev/null 8.96s user 0.33s system 99% cpu 9.336 total ~/s/src/linux-2.4.20 % time ruby search_read.rb -f 'sys_ioctl' > /dev/null 0.57s user 0.35s system 102% cpu 0.896 total
いきなり 10 倍速になった。なぜっ!? これは File#each が遅いのか、 はたまた正規表現マッチ開始時のオーバーヘッドが大きいのだろうか。 もうちょっと考察の余地がありそうだ。
なるほど。 中田さんの仰るように、each が原因というのもありそうです。 検証しました。
# each で読み込むだけ (正規表現マッチはやらない) ~/s/src/linux-2.4.20 % time ruby loadonly_eachline.rb ruby loadonly_eachline.rb -f sys_ioctl 6.52s user 0.37s system 100% cpu 6.884 total # read で読み込むだけ (正規表現マッチはやらない) ~/s/src/linux-2.4.20 % time ruby loadonly_read.rb ruby loadonly_read.rb -f sys_ioctl 0.44s user 0.28s system 104% cpu 0.692 total
おおっ! 犯人は each_line だったか! 文字列オブジェクトが増えるのが遅いのかなあ。もしかしてほとんど GC? そうか、検索サーバも GC 頻発で遅くなってる可能性があるな。 GC 止めてみよ。 Linux のツリーで GC 止めたらシェルに殺されたので glibc でやってみた。
# each で検索 ~/s/src/glibc-2.2.5 % time ruby search_eachline.rb -f sys_ioctl 2.10s user 0.19s system 101% cpu 2.261 total # read で検索して each ~/s/src/glibc-2.2.5 % time ruby search_read.rb -f sys_ioctl 0.27s user 0.20s system 105% cpu 0.445 total # 全部読み込んでおく (GC.enable) ~/s/src/glibc-2.2.5 % time ruby search_client.rb -f sys_ioctl 0.01s user 0.00s system 0% cpu 1.734 total # 全部読み込んでおく (GC.disable) ~/s/src/glibc-2.2.5 % time ruby search_client.rb -f sys_ioctl 0.01s user 0.00s system 0% cpu 1.716 total
あんまり変わらない。 単にこの検索のときにたまたま GC が起こってないだけかもしれないな。 それに glibc だとプロセスサイズが 200MB くらいしかないからさっきと条件が違いすぎる。
まとめると、each で大量に文字列オブジェクトを生成するのが遅い、 ということなのかな。キャッシュ云々はあんま関係なさげ。
■
なかだ [File#eachは、改行を探して各行ごとにStringを生成するあたりが大きいのかも。
File.readは、通常ファイルなら一回で読んじゃいますし。
# でもふつー、 grep -r のような。]
■
あおき [-r 知りませんでした…。
あ、GNU grep のオプションなんですね。
それはちょっと…]
■ woods [じゃfind . -name '*.c' | xargs grep 'hoge' /dev/null では?]
■
あおき [xargs って複数回に分けたりもするんですか!
それも知らなかった…(恥)。勉強になります。]
■ たむら [どうせ editor で開くんだから ctags -R *.[ch]]
■
旧世代 [find . -name '*.c' -exec grep 'hoge' {} \ -print;
しか知りませんでした。勉強になりました。]
一週間も死んでたのか。 いかんなあ。
つまりアレだ。なんて言うかいわゆるひとつの、
digital PersonalWorkstation 600au 買いました。 「すぐフロントパネルが壊れるモデル」として有名です。
入手したのは L3 キャッシュが 4MB で USB 付きの後期モデル。 さすがに 600MHz になると速いですね。 P3 600 ……と比べるのはちときついか。でも体感は結構速かった。 ような気がする。例: zsh の compinit が遅延なしで使える。とか。 とりあえず常用してもいいかなと思うくらいの速度は出ます。
メモリが 320MB しかないのはヘボいですが、 dPW のメモリは SDRAM なので増設メモリを見付けるなんざ 赤子の手をひねるより簡単なことです。 たとえそれが registered ECC であったとしても。 (ちなみに dPW は ECC 必須じゃなかったような気がする)
ちょっと詳くて写真が多めの情報はこちら。
つまりあれなんですよ。これはなんと言うかようするにその、
digital AlphaServer 800 5/333 も買いました。
ペデスタル匡体 death よ? でもってハードウェア RAID ですYO? はーどうぇあーれいどですよ?! IDE RAID なんてぇ糞庶民の糞ハードウェア RAID とは糞違うんです、 つーかおまえら RAIDって言いたいだけとちゃうんかと、 ってツッコみたくなる IDE RAID とは違うんです、 SCSI-3 (UltraWide) が 3 チャネルのハードウェア RAID なんです。 え? ホットスワップはデフォでしょ?? みたいな???
まあそんなこと言っても ASv800 は所詮エントリサーバなので 内部には HDD 4 発しか積めないんですけどね。せこいです。へちょいです。 豪勢に 16 発くらい積んでみたいものです。 あるいはせめて最上位の 500MHz モデルならよかったんですが。
あー、そうさ、どうせ買い損ねたよちくしょ〜! 500MHz のはちょっと高いからって躊躇しているうちに買われたんだよちくしょ〜! 秋葉原三大原則! 欲しくなったら買う! 悩んだら買う! 考える前に買う!
そんなわけでヤケになって買ったのがこの二台です。 まあ RAID は楽しめそうだし、600au はなかなか上物だったのでよしとしました。 生活費ですか? そんな core 知りません。
ASv800 詳細
OS は NetBSD にした、というかそれしか選択肢が残らなかったんですが、 インストールでめちゃくちゃ苦労しました。 たかが OS のインストールでこんなに苦労したのは始めてです。
ところで少し前に AlphaStation 500 のメモリを registered ECC 5V EDO DIMM と言いましたが、 よくよく調べたら registered ECC 5V FastPage DIMM でした。 ここにお詫びして訂正いたします、まる。
ごめんなさい。
# まあ EDO 刺しても動いちゃったわけですが
しかし最近は日記が Alpha ばっかりだなー。 きっとそういうバイオリズムなんだろうな。 こう、ソフトウェアの抽象世界と、 ハードウェアの具体世界の間を行き来する曲線が走ってるわけだ。 んで抽象世界にグラフが振れてるときは「LL(k) 萌え〜」「Haskell 萌え〜」となる。 具体世界にグラフが振れてるときは「Alpha 萌ぇ」「インラインアセンブラ萌ぇ」となる。
ちなみにこの曲線は別名「銀行口座の残高曲線」とも言うんですけどね。
ああ、そろそろ Haskell がまた気になってきたなあ……
UNIXって名前の文化ですよね。つまりファイルシステムってことですけど。すべてをファイルにするとは、すべてのオブジェクトに名前を付けるということです。逆に言えば、名前を付けると(ファイルシステムに編入すると)、そのオブジェクトが扱えるようになります。
この際、名前がツリー型に構造化されているってのはどうでもいいですね。問題なのは、ツリー型のシステムをパス(名前)でもって表現しているというところです。
そして名前はテキストで表現されていて、UNIX にはテキストを扱う手段がある。つまり sh がある。細かく言うと、sh と、パイプと、それによって統合される UNIX ツール群がある。こういったツール群はファイルの中身を扱うものとして語られることが多いけども、実は名前自体をいじれることのほうが重要なんではなかろうか。
寿司とコーヒーは合わない。
ASv800 のインストールをしてて 101 キーボードが必要になったんですけど、 なんと現在家には 101 キーボードがないことがわかりました。 そこで安いのを BIC P 館に買いにいったんですが、 Windows キーのない 101 配列キーボードは HHK Lite しか存在せず……。 しかたなく HHK を買ってきました。
しかし HHK Lite は安いですね。5000 円ちょいですもんね。 ぷらっとほーむで 25000 円の 値札を付けて売ってたころからするとずいぶん変わったもんです。 その分作りがちゃちくなった感じ (またフレームの元を……)。
まあもともと HHK は好きじゃないんです。 ぼくはナチュラルキーボード派なので、 あんなせせこましいキーボードでは打てません。 キーマップは loadkeys と xmodmap と窓使いの憂鬱にお任せで。
それにしても ruby-bugs-* はスパムばっかりですね。 あとから問題のバグを探すのも不便だし、URL が次々変わるし、 ruby-list/dev で投げてくれるほうがずっと便利って気もします。 おくじさんの日記 (のツッコミ) だと思いましたけど、 ML と融合した BTS ってのはよさげですね。
XML-RPC も入った模様
ああそうか、ML と融合すると subscribe しないといけないな。 かと言ってユーザ登録なしにすると SPAM が蔓延するし。 困ったもんだ。
あ、そうだ突然思い出した。
長らく放置状態の Ripper ですが 1.8.0 が出たら更新しようと思ってます。 あれは人力で追従してるので、ある程度文法が固まらないとやる気にならないんですよね。
そういや普通 ripperって言うと CCCD をクラックするとかそういうやつになるんですね。 自分としてはどっちかと言うと Jack the Ripper なんですけど。
こうして予告しておかないと更新しなくなるからなあ。
少し昔、hdparm -d1 するのを忘れてて DMA がオンになってないということがあった。 それ以来、/etc/rc で hdparm してるから大丈夫だと思ってたのだが……。
/dev/hdb のことを忘れてたよ! ウァァァァァァァァァン! なーんか、でっかいファイルを作った直後、妙に反応が鈍くなると思ったんだ。 CPU ががんばってアクセスしてたんかい!
# hdparm -t /dev/hdb Timing buffered disk reads: 64 MB in 21.55 seconds = 2.97 MB/sec # hdparm -d1 -c1 # hdparm -t /dev/hdb Timing buffered disk reads: 64 MB in 1.16 seconds = 55.17 MB/sec
きゃー。
18 倍速……。こ、これは当分立ち直れないヨカーン……。
ついでに dPW600au (Quantum Viking II / Ultra Wide SCSI)。
Timing buffered disk reads: 64 MB in 5.14 seconds = 12.46 MB/sec
ふーむ、こんなもんか。 まあディスクが相当古いしな。
Linux の起動時に表示される BogoMips について ちゃんとした知識がなかったので調べてみた。
http://www.linux.or.jp/JF/JFdocs/BogoMips/faq.html
「bogo」は bogus (いんちき) なんだそうな。
ちなみにこんな感じ。
UltraSPARC-II 250MHz 488.00 Alpha 21164A 600MHz 591.39 Celeron A 333MHz 683.21 Pentium 4 2.4GHz 4784.12
やる気なしです。鬱です。ここ数日メールすら読んでませんでした。 そのわりに京極夏彦 5 巻分 (文庫で 4000 ページくらい) を読み通したりしてましたけど。
むむ、range がバグありでしたか。 ありがとうございます。
うぁ、こっちもかあ。 またまたありがとうございます。
むー、Ruby レベルでも汚染チェックが必要なことがあるのだな……。 C レベルだけチェックすればいいと思ってたからちょっと盲点だった。 net/smtp は RCPT TO の引数にチェックがかかってるけど、 他はどういう場合があるだろう。
先週だったのか……。完璧に忘れてた。
asv800:~/obj/ruby % uname -srm NetBSD 1.6.1 alpha asv800:~/obj/ruby % make test test succeeded dpw600au:~/obj/ruby % uname -srm Linux 2.2.20 alpha dpw600au:~/obj/ruby % make test test succeeded
普通は HDDってそんなに飛ばないものなんですかね。 ぼくはこれまでに 5、6 台のクラッシュ経験があります。 IDE SCSI 3.5" 2.5" ハーフハイト フルハイトと、 多種多様な HDD が次々とクラッシュしてくれました。 そんな経験はしたくありません。
うーん、しかし……。5 / 28 本って、 のべ本数比率だと 16%、 1 本/年 の確率でクラッシュしてるわけか。 中古のが多いせいもあるだろうけど、 いくらなんでもクラッシュ率が高すぎるな。 もしかしてハードディスクの神様に呪われてますか?
■ なかだ [それは当然、fixしろってことでは。]
■ あおき [やっぱ直さなきゃだめですか…]