トップページ | 2006年11月 »

うめき声

先ほどソフトバンクのシステムが復帰したよう.

停止中にau/docomoから総攻撃を受けたようで,webをチェックした人はけっこう高確率でソフトバンク導入をとりやめたんじゃないだろうか.

気になるのは発表がwebベースだったことで,その瞬間にwebをチェックしていない人にどこまで伝わったかということ.au/docomoの声明はその瞬間は確かにインパクトがあったが鎮静化してしまえば過去の話である.何しろその時点では他社<--->ソフトバンク間双方向とも動きが取れなかったので,後になって冷静に考えたらやっぱりソフトバンクのサービスがいいという判断になり(その時点で冷静じゃないんだが),そっちに流れるかもしれない.まぁそもそも他社<--->ソフトバンクという構図もおかしな話なんだが.(au/docomoは基本的に単体でソフトバンクより強いから)

しかしauが学割を発表した当初,加入者が増大しつながりにくくなったことを考えれば,(不要な痛みではあるが)乗り越えられないレベルでもないだろう.

総じるとシステム停止の悲鳴はうれしさ半分痛み半分のうめき声で落ち着くのではないだろうか.

悲鳴

ソフトバンク「予想外」、連日の携帯電話契約停止

"システムの処理能力を超える申し込みがあったとして新規や機種変更などすべての契約業務を停止"

これははたしてソフトバンクにとって嬉しい悲鳴なのかそれとも断末魔なのか.

競合3社が予想してた通り,土日の込み具合はすごかった模様.
僕の知っている人の間だと,わりとWEB関連の記事をよく見てる人は「ソフトバンク乗り換えは危険」と判断し,そうじゃないごく一般的な人は「ソフトバンクは安い」と思っている傾向にある.
その人数比は

ソフトバンク乗り換えは危険 < ソフトバンクは安い

なので,販売店でも土日はそのような比率で人が集まったんじゃないだろうか.

しかしよりによってお客の集中するときにトラブルを起こしたのは痛かったろう.
「障害の原因が不明」となっているので,少なくともシステム上の人的リソースの問題ではないのは確か.意表をついた作戦がアダとなって信用を失墜させたか.

しかし現実に復旧さえしてしまえば顧客はあまり気にしない人が多いと思われるので(何しろソフトバンク携帯は全時間無料と信じてる人が多いくらいなので)結果的にはソフトバンクがこの件に関してリードしそうな気もする.
むしろ"システムが障害を起こすほど大人気"と思い込んだ顧客がかえって流れてくる可能性さえあるかもしれない.

果たして今回のシステム障害はどういう結果をもたらすか.

トラックバック1251件

当ブログはココログというサービスを使ってるんだが,このサービスは眞鍋かをりさんも利用していて眞鍋関係の広告がしょっちゅうトップに表示される(しゃちょーがどうとかgoogleがどーとか).
で、さっきはじめてその眞鍋ブログをのぞいたんだが,一つのエントリーを適当にのぞいてみると「トラックバック(1251)」.食ってたラーメンが耳から飛び出るほど吹いた.

で,1251件全部のぞいて感想を書こうかと持ったんだが2件くらい見たところで力尽きたのでやめる(ヘッドラインだけ見るとトラックバックの85%程度は眞鍋エントリと無関係そう).
眞鍋さんのエントリ自体は(トラックバックの件数以外)ごく普通の日記である.

このブログサービスはスパムトラックバックを受けることが多いんだが,なんか技術的に排除するいい方法はないんだろうか.自前サーバだったらどうにでもなるんだが.

(※眞鍋エントリへのトラックバックがスパムだと言ってるわけではない)
(※本質的にはスパムみたいなもんだとしても)

ネットワークの話

ネットワークと聞くとインターネットがどうだとかCGIがどうだとかWEB2.0がどうだとか,そういう清く明るい(?)話題がまっさきに思いつくものだけど,そんな健全な話題を僕がするかと思ったか!!残念だったな!!(僕の脳みそが)

というわけでOSI基本参照モデルがどうとかプロトコルがどうだとか言う,基本情報処理試験のテキストの中で出てきたら「ひまわりでゲームつくれるおれすげえ」系の若い学生さんにとりわけ毛嫌いされる部分について述べたいと思う.(いやひまわりは確かにすごいんだが)

なんでそんな話をするのかというと,仕事でネットワークに関連することをやることになっていろいろ調べてたらpreccsが未踏のプロジェクトだと知って,ちょっと興味が湧いたから紹介したくなったのである.(どうでもいいけど未踏のすごいプロジェクトって研究施設関連の人のばっかりで(技能屋としての)個人プログラマの影が薄くてちょっと悲しい)

preccsはプロトコルコンパイラである.
形式にそった言語で書かれたプロトコルの定義を食わせるとそのプロトコルを処理するC言語コードが出産されるというものらしい(じっさい使ったことはないんだけども).

さて,インターネットのプロトコルはTCP/IPなのだけど,TCP/IPはコンピュータtoコンピュータのデータ通信方式を定義しているに過ぎない.
指定したコンピュータ上のプロセスまでデータがきちんと到達するためにはプロセスtoプロセスの通信方式が定義されなければならないし(セッション層),さらにそのデータをどうアプリケーションが解釈するか(プレゼンテーション層)も定義されなければいけない.HTTPやFTPなんかのプロトコルはだいたいアプリケーション層からセッション層までが一緒くたになって定義されてるんだが,telnetなんかでヨソのサーバにアクセスするとアプリケーション層やプレゼンテーション層なんかをすっとばすことができるのは,OSがセッション層できちんとつないでくれるからである.
こんな風にネットワークは階層構造になっていてそれぞれの層をシステムのどの部分が受け持つかだいたい決まっているので,大抵の場合アプリケーションプログラムはネットワーク通信におけるアプリケーション層とプレゼンテーション層くらいしか気にする必要がない.便利なもんである.

で,preccsの話に戻ると,preccsのモデリング/マッピング方式は実用的にはデータリンク層からセッション層くらいまでをサポートするとされている.要するにアプリケーションプログラマにはほとんど縁のない部分である.
preccsのモデリングはプロセス代数に基づき,OSのようにプロセスの状態を遷移させながら同期的な通信を定義する.
preccsのサポートする層のプロトコル処理エンジンはアプリケーションプログラムからは見えなくても実は大抵の電子機器に実装される部分で,しかもこれがけっこう複雑なのである.だからこれを体系的に自動生成できればかなり設計効率は高くなるはずである.

このリンク先には最適化があれば...という話が出ているが(プロセス代数におけるモデリングでの最適化というのはやっぱり主としてステートマシンの最適化になるのだろうか),Cコードを生成するのでpreccs入力言語上でのマニュアル最適化とprecssコンパイル後のCコードマニュアル最適化で十分実用的になりそうな気もする(いやほんと使ったことないからわからんのだけど).

というわけで通信機器に興味があってpreccs使ったことのある人はぜひ感想を聞かせてほしい.

実用性

プログラミング言語の実用性を考えた場合システムコールへのインタフェースがないと話にならないのだが,300以上もあるLinuxシステムコールのインタフェースをfridgeの中に全部組み込むのははっきり言って嫌だ.なぜならめんどうだから.
fridge/shellではwaitとかsleepとかbashで使えるシステムコールははじめから全部使えるのでしばらくはそれで代用願いたい.言語そのものの構造がもう少し安定したらライブラリの充実にも目を向けようと思っている.

------------------------------------

世の中2.0ブームである.web2.0がなんなのかはよくわからないのだが,とにかく流行っているのはわかる.たぶんそれはトカゲとサンショウウオのシルエットだけ見てもどっちがどっちだかよくわからないような感覚である.自分で言ってても何を言っているかよくわからない.

というわけでそろそろ実績づくりのためにもfridgeでなんか軽いwebツールでもつくろうかと思っているんだが,何をつくろうか.CGIをC言語で作ってしまうような僕ではあまり想像力が働かない.

医療の事

もしこの件をまだ知らない人がいたら,下の記事を必ず両方読んでほしい.

奈良の妊婦が死亡 18病院が転送拒否(gooニュース)
2006-10-18 その日が来たか・・・(新小児科医のつぶやき)

難しい話で,すぐに解決することは不可能だ.
でもきっとすぐに解決されなければいけない問題なんだと思う.
そしてもっとも速く解決する方法は,より多くの人が事実を知ることだ.

僕達プログラマの間で,プログラムにバグがあった場合にそれで刑事責任が問われる事例がどの程度あるのだろうか.

医療現場におけるミスや事故が非常に重くとりあげられるのは,一重に人命に関わることだからである.プログラマの現場においても,それはまったくないわけではない.
例えば某社エレベータの制御プログラムの件は記憶に新しい.
また遊園地のジェットコースターやスペースシャトルのプログラムにバグが含まれていたら,これは即命に関わることになる.
これら重大なバグは,社会的に注目を集めているとき特に大きなバッシングとなって帰ってくる.

バグはどんなプログラムにも含まれるというのは一般的に受け入れられている認識だが,特に人命に関わる場合は当然テストフェーズにおいてそれだけ慎重になる.だがそれでもなくならないのは,過去の悲惨な事実が証明している.

『事故』なのか,『ミス』なのか.
『逃げ場のない医者』と『受入先のない患者』がいて,それは誰かの罪なのか.

いずれにせよ,亡くなった方は本当にかわいそうだ.

重要なのは多くの人が知ることだ.誰かの責任を問うことじゃない.
多くの人が知らなければ世論は変わらないし,体制も変わらない.

花粉症のない世界

今日は花粉症の話だよカフンショー.おそらく天津飯あたりが使ってくる必殺技のことである(嫌).

筑波大チーム、花粉ない植物を開発…種できず花長持ち


筑波大で花粉をつくらない植物をつくることに成功.
人間で言うところのパイプカットのようなものか.しかもパイプカットされた植物は長持ちするらしい.まさに人工遅漏.

別にそんな下品な冗談が言いたくてこの記事をひっぱってきたわけではない.

僕は昔からずっと慢性的な鼻炎で,花粉症の季節になると生死にかかわるほど呼吸をするのが大変になる.
花粉症がはじめて発病したのは大学2年あたりのころだったが,いったん花粉をすいこむともう鼻水も涙もよだれも耳汁も止まらなくなり,何度も何度も大学を休んむはめになったものだ(元気な時も休んでいたが).

日本人の約20%が花粉症と言われるほど広く普及(?)しているこの症状だが,最近は花粉症に効く薬も出回っていてそれほど深刻なものではなくなってきている(飲むと眠くなるので結局大学は休むのだが).
だから今回の新技術が社会的にどれほど有用なのかはちょっとわからないが(花粉を抑えることよりも植物が長持ちすることに大きな意味があるかもしれない),それでも薬を飲まずに花粉を抑えられるならばぜひとも実用化してほしい.


文系および理系

つい半月前まで学生だった者からの視点として書いてみる.

参考:
再考:理系と文系(Logical Sebastian)

聞系と履系(404 Blog Not Found)

結論から言うと文系でも理系でもすごいヤツはすごいしダメなヤツはダメ.上下とるとだいたい同じくらいになると思う(友人一同ながめてみてそう感じる).
で,優秀さで真ん中あたり平均するとやっぱりなんとなく言われがちなとおり文系の方が若干「ダメ」気味な人が多いように感じる.だからLogical Sebastianに書かれている

「文系バカ≦理系バカ<(越えられない壁)<文系優秀<理系優秀<文系神」

は,間違っちゃいないけど正確には

「文系バカ≦理系バカ<(越えられない壁)<文系優秀<理系優秀<文系神=理系神」

である.

でもこれはちょっと世代によって順位が上下する.たとえば僕と同世代くらいでの理系は,僕の知る限りははっきり言って文系以上にひどいのが多かった.
理由は明白で,上の世代では「文系に行って遊び倒す」ような人達が,時代の流れのせいか理系にも大量に流れてきたからである.僕と同じ情報系の学部に4年間通って,卒業して学んだ事は「おれにはパソコンは向いてなかったということ」と言ったやつが本気でいたくらいだ.
「理系はなんとなく就職に有利そう」と思って願書を出した「大学で遊び倒すつもり」の人達が,実際に入れてしまうからこんなことがおこる.

実際文系が上か理系が上かと言ったら優秀なやつが上でダメなやつがダメである.
僕は社会学や経済学出身で年収何千万という人を知っているし,弁護士は言うまでもない.
いずれも専門分野を極めた人間というのは自分次第でどこまでも上り詰められる可能性を秘めている.もしも誰かにとってどっちが上か重要になるとしたら,たぶんその人はどっちかに属していただけで,とても「専門を学んだ」とは言えない人間なんだろう.

話の視点を404 Blog Not Foundよりにする.

数学がなんかすげーって言うのは概ね賛成である.
抽象化してとらえたモデルからなんでもかんでもはじきだそうというのが概ね僕の数学に対する理解なんだが,抽象化されているからどんな分野にも必ず応用がきく.
「微分積分がなんの役に立つか分からない」と言う人,落ち着いて考えてみてくれ.微分積分がなければ携帯電話もパソコンもない.フーリエ変換が積分より定義され,そのおかげでカメラ付き携帯がすばやく画像を保存してくれるんだ.ましてや今君が見ているインターネットの技術なんてフーリエ変換の固まりだ.

ま,でも確かに使うだけならそんなことは知ったこっちゃない.

重要なのは,数学がはじめから「他の分野に応用をきかせるための分野」であることである.
だからthere was only mathematics.という言葉は数学のなりたちという立場から見るとまったく正しい.「世界のすべて」を学ぼうとする学問を僕は数学と哲学しか知らない.細かく探したらいっぱいあるかもしれないが.

404 Blog Not Foundでは

理系にとって全順序というのは、先人の肩にのり、そして後人を肩に乗せる、歴史を超えた壮大な肩車の一環なのだ。 そしてそれがため、理系というのはどうしても謙虚になりがちだ。彼らは自分の業績が自分だけの業績でないことをあまりに知っているのだ。

これに対して、「文系」というのは、あまり先人の肩をあてに出来ない。全順序をあてに出来ないからだ。肩かと思って乗っかると、そこはみぞおちで先人のうめき声が聞こえたりというのがむしろ普通なのではないか。

と述べている.これはつまり「理系にふくまれる学問は過去からのベクトルで,文系にふくまれる学問は過去からの集合だ」と言いたいのだろうか.なんだか文系理系の定義すら明確にしてくれそうだ.

実際,少なくとも過去から学び未来に生かそうという視点から見たらこの定義はあきれる程正しい.法律や政治,心理学,社会学等は経験に基づく場合が多い.たくさんの経験(失敗も成功もふくむ)という要素を持つ集合をヒントにし,新しい経験をして集合に要素を加える.
対して数学や物理学,生物学などにおいては過去の経験は前提条件になる.過去に証明された事象を再びくり返す必要がないので,新たな経験はベクトルとして伸びていくだけである.

それを踏まえてさらに引用すると

文系の方が「先人」という言葉を多く使いたがるようにも感じる。なぜだろうか。「先人」を使うことにたけては理系の方がはるかに頻繁なのに。

一つには、理系が先人を使う時には、「先人」という十把一絡げの言い方ではなく、具体的に「ニュートンのF=ma」とか「アインシュタインのE=mc2」という言い回しを好むからだと思う。それが空気のように当たり前なので、空気のように見えない、というわけだ。

これについての本当の意味はたぶんこうだ.
文系においては「先人」は「過去の経験の総称」を指すのだ.理系において先人を語るときはほとんどの場合具体的な個の人物を指すことができるが,文系においては「あの時はこう,その時はこうだった.だからこうだ」という議論を展開するために「先人」となるのである.これはそれぞれそういうアプローチの学問形態だからなのであって,好みは関係ない.

ここまでの理系文系両者を振り返ると,文系の方が混沌としやすい学問だといえる.なぜなら今日正しかったことが明日正しいとは限らないからである(だからこそだめなやつまで「おれできる」って思っちゃうんだが).

ところで文系の人が業績に対する姿勢も傲慢になりがちだという話なんだけど,僕はまったくそんなことは感じないし,思った事もない.これは僕が傲慢だから他の人に対してそう感じるのかもしれない.

継承機能

fridgeに継承機能を追加してみた.@演算子で継承できる.

例)
      1 #!/usr/bin/fridge
      2
      3 #object 1
      4 def child1 echo ,I'm a boy.
      5
      6 #object 2
      7 def child2 echo ,I'm a girl.
      8
      9 #the object for test of inheritance
     10 def testInheri :
     11     arg[0].child
     12     ...
     13
     14 #testing
     15 x.child@child1
     16 testInheri x
     17
     18 x.child@child2
     19 testInheri x
     20
     21 return 0

上記の例はxのchildというオブジェクトにchild1とchild2をオーバーライドした例.
クラスタイプの継承とは意味が違うので注意.
fridgeの継承ではオブジェクトが持つふるまいを指定した場所に張り付ける.

ガーベージコレクション

ほとんど気まぐれでgcを実装してみた.
もともとfridgeにはnewやdeleteに該当する機能が(今のところ)ないので,かき集められるゴミは動的に生成されるバッファに対してだけである.
めんどくさくて今までやってなかったんだけどやりはじめたら2時間くらいでできた.ほんとにだいじょうぶかこれ.

そろそろもう一つくらい「fridge独特の機能」がほしいよね.
そのあたりの仕様が決まって実装できればβ版卒業してもいいのに.

リダイレクト

fridgeの標準ライブラリにリダイレクト機能を追加してみた.

sample)
      1 #!/usr/bin/fridge
      2
      3 dwrite "tmp.txt" "test test test"
      4 dread "tmp.txt" outbuf
      5 echo outbuf
      6 rm ,tmp.txt
      7 return 0
      8

リダイレクトって一見地味だがほんと便利だと思う.
ほとんどのテキストファイル入出力ってopenしたら全部書くか全部読むか追加するかのどれかだし.(fridgeはdappendで追加モード)

個人的にはあと「継承」機能とperlみたいな「文字列内の変数展開」みたいな機能を実装したいんだが,どうなんだ.
継承っつって一口に言ってもいろんな実装あるしfridgeはクラスはないしそもそも必要かどうかもわからんし.
文字列内の変数展開もデフォルトでそういう動作にするのかライブラリで対応するのかでも違うし.
迷うところ.

ポインタがなくなる日

最近のプロセッサユニットとゆーもんは並列化するのがかなり一般的になっているんだが(参考),アーキテクチャの特性が変わるとソフトウェアの特性も変わる.

DSP向けのプログラムを書いた事があるひとは知っていると思うけど,実は並列に演算を行うプロセッサに対してC言語でポインタを使いまくると処理が極端に遅くなることがある.
なぜ遅くなるかと言うと,ポインタを使うと演算の依存解析が極端に難しくなり,コンパイラがコードをうまく並行化してマッピングできないからである.
依存解析による並行化というのはたとえばこういうやつ

例)
x=a+b
y=a-b

この二行の演算は互いに依存性がない,つまり入れ換えても問題がないから並列に実行可能であることがわかる.依存関係のない演算をひとつのブロックとした場合,それらの中では好きなようにヒマしてるプロセッサに演算を割り当てることができる.
この依存関係というのは変数のライフタイム(値を保持すべき時間)から知ることができるが,ポインタを使うとライフタイムの追跡が極端に難しくなる.そのためプログラムの完全性を保つため並行化できるブロックが細かくなり,無駄なCPUの空き時間が増え結果として処理効率が低下するのである.

ちょっと前だとポインタを使った方が速い場合というのはよくあったが,今後はC言語でもポインタを極力減らすプログラミング作法が普及するのだろう.

ベジータ戦闘服

すげーよコレ!!
これで誰でもエリートになれるぜ!!

カオス指向プログラミング言語

前回のエントリで「例えば種を植えれば何もせずとも花開いていくような」言語とかいうヨタ話をしたんだが「それって要はカオスってことか」と思い付き,「じゃあそれはカオス指向のプログラミング言語だな」と勝手に納得したのでカオス指向プログラミング言語について考える.

カオスというのはアレ.ベルヌーイ写像とかロジスティック写像とかのソレ.

カオスの解釈はいろいろあるらしいんだけど,とりあえずここでは単純な系(システム)から複雑な振る舞いをするものの事をカオスと呼ぶ.

カオス指向プログラミング言語における系とはそのプログラミング言語で書かれたプログラムそのもので,じゃあ出力は何かというと実はこれもある種の系である.プログラムからプログラムを生成というとジェネレータが思い浮かぶが,出力された子供の系はさらに孫の系を出力し,孫は曾孫を出力し...というように自律的に成長していく.あるタイミングで出力された系はユーザによってデータとみなされ,これがシステム全体の出力となる.

なんとなくこう書くと再帰呼び出しが連続する関数型言語が思い浮かぶが,それは違う.自律的に成長することが大事なのである.

実際には子や孫を生むだけじゃなく分裂や突然変異も発生し,分裂した系がまたなんか生んだり死んだりして別の進化をたどったりして目的の系を目指す.進化の途中でもうそれ以上進化しても目的の系を得られないことがわかればそのー族は死ぬ.

カオスと言うより遺伝的アルゴリズムとしてとらえることもできるかもしれない.

ここまで書いて「本当にそんなことが可能か?」と言わればなんだか無理そうな気がしてくるんだけど,ちゃんと言語仕様を考えればプロトタイプ的なものくらいはできるかも知れない.

ぱっと思い付く限りでは,「初期条件」「終了条件」「例外条件」なんかがプログラムソースコードに書かれることになると思うんだけど,カオスに詳しい人ならなんと言うだろう.

たぶん関連:

『現代という時代は、どのようなプログラミングを求めているのか?(Matzにっき)

どのプログラミング言語が一番優れているか / 2

目的/用途を問わずすべての言語を統合することは非常に難しいが,一部の言語に関してはすでに統合することで良い結果を出すことが証明されている.
例えばJavaや.NETである.これらの環境はまったく別の言語を低い抽象度において統合することで,ただ互換性を生み出す以上の働きをする.Jython,Jruby,rhinoは究極的にはいずれも同じ言語であり,Javaのクラスライブラリに100%アクセスできる.
またSystemCも言語統合のひとつの形である.SystemCはC++だが,段階的に抽象度を下げることで今までHDLでしか行うことのできなかった合成作業をC++ベースで行えるようにした.SystemCには習得の難しさやパフォーマンスなどまだ問題は残るが,これによりソフト/ハードを単一の言語で協調しながら設計することが可能になった.

長々と書いたが要するに何が言いたいかと言うと,プログラミング言語はその用途が広がっていく一方で,言語そのものはよりスマートに単一化することが求められているのである.

しかし単一化すると言ってもひとつの言語になんでもかんでも機能を実装すればいいというものではない.それは例えばperlのように,簡単に言語の肥大化を生み出す.

単一化のキーワードはやはり現代ある技術の中ではオブジェクト指向/メタプログラミングである.
肥大化した仕様をスマートに満たすためには,例えば種を植えれば何もせずとも花開いていくような,そういった機能が求められる.しかし,だからと言って安易に「それ用の機能」ばかり使うと,プログラムは簡単にデバッグ不可能なものになる.
次世代のプログラミング言語は多様性を持つと同時に,容易に軌道修正できるものでなくてはいけない.それはフロントエンドだけでなく,ミドルエンドやバックエンドでも同様である.

--------------------持論おしまい

どのプログラミング言語が一番優れているか

いろんなところで議論され,そしていろんなところで不毛な議論だと結論されるこの話題.
この議論自体は非常に不毛だが,これについて考えていると今後の開発に有効だと思われるアイディアが思い浮かぶこともある.

以下持論-------------------------------

プログラミング言語の使用は手段であって目的ではない.
だから「pythonやrubyの後はどのような言語が必要か?」という問いは無意味だ.
なぜなら目的がなければ手段は必要ないから.

じゃあもう新しい言語が必要じゃないかと言われればそうじゃない.

多くの言語は,その言語ひとつだけでもとりあえずなんでもできる...ように一見みえる.
計算可能性という意味ではそうかもしれないが,マクロな視点から見るとそうじゃない.

perlの計算速度ではどう考えてもC言語で作ったシミュレータの速度には追いつけず,定められた期間内に結果を出すことができない.C言語でどんなプログラムを書いてもverilog-HDLのようにハードウェアに合成することはできない.verilog-HDLでどんなに抽象度を高く書いてもperlのように正規表現で柔軟にテキスト処理を行うことはできない.

これらはもう不便だとか好みだとかいう問題ではない.無理なもんは無理である.だからこれらの言語は存在する.

で,話を元に戻すと「どのプログラミング言語...」という話はひとつの目的に対して複数のプログラミング言語が選択可能だから巻き起こる議論なんだと思う.またプログラミング言語は強いブランド性もあるから,目的が競合すると自分の好みの言語以外には否定的になりがちである.

では次世代のプログラミング言語とは何だろう.
個人的に,プログラミング言語は現代でもすでにソフトウェアを開発するためだけのツールではないことに着目している.
例えばPOV-RAYのような画像処理ソフトの内部の言語処理系.
データベースや信号処理シミュレーションによく出てくるM言語だってプログラミング言語である.
仮にネットワークプロトコルが制御構造を持つプログラミング言語だったどうだろう?
これらを一般化し,一つの言語で表現できるとしたら,それは新しい世代のプログラミング言語と呼べるのではないだろうか.

しかしこれらは夢のような話で,世界中の国の言葉をひとつに統一するようなものである.

-------------------------------つづく(といいな)

悲劇

もうほんと悲しかった.
誰だってブログ書くとき,「ワンクッション置くためのエントリー」ってあるじゃん?なんつーかさ,次のエントリーまでのつなぎみたいな,「間」を置くためのエントリー.大して意味もないけどなんとなく感覚的に書くヤツ.

それが今回48時間以上もTOPに出たままどうすることもできずに放置されてた.すごいまぬけなエントリーだよ.SME(すごいまぬけなエントリー)だよ.
なんでそんなことになったかっていうと単にメンテナンスにぶつかっただけなんだけどさ.もう48時間も晒されてアタイ汚されちゃったわ...二度とメンテ前に変なエントリーしないよばか!

で,まぬけつながりなんだけど僕はメーリングリストやブログですごいまぬけな質問やコメントをよくする.というかそういうコメントしかしてない気がする.
ほんどの場合そういうコメントは事前によく考えればしなくてすむはずなんだけど,寝ぼけてるときや暇な時によくやってしまう.

でも考えてみるとそういう質問やコメントでもしないと,時々本気でコミュニケーション不足になる気がする.あまりに配慮にかけた質問はともかく,ある程度以上積極的に質問しないと人とのつながりがなくなってしまうような.

自分が質問される側にまわればそんな心配もないのかも知れないけど,何しろweb上にはすごい人がいっぱいいて僕が答えられる程度の質問では大体google神様が全知全能のアレでウッフン(?)してしまうからね.神には逆らえない.(参照)

と言うわけで映画版デスノート後編の上映がはじまったら観にいこうと思ってる(神つながり).

-----プログラマの生き様-----

1  .コードを書くのが好き
2  .ものごとに首を突っ込むのが好き
3  .強制されるのは嫌い
4  .寝不足気味
5  .朝は弱い
6  .胃腸も弱い
7  .視力も弱い
8  .足腰も弱い
9  .相手が誰でも媚びない
10.バグが発覚しても謝らない
11.上司に怒られても謝らない
12.ハードボイルドを気取る
13.でも立場は低い
14.ガンダムは好き
15.スターウォーズも好き
16.おたくのくせに嫁は可愛い

五つ以上当てはまったらあなたはプログラマ.
※本作品はフィクションです

無断リンクを排除する

例によって夜中に目が冴えてしまったのでなんかして遊ぶ.

引用:
あなたが泣こうがわめこうが、技術的に排除しない限り無断リンクはなされるのだから。

「あちら側」と「こちら側」のルールメイキング

というわけで,技術的に排除してみた.

      1 #!/usr/bin/fridge
      2 #usage : http://HostName?PageName
      3 hostName="127.0.0.1"
      4 htmlPath="./"
      5
      6 echo ,Content-Type: text/html
      7 echo ,\n
      8
      9 pread "echo $HTTP_REFERER" fromLink
     10 if (match fromLink "^http://"+hostName)<0 toPage="index.html"
     11 else  pread "echo $QUERY_STRING" toPage
     12 pread "cat "+htmlPath+toPage htmlText
     13 echo htmlText
     14 return 0
     15

ポリシーは「TOP以外にリンク貼らせない」.
コツはhtmlファイルをサーバのドキュメントルート以下のディレクトリ以外の場所におくようにすること.
CGIを通してしかhtmlファイルにアクセスすることができず,同一ホスト以外からのリンクから飛んできた人は全部TOPページに飛ぶ.

しかしプログラマはいいけども,そうじゃない人に「技術的に排除しろ」っていうのもなかなか無茶な話だと思う.(そもそも技術的に排除できる人は自分のサイトで無断リンクお断りとかあんま言い出さないよな)

ということは,オプションで「無断リンク強制排除」とかって機能をつけたホスティングサービスやBlogなんかのWEBツールが出たら金になるのかもしれない.

#追記-------------(2006/10/17 14:00)
コメント欄で指摘をうけたように,このままのスクリプトだと$HTTP_REFERERを偽装されただけで外からホスト内のファイルがまる見えになってしまうので,実際の運用では指定したディレクトリ以下のファイルしか閲覧できないように「../」などの危険な文字列を除去する処理等が必要になると思います.

googleとYouTube

----[WSJ] 罰金は数十億ドル? メディア企業が対YouTubeで団結 http://www.itmedia.co.jp/news/articles/0610/16/news067.html

あっちでも こっちでも 話題になっている,googleとYouTubeの話.

記事を見てると,起訴をちらつかせて有利な提携を結ぼうとしてるんじゃないかと思えるような思えないようなどうなんだ.とりあえずここまではgoogleの読み通りなんだと思う.

後のことを予想してみると,結局起訴は起こらず(もしくは形だけ起こすような感じで)結局提携する会社が増えるんじゃないかな.何しろYouTubeぶっつぶすと,その場では賠償金が入っても長期的に見てその市場が使いものにならなくなってビジネスチャンスが減るってことも考えられるような気がするし.とかいいつつほんとにぶっつぶされたら大笑いだけど.

だから,どう自分に有利になるように提携交渉を進めるかが焦点になりそうなならないような.

Profiling python with fridge / 2

前のスクリプトを改造して,抽出した関数にBreakPointを設定し,Cを連打してどの関数が何回呼ばれたかプロファイルをとってみる.

>> ベンチマークpythonスクリプト

      1 a=10
      2 b=20
      3 c=a+b
      4 print c
      5

>> fridgeスクリプトソース

      1 #!/usr/bin/fridge
      2
      3 MAXFUNCTION=100
      4
      5 #calling a process
      6 call "gdb -silent ./python" fd
      7
      8 #getting functions
      9 talk fd "info functions\n" outbuf
     10 rslice outbuf "[^ \t\n*]+[(]" "g" functions
     11
     12 #setting break points
     13 for i in functions.size :
     14     if i > MAXFUNCTION break
     15     talk fd "b "+--functions[i]+"\n" outbuf
     16     ...
     17
     18 #starting process
     19 talk fd "run test.py\n" outbuf
     20 while (talk fd "c\n" outbuf) :
     21     rslice outbuf "[^ \t\n*]+[ ][(]" "" funcname
     22     if funcname<0 break
     23     --funcname
     24     if(fTbl[funcname]==0) fLst[fLst.size]=funcname
     25     ++fTbl[funcname]
     26     ...
     27
     28 #displaying functions
     29 for i in fLst.size echo fLst[i] ":" fTbl[fLst[i]]
     30
     31 #close a process
     32 write fd "q\n"
     33 close fd

>>結果
      1 Py_Main  : 1
      2 PyObject_CallFunctionObjArgs  : 74
      3 PyObject_Call  : 688
      4 PyObject_CallFunction  : 26
      5 PyObject_CallMethod  : 27
      6 PyNumber_AsSsize_t  : 1110
      7 PyNumber_Index  : 1110
      8 PyMapping_Size  : 2
      9 PyParser_ParseStringFlagsFilename  : 10
     10 initerr  : 11
     11 PyTokenizer_FromString  : 10
     12 tok_new  : 11
     13 decode_str  : 10
     14 check_bom  : 11
     15 buf_getc  : 10
     16 buf_ungetc  : 10
     17 check_coding_spec  : 12
     18 get_coding_spec  : 12
     19 parsetok  : 11
     20 PyTokenizer_Get  : 49
     21 tok_get  : 49
     22 tok_nextc  : 148
     23 tok_backup  : 39
     24 PyTokenizer_Free  : 11
     25 PyNumber_Multiply  : 34
     26 PyIter_Next  : 359
     27 PyNumber_And  : 107
     28 PyNumber_Or  : 3
     29 PyNumber_Int  : 26
     30 PyNumber_Remainder  : 4
     31 PyNumber_Add  : 33
     32 PyNumber_Long  : 4
     33 PyObject_AsCharBuffer  : 4

real    0m7.270s
user    0m0.471s
sys     0m0.500s

うほ.これはおもしろいかも.I/O時の同期のとりかたを洗練させればもっと速くなりそう.
ftpクライアントとかに接続すれば正規表現によるダウンロードとかできて実用的にも役に立つかもしれない.

同期/息切れ /2

結局子プロセスの標準入出力との同期の問題はかなりややこしい問題であることが判明.
期待するスケジューリングは

    
  子プロセス    ソケット                 親プロセス
1. 入力待ち状態 書き込み可能状態   
2. read状態       write状態
3.     write終了
4. read終了        
5. write状態     読み出しブロック    読み込み待ち            
6. ...                    
7. ...                    
8. write終了     読み出し可能状態  read状態 
9. 入力待ち状態 書き込み可能状態   

みたいな感じなんだけど,何がややこしいかってどのデータがどのタイミングでどこにいて,どの状態に遷移しているのかがよくわからんこと.

子プロセスが何に化けるかはわからないから,子プロセス側で入出力のタイミングだけロックすることはできない. ソケットはキューを持っているのでソケットのI/O可能状態は子プロセスのそれとは一致しないからselectしても無駄.waitはシグナルによる状態変化かプロセス終了しか待てないので対話的な通信には無意味.

結局断続的にとどくデータをどこまで読めばよいのか判断する一般的な方法が見付からなかったため,/procから子プロセスの状況を調べて,子プロセスがwaiting状態になるか終了するまで待つという同期のとりかたを実装してみた.結果8割程度は期待どおりに動くようになった.
この手の同期を実装したプログラムなんていくらでもありそうと思ったんだけど,意外と「コレだ」っていう方法が見付からなかった.

同期/息切れ

forkで分離した子プロセスに対してsocketpairとdup2を使って標準入力と標準出力をつなぐ.
要するに子プロセスにpipeみたいな双方向通信の経路を作ったんだけど同期がうまくいかない.
とりあえずfcntlでO_RSYNCとO_SYNCを設定してみるが意味無し.

   1176     if(socketpair(AF_UNIX,SOCK_STREAM,0,sv)<0){
   1177         perror("socket");
   1178         return -1;
   1179     }
   1180     /*setting mode*/
   1181     fcntl(sv[0],O_RSYNC|O_SYNC);
   1182     fcntl(sv[1],O_RSYNC|O_SYNC);
   1183     /*fork*/
   1184     fflag=fork();

さらにselectで読み込み可能待ちをしても二行くらい読み込んで力尽きる.
これはたぶんデータが断続的にくるせいだと思うけど,親からデータを書き込んでからselectで子が次に書き込み可能状態になるまで待っても二行くらいしか読み込まないのはなんでだろう?
試しにsleep(2)とかで待ってみるとちゃんとデータが届いた.ということはやっぱりデータ到着しきる前にreadしてるから同期がとれてないというのは間違いないぽい.
fcntlフラグで強制的に同期してるから子プロセスがwriteし切らないうちにread状態になるとは思えないんだけど,なんか勘違いがあるのかな.

Profiling python with fridge

pythonの実行ファイルからデバッガをつかってすべての関数名を抽出するスクリプト.

      1 #!/usr/bin/fridge
      2
      3 #calling a process
      4 call "gdb -silent ./python" fd
      5
      6 #getting functions
      7 talk fd "info functions\n" outbuf
      8 rslice outbuf "[^ \t\n*]+[(]" "g" functions
      9
     10 #displaying functions
     11 for i in functions.size : echo --functions[i] ...
     12
     13 #close a process
     14 write fd "q\n"
     15 close fd
     16 return 0
     17

このプログラム自体はあんまり意味ないけど,プロセス間通信のテストとして動かしてみる.
バッファの動作がいまいち不安定.同期がうまくいってないもよう.

日常生活

パンツ一丁で歩いていたら,そのパンツのゴムが緩くてどんどんずり下がってきて,いつの間にかパンツが脱げてどっかに行ってしまった.誰かうちの子を見掛けたら連絡してほしい.

というわけで今日はオープンソースとパンツの話(嘘).

今日出先から帰ってくると,無線LANがつながらなくて何時間もハマった.
僕はipw2200を使っているのだけど,いつもは嫌よ嫌よと言いながらもうれしそうに接続するくせに今日はなぜかハードウェアを認識しない.いや認識をしないというか見て見ぬふりをされている感じ.
「反抗期か!!そんなやつはうちの子じゃない!!」とか言いながら別のモジュールをロードしたりしていろいろ試したんだけど結局だめ.
「パパが悪かった...もう,許してくれ..」と泣きながら土下座してもつながらなくて,ほんと悲しかった.

で,結局再起動したりしてるうちにbiosで無線LANがオフになっていることが判明.結局パパが鈍感だったということで問題は解決され,いつまでも平和に暮らしましたとさ.しかしなんでオフになってたんだろう.

健康診断

健康診断の結果がきた.血圧が上80の下50だった
でもハッカーはみんな寝不足で低血圧だから仕方ないと思う(偏見).
あと視力もすごく下がってた.どおりで新宿の路上占いの運気と男気を読み間違えるわけだ.
不安になったので休憩中はなるべく裸眼でいるようにしている.

うひょひょひょひょひょひょひょひょひょひょひょひょひょ

fridgeにプロセス間通信機能を追加した.
でも人が使うときにreadやwriteの山になるのは使いづらいから,もうちょいなんか工夫したいと思った.ついでに同じコマンドでTCPとかUDPなんかの通信もできるようにしたいところ.まぁローカルからtelnetコマンドに接続すればいいだけの話なんだけどさ.それもなんかバカっぽいし.

------
GoogleのYouTube買収に見る「金はあっても考えなし」の愚

引用:

金はないが暇ならたくさんある、ということを自ら証明しているような、世界で最も無頓着なメディア消費者らの注目を集めたいのであれば、YouTubeのような方法もありだろう。

YouTubeはまさに、大勢の視聴者の中から、わざわざくずのような視聴者をすくい取るよう設計されている。

あんまりひどい言いようだから思わずふいてしまった.
僕はYouTube使ったことないから本当のところはわからないけど,どちらかと言えばこの手の消費者は金も暇も持て余している層が多いと思ってた.だって動画とかつくったり見たりするの結構時間かかるから,仕事忙しかったらやろうと思わないし(本文中で記者もそう言ってるし).

逆に言えばここに集まるユーザは仕事がんばってなくても(もしくはしてなくても)普通に生活できて暇になっちゃうような人だから,それなりにお金持ってるんじゃないかなって.

簡単に言えば貧乏人はそんなんで遊んでる余裕ないってことだ.カンだけど.

そんでそんなユーザが動画のわきにわけのわからん広告でも張ってあるの見掛けたら,確かに何も考えずにクリックしてしまうんでないかな.だって暇だから.

まぁそれでgoogleが元を取れるかどうかはまだわからないけども.

仕様書のないプログラム

どっかのブログ(どこだったか忘れてた)に「現代は昔と違って多くのニーズが満たされていて,昔と違って何をつくればいいか単純にはわからなくなった」というような内容が書いてあった.
もしそんな記事を見て「本当にその通りだ」と思った人がいるなら,その人にはわざわざIT社会に生きなくても焼き鳥屋やビルの清掃といった道もあるんだよと伝えておく.

世の中は問題で満ちあふれている.

僕はOSの専門家じゃない.でも僕の携帯電話の動作はバカみたいに遅いから,携帯のアーキテクチャのパフォーマンスをフルに引き出すOSの登場を切に願っている.
僕はインターネットの専門家じゃない.でも僕の契約しているプロバイダのモデムはなんだか使い辛くて,でも僕の住んでる地域は他に選択肢がないからなんとかしてほしいと切に願っている.

世の中は問題で満ちあふれている.

--------------そんな前置き--------------

僕のところに来る仕事ではまず100%仕様設計書がない.
「仕様書がないプログラムなんてオモチャだ」「そんなプログラムはビジネスの対象にはとてもならない」.あぁほんとその通りだ.僕も嫌になるくらいそう思う.
でもそんなプログラムが時には一般のソフトウェアの相場を遥かに上回る値段で取り引きされることもある.嘘じゃない.
僕が属しているのはそういう業界だから,そんな無茶がまかり通る.
それは一人でつくろうが一万人でつくろうが値段は変わらない.それが相場だから.

仕様書がないからって別にいい加減にプログラムをつくっているわけではない.
例え時間がなくてテストが不十分だったとしても,大体取引先が検収(要件を満たしているか検証)をして,その後に報酬の支払いが行われる.ニーズを満たして取引先が満足しているんだからそれは正当な報酬だと思う.

それでも「仕様書のないプログラムは考えられない」と言う人は後を立たない.そういう人は永遠に/dev/nullからの出力を取得する方法でも考えていればいいと思う.

なんの話だっけ.仕様書のないプログラムでも金になる時はあるってことだ.じゃあどういう時がそういう時かというと,多くの場合まったく新しいアプローチを実装したプログラムがそれにあたる.
つまるところ研究や実験的要素が多いプログラムがそれだ.そういうプログラム(言葉を変えるとシステム)は仕様書を用意しても実装した時に仕様書の通りではまったく実現できないことが多い.だから仕様書をあらかじめ書くと時間の無駄になってしまう確率が高いのだ.だから先には書かない.

でも人間社会の技術を進歩させるのはいつもそんなプログラムだ.だから「ニーズが満たされ過ぎてて何をつくればいいのかよくわからない」と言う人は仕様書のないプログラムをほとんど書いた事がないんだと思う.だってその仕様書を見て完全にプログラムをつくれるなら,その問題はすでに解決しているのだから.すでに過去に満たされたニーズを実体化しているに過ぎない(もちろんそれはそれで意味はあると思う).

そのような仕事は工場のロボットと同じだし,あるいは凡庸な社会の歯車だ.

そしてそのような場に疑問を持ち,愚痴をこぼし,社会の何かが間違っていると叫ぶ人はハッカーになるべきだと思う.コードをコードとしてではなく表現として受け取り,コードからコードを生み出せる天才を目指すべきだ.そして人々から自然とそう呼ばれるようになったとき,はじめて自分が慣れ親しんだ仕様書という文字の固まりの本当の意味がわかると思う.

ってさっきキヨスクで知らないおっさんに言われた.

おいたち

OSS(オープンソースソフトウェア)っていうくらいだから,OSSの話題はソフトウェア関連ばかりである.fridgeはOSSだが,その生い立ちはハードウェア設計(というかシステム設計)に深く関連し,少し複雑である.

C言語やC++はソフトウェアを記述するためだけの言語,と思っている人ははっきり言って古い.ハードウェア設計でもC言語ベース設計は一般的になっている.

プログラミング言語を語るとき,しばしばアーキテクチャと言語を完全に切り離した話をする人がいる.プログラミング言語が高級になればアセンブラなんて知らなくてもアプリケーションはつくれるから仕方ないんだけど(もちろん大したものはできないけど),それでは少し世界がせまい.経験的に,アーキテクチャに理解がないプログラマはハッカーにはなれないように感じる.

話が脱線した.とにかく現在のC/C++の用途は広い.対象となるバックエンドが異なると最適化の種類も違うものになる.gccには特定アーキテクチャ向けの最適化オプションがあるが,次々と登場する新しいCPUや,あるいはDSPに対して完全に能力を引き出した最適化を施すのは難しい.これがハードウェアシミュレータや合成ツールになってくるとなおさらである.

そこでコンパイラの最適化を動的に制御する方法を考えるようになった.例えばあるアーキテクチャに対するネイティブコードを生成するとき,

//コードサイズがキャッシュサイズより小さければ関数をインライン展開
if(code_size < cash_size) function_inline()

のように外から制御できれば,新しいアーキテクチャが登場してもすぐさまそのアーキテクチャの能力を最大限に生かした最適化を施すことができる.
fridgeはそのためのインタフェースのプロトタイプとしてつくりはじめられた.

その後コンパイラの最適化に対してだけじゃなく,もっと一般的なアプリケーション制御を考えるようになった.それは究極的にはアプリケーションのマクロ言語であり,設定ファイルである.

まず最初にfridgeをshellに組み込んだのは,そういった実験をしやすかった事と,制御構文が使い辛かったシェルスクリプトを使いやすいものにしたかったからである.その役目は現在のβ版fridge/shellでも十分果たしてくれると思う.

次のステップではデバッガとfridgeを統合してプログラミングできるデバッガをつくるつもりだったが,これはfridgeにプロセス間双方向通信機能を持たせればもっと一般的な方法で実現できそうなのでそのようなライブラリを作ることにする.
ちなみにデバッガでプログラミングできると次のようなメリットがある.

1.大量のブレイクポイントやステップ実行のログを自動的に生成して解析することができる
2.アプリケーションテスト時のシーケンス網羅チェックをすばやく行うことができる

デバッガでのこれらの機能は組み込みマクロによってすでに実現しているかもしれないが,fridgeでは他のアプリケーションも制御できるのでひとつの言語を覚えれば複数のアプリケーションを制御できるということになる.

なんだか後半は宣伝になってしまった.
そんなわけでfridgeはハードウェア設計->一般化によって生まれた言語ということである.

Hacking Ruby by Fridge / 2

昨日の夜の続き.
結論から言うと,まつもとさんの言う通り関数ポインタじゃほとんど速度が上がらないことが判明.
以下その実証(あんま意味ないけど).

まつもとさんのコメント(昨日の日記参照)を見た後で 実際にrb_eval()の中の条件分岐を関数ポインタにする作業をやるのは 呪われそうでさすがにちょっと嫌だったので,インチキコードをうめこんで実験してみた.

昨日使ったベンチマークをデバッガの上で起動して眺めてると,rb_eval()上ではどうやら NODE_CALL,NODE_LVAR,NODE_LIT,NODE_NEWLINEの四つの型のノードが 主に使われているようなので,ソースに次のように追加.

      
2916  if(nd_type(node)==NODE_CALL)        goto _NODE_CALL;
2915  else if(nd_type(node)==NODE_LVAR)   goto _NODE_LVAR;
2916  else if(nd_type(node)==NODE_LIT)    goto _NODE_LIT;
2917  else if(nd_type(node)==NODE_NEWLINE)goto _NODE_NEWLINE;
2918  switch (nd_type(node)) {
2919    case NODE_BLOCK:
2920      if (contnode) {
...
3436    case NODE_CALL:
3437    _NODE_CALL:
...

上記みたいにcase文の下にラベルをはって,switch文に入る前に goto文を使って条件分岐の演算を前倒しする.
こうすればベンチマークで使われる4つタイプのノードがどんなにcase文で優先順位が低くても, 条件分岐演算は多くても4回(平均2回)ですむことになる.

で,このソースでベンチマークをまわせば取り合えず速くなると思ったんだけど全然速度変わらず. ということはボトルネックはやはり条件に到達した後の処理ということか.

さすがに優秀な人がソースを見てるだけあって,高速化も単純にはいかなかった.

---おまけ---
あんま推奨はされないけど,実は関数ポインタ以上に switch文のような条件分岐の速度を向上させる方法がある.
ほんとはrubyのソースコードにやってみようかと思ったけど 条件分岐が速度にあんま関係なさそうだったので今回は断念.

      3     static void* to[]={
      4          &&TO0,&&TO1,&&TO2,
      5     };
      6     goto *to[1];
      7     TO0:
      8     //operation 0
      9     TO1:
     10     //operation 1
     11     TO2:
     12     //operation 2
     13     return 0;
     14 }

&&演算子を使うとラベルが表すアドレスを取得できるので, これを利用して指定したアドレスにいきなりジャンプする.

単純にjmp命令に置き換わるだけなのでオーバーヘッドがなく速い(たぶん).

Hacking Ruby by Fridge

夜中に目がさえてしまったのでfridgeを使ってrubyをハッキングする. まぁあんまfridge関係ないけど.
下準備としてrubyをデバッグモード(最適化オプションを外して)コンパイルしておく.
以下がハッキング用fridgeソース

      1 #!/usr/bin/fridge
      2
      3 # ruby src -------------------------------
      4 rSrc="""
      5
      6 i=0
      7 while i<10000000
      8     i+=1
      9 end
     10 p i
     11
     12 """
     13 # getting profile -------------------------
     14 opcontrol, --reset
     15 opcontrol, --start
     16 pwrite "time ./ruby" rSrc
     17 opcontrol, --shutdown
     18 opreport ,-l | head

これぞfridgeによるインラインruby.
fridgeではどんなスクリプト言語でもインライン展開することができる(なんの役に立つかはわからないけど).
中身は簡単.oprofileを起動してrubyスクリプトの部分のプロファイルを取るだけ.
結果は以下の通り.

samples  %        image name  app name  symbol name
2708     49.1738  ruby        ruby      rb_eval
1203     21.8449  ruby        ruby      rb_call0
751      13.6372  ruby        ruby      rb_call
238       4.3218  ruby        ruby      call_cfunc
230       4.1765  ruby        ruby      fix_plus
148       2.6875  ruby        ruby      fix_lt
101       1.8340  ruby        ruby      rb_class_of

rb_eval(eval.c)という関数が重いんだけど,中身を見たら

   2908   again:
   2909     if (!node) RETURN(Qnil);
   2910
   2911     ruby_current_node = node;
   2912     switch (nd_type(node)) {
   2913       case NODE_BLOCK:
   2914         if (contnode) {
   2915             result = rb_eval(self, node);
   2916             break;
   2917         }
   ...         

という長いcase文になっていて,たぶんここの部分を関数ポインタのリストとかにすれば だいぶ速くなるんじゃないかと思った.
パッチつくろうかと思ったけどけっこう量がありそうだし, 明日は彼女とディズニーランドに遊びに行くので今日は寝る.
誰か興味があったらやってみてくれるとうれしい.

そのうちfirefoxのハックとかもやってみようかと思ってる.

関連
ruby本家:ruby公式サイトです.
Matzにっき:作者のMatzさんのにっき
ユメのチカラ:oprofileによるrubyのハックやってます.色々教えてもらいました(すごく助かってます).
fridge home page:宣伝

カーネル

oprofileを使った時にvmlinuxがないと指摘を受けたのでインストールをしてみた.(/boot/にはvmlinuzしかなかった)
僕が使っているsuse9.3のYASTからはコンパイル済みのイメージが見付からなかったので, ソースをダウンロードしてコンパイルする.

# cd /usr/src/linux-XXX
# make

何も考えずにmake.なんとなくカーネルイメージが完成したのでそれをopcontrolで指定してプロファイルを取る.

samples  %        image name               app name                 symbol name
8507     58.5277  processor                processor                (no symbols)
1404      9.6594  fridge                   fridge                   cvectorFind
487       3.3505  fridge                   fridge                   fgSysCast
476       3.2749  fridge                   fridge                   fgSysCastObjInt
423       2.9102  fridge                   fridge                   fgSysObjAssMeth
372       2.5593  fridge                   fridge                   fgSysObjLesMeth
332       2.2841  fridge                   fridge                   fgMethDef

昔うちの大学に講師に来てた人が「LinuxはプログラマのためのOSだ」と言っていたが, 今でこそその言葉が実感できる.

話変わって.
個人的に,どんなにプログラミング言語が進化してもC言語だけはなくならないと思う(例えC++がなくなっても). Javaがどんなに進化しようがCPUに直接入力できるネイティブコードを吐き出すわけではないので,C言語に取って代わるものではない.
僕の本来の専門分野では現代のハードウェアスペックを持ってしても膨大な計算量がかかってしまう場合が多く, その分野においてはC言語(もしくはアセンブラ)という選択肢以外ありえない(C++ですらありえない).

でもC言語では生産性という面に関しては(他の言語と比べると)あまりよくなくて, しかもセキュリティ的な観点から見ればまったくよくないものができてしまうことも多々ある.

だから例えば,Javaで言うところのGroovyのような言語がC言語にもあればと最近よく思う(もちろんオブジェクト指向である必要はまったくない).
C言語の実効速度(もちろんインラインアセンブラも使えて)で生産性の高い言語ができれば, 世の中けっこういいことが起こるんじゃないだろうか.

というわけでコレはそのうち実装するかもしれない.

卒業

来週水曜日に,おとんと姉貴が大学卒業祝いとして飯をおごってくれるそうです.
ひさしぶりにスーパーの弁当(50円引き)以外の飯が食えるぜ!!ヒョヒョヒョ!

--気になってる記事

Google八分を批判する情報大航海プロジェクト
http://slashdot.jp/articles/06/10/06/0827237.shtml

たぶんこのプロジェクトは打倒googleよりも眞鍋かをりが重要なんだと思う.

再び速度

fridgeの速度アップ作業が2割程度終わったところなんですが,
ここでおもしろい実験結果が出たので載せてみます.
次のコードでそれぞれ速度を測ってみました

--python
i=0
while i < 5000000 :
                   i+=1

--ruby
i=0
while i < 5000000
                   i+=1
end

--fridge
i=0
while i < 5000000 i+=1

全部同じ意味のコードです(fridgeのi=0はいらないけど一応同じにするため書いた)
で、こいつらを20回くらい実行して平均時間を取ってみます.

python : 2.233(sec)
ruby : 2.325(sec)
fridge : 2.195(sec)

...fridgeはやいじゃん!!!
というわけで人並な速度になってきました.
実際中規模程度のプログラムを書くと圧倒的にfridgeが遅くなるんですが, それは今後のチューニングでなんとかするとして.

実はどんなにチューニングをしてもfridgeには速度的に越えられない壁というものがあります.

なぜか.それはfridgeが変な構造をしているからです.
一般的なプログラミング言語というものは大まかに言って

1.フロントエンド(抽象構文木生成)
2.ミドルエンド(中間言語生成,最適化)
3.バックエンド(目的コード生成)
4.コード実行(CPU上なりOS上なり仮想マシン上なり)

といった流れになる場合が多いです.しかしfridgeの場合は.

1.フロントエンド(抽象構文木生成)
2.コード実行(オブジェクト間の連鎖的な通信による実行)

というふざけた構造を持っています.
fridgeのような構造だとミドルエンドとバックエンドがないので,
例えばOSや特定CPUの機能を使ったローレベルな最適化が行いにくくなります.

ではなんで僕はこんな構造にしたのか.一番大きな理由は単に変な事をしたかったからなんですが, 一応メリットもあります.
見ての通りfridgeではフロントエンドから実行までのフェーズを大幅に省略しているので, プログラムを起動してから実行が開始されるまでの時間が短くなります.
もっと言葉を言いかえると,fridgeはプログラムとして非常に「軽い」処理系ということになります.

プログラミング言語が軽いことのメリットは何か.
例えばwebにおけるphpはサーバアプリケーションにプロセスを常駐させ「軽く」しています.
Lightweight Languageなんて言葉がありますが(僕はあんましこの言い方が好きじゃない) 処理系が軽いことは特定の分野において非常に強みとなります.

まとめると,fridgeは「早い」プログラミング言語ではなく「軽い」プログラミング言語ということですね.(while文は早かったけど)

Oprofile

いつも参考にさせていただいているこちらの方でOprofileによるrubyのハックをやっていまして,おもしろそうなのでfridgeにも試してみます.

はずかしながらOprofileを使うのはじめてなんですが,だいたいこんな感じでしょうか.

---------------------------

0804e505 480  2.0655  fgraph.c:0                  fridge   cmapFind
0804fc7c 107  0.4604  (no location information)   fridge   fgGetObj
0804f42e 96   0.4131  fgraph.c:0                  fridge   fgMapStrCnd
0804f3ee 96   0.4131  fgraph.c:0                  fridge   fgMapStrKey
0804f46c 61   0.2625  fgraph.c:0                  fridge   fgMapIntCnd
08050915 46   0.1979  fgsysobj.c:0                fridge   cmapFind
0804f462 40   0.1721  fgraph.c:0                  fridge   fgMapIntKey
08059f0a 34   0.1463  fgsysobj.c:0                fridge   fgSysObjDfMeth
0805248c 29   0.1248  fgsysobj.c:0                fridge   fgSysObjArginiMeth
0804f8b2 27   0.1162  (no location information)   fridge   fgMakeObj
0804fda2 27   0.1162  (no location information)   fridge   fgMethod
0804fbc9 23   0.0990  (no location information)   fridge   fgSetObj
0804f7cf 20   0.0861  (no location information)   fridge   fgGraphGetName
08048ba8 19   0.0818  (no location information)   fridge   .plt
08051ce7 18   0.0775  fgsysobj.c:0                fridge   fgSysObjMethIf
0805a25f 17   0.0732  fgsysobj.c:0                fridge   fgSysObjArryInt
0805a3c5 15   0.0645  fgsysobj.c:0                fridge   fgSysObjArryMeth
0804e598 10   0.0430  fgraph.c:0                  fridge   cmapUpdate
08056cf4 9    0.0387  fgsysobj.c:0                fridge   gSysObjAddeMeth
08051870 8    0.0344  fgsysobj.c:0                fridge   fgSysObjMethDef
0804fd55 7    0.0301  (no location information)   fridge   fgMethDef
0805aaae 7    0.0301  (no location information)   fridge   fgSysCast
0805a368 7    0.0301  fgsysobj.c:0                fridge   fgSysObjArryObj
0805a9c7 6    0.0258  fgsysobj.c:0                fridge   fgSysCastObjInt
08055958 5    0.0215  fgsysobj.c:0                fridge   fgSysObjLeseMeth
0805a00c 4    0.0172  (no location information)   fridge   fgSysObjDotMeth
0804fe3a 3    0.0129  (no location information)   fridge   fgSetMeth
0805acc4 3    0.0129  fgsysobj.c:0                fridge   fgSetValTypeObj
08052d25 3    0.0129  fgsysobj.c:0                fridge   fgSysObjConstMeth
08057626 3    0.0129  fgsysobj.c:0                fridge   fgSysObjSubMeth
0805a834 2    0.0086  fgsysobj.c:0                fridge   fgSysCastDef
08056b37 2    0.0086  fgsysobj.c:0                fridge   fgSysObjAddeInt
080557d3 2    0.0086  fgsysobj.c:0                fridge   fgSysObjLeseInt
080558fb 2    0.0086  fgsysobj.c:0                fridge   fgSysObjLeseObj
08051a8a 2    0.0086  fgsysobj.c:0                fridge   fgSysObjMethReturn
080574b6 2    0.0086  fgsysobj.c:0                fridge   fgSysObjSubInt
0804e700 1    0.0043  fgraph.c:0                  fridge   cmapDes
0804e0cd 1    0.0043  fgraph.c:0                  fridge   cmapMakeBuffer
08056ca5 1    0.0043  fgsysobj.c:0                fridge   fgSysObjAddeObj

---------------------------

...なんで行番号でないんだろ.

一番たくさん文句をタレてるcmapFindという関数はハッシュ表を探査する関数なんですが, ちょうど今やっているチューニングもこの関数をできる限り減らすというモノです.

いまやってるチューニングが終わるとようやくプログラミング言語として人並な速度になりそうな感じなんですが, ガーベージコレクションなんかの処理を適切にやっていないので(なんて言語だ) 次はそっちの実装がいそがしくなりそうです.いつになったらβ版卒業できるんだか.うひょひょ.

速度

「アンタバカなんじゃないの!!」

そんな罵声をあびせれながらも、ギョウザにからしをつけて食べることがやめられません.
定食屋のおばちゃんにすげー嫌な顔されるのが気持ちいいです.

昨日も言いましたが現在fridge/shellのチューニング中です.機能によって5倍から10倍くらい速度アップしてきてます.時々最適化しすぎて期待と違う動作しちゃったりしてますが.かっこわらい.

もうちょいやればweb系のツールくらいだったら実用的なものが作れそうです.ライブラリつくってないから結局遅いのは変わらないんだけど.

話変わって,日本でのOSS支援について.
日本はOSS業界を国をあげて支援している国です.
教育機関での活動や,法人への支援などけっこういろいろやっています.

で、それはいいんですが,これらの支援にはじつは穴がる,と個人的に思っています.
何がって,個人のプログラマに対する支援がない.
IPAの助成要項には法人であることが条件 (これには驚いた)と書いてあるし,その他の支援も大抵コミュニティや法人に対してか学生向けです.
Linuxを代表として数多くの個人プログラマがエライもんつくってんだから, 個人のプログラマに対する支援(特に若い人向け)があってもいいと思うんだけど. おれが知らないだけかな.

OSSの開発現場

OSS(オープンソースソフトウェア)のプロジェクトでは,コミュニティ(というのもあいまいな言葉ですね)が活発に活動するものです.
うちのプロジェクトのコミュニティも活発です.どんな時も参加人数100%です.だって一人しかいないから.バカにしてんのか.
一人で全部やるのはめんどうな人間関係から開放されて良いのですが,市場のニーズというやつがわからなかったりヒソんだバグに気づかなかったりと問題もあります.
そんなわけでSourceForge.jpに登録したんですが状況変わらず.孤独最高!!!!!

...うちのプロジェクトの紹介をします.
fridge/shell(通称fish)はオブジェクト指向プログラミング言語です.
特徴はバカみたいに早くプログラムが書けることです.
シンタックスはrubyやpythonに近いですが内部構造は全然別物です.

いわゆるスクリプト系の言語なのですが,オブジェクト指向のパラダイム的に言うと プロトタイプベースと呼ぶのが正しいでしょう. だから動作のノリはJavaScriptに近いんですね.

fridge/shellはJavaScriptと同様シンタックスエラー以外のエラーをほとんど吐きません. これは宣言されていないオブジェクトに対して必ずデフォルトの動作 (つまりプロトタイプとなるオブジェクト)が設定されているからです.

fridge/shellではこの機能を利用して,デフォルトのオブジェクトの動作を シェル上のパスの通ったコマンドにバインドしています.(だからfridge/shellって言うんですね)
そのためfridge/shellでlsと打てばファイル名一覧が表示されるし,cpとすればファイルのコピーが可能です.

この機能は小さいプログラムを書くときに非常に便利なんですが, これの実装のためにパフォーマンスが殺されて rubyやpythonと比べて若干速度が遅くなっています(現在チューニング中).

というわけでfridge/shellは昔のperlのように bashとかcshなんかのシェルスクリプトのかわりに使ってください.

開発

http://fridge.ddo.jpにて,OSSのオブジェクト指向プログラミング言語/シェルであるfridge/shellを開発しています.

トップページ | 2006年11月 »