日々のつぶやき(98/10/16〜)

1998/10/31(Sat)

佐渡島に社員旅行。バスに乗るまで目的地を知らなかったという…。(^_^;

1998/10/30(Fri)

クラスタリングプログラムはひとまずいったん終了ということに決まる。これ以上ちょっと速い最遠接法を実現する実装も思いつかないし、かといって別のクラスタリングアルゴリズムにすると、別方面に影響がでかいし。

vyama「このままだったら、200日かかるけど、課内にあるマシン全部を使って分散処理させて、複数台で計算すれば一ヶ月以内に終ります。(笑)」
Nさん「確かにそうだけど、その間おれたち何やってればいいの?(笑)」
二人で大笑い。(^_^;

で、後回しにしていたバグを退治。該当箇所を読んでみたら、計算はしていたのだが、計算結果のコピーを忘れていたという間抜けなバグだった。(^_^;memcpy()一閃でバグが消えた。

これでクラスタリングアルゴリズムが一応終ったということにして、次バージョンのプログラムに取り掛かる。私の担当はアプリケーションが抱えているデータをテキストとかRTF形式にして出力する部分だ。色々形式はあるのだが、とりあえず一番簡単そうなテキスト形式に出力する部分に取り掛かる。本体は500行程度の短いプログラムだったのだが、240行程度の関数2つと、20行程度の関数の1つしかない。(^_^;

こんなソースは後でメンテナンスするのが面倒になるから、さっさと、適当な関数単位に分けていった。さらに、何故かLPWORD型の変数にwErrCodeなんて名前(普通はlpwErrCodeか、pwErrCodeだろう)が付いているとか、その他の変な変数の命名の仕方を直したりしてしまう。

良く読んでみると、このプログラム、自前でファイル出力のバッファリングをしているのだが、バッファリング部分がプログラムの中に埋めこまれてしまっていて、モジュール化されていない。おかげで、用意されたバッファサイズより大きな行を出力できないというバグは抱えるわ、バッファリングに関係する変数をそこかしこでいじらないといけないわで、問題が大きすぎた。

プログラム自体は、単純にシーケンシャルな書き込みしかしていなかったので、HFILE、OpenFile()、_lwrite()、_lclose()(って全部Win16時代の名残じゃんか。(^_^;これを書いたのは--書いたのは私じゃない--今年の1月なんだけどなぁ。)を使っていた部分を全部、Cの標準入出力ライブラリを使って書き直してしまう。バッファリングはライブラリ任せにしてしまう訳だ。このおかげでWin32APIを使った時ほど細かいエラー制御が出来なくなってしまったが、その分プログラムはすっきりした。もっともエラー制御に関しては元のプログラムだって、ファイルがオープンできないか、書き込めないか(書き込めなければディスクフルというロジックになっていた(^_^;)の2つしかチェックしていなかったのだから、それほど神経質になることはない。

外にも、中間ファイルの名前が固定だったのをGetTempFileName()を使って、まともな中間ファイル名が得られるようにしたりとか、本体以外のところで、ファイルのコピーが、ファイルをオープンして読み込んで、出力ファイル側に書き込むという動作だったのをCopyFile()を使って書き直したりとかしているうちに、なんかプログラムの原形がなくなるほどの改造になってしまった。(^_^;

そこまで改造して、今まで他の人が作ってきたモジュールとの結合検査をしてみると、無気味なことに一発で動いてしまった。おお、こんなことは滅多にないぞ。(^_^;大喜びで帰ろうとして気がついた。今回のバージョンでは表の内部形式がすっかり変更になっているのだが、肝心要のそれに関する変更を忘れている。(^_^;何やってんだか。←vyama

うちの会社は小さいのだが、親会社がそこそこ中規模なので社内に組合なんてモノが存在する。で、秋闘という労使交渉の前の組合員への交渉方針の是非を問うのだが、その方針の中に「有給休暇を増やせ」というのがあったので、「どうせ有給休暇なんて増やしても、みんな取ってないと思う。ただ、データがないから議論のたたき台としてどの程度有給休暇を取っているかの数字が欲しい」という意見を出しておいた。

そしたら今日、その意見集約結果に回答が載っていて「平均7日」という答え。今一年間に付与される有給休暇って13〜17日以上はあるから(勤続年数によって与えられる日数が違う)、「平均的な」人は半分程度しか消化していないってことじゃん。使わない(もしくは使えない)有給休暇なんかもらったって、組合の幹部はうれしいかも知れなけど、組合員にはちっともうれしくないだろう。

で、さらによくわからないのが、「平均7日」という数字が議論のたたき台になるであろうという認識。この場合、平均なんてのはどうでもよくて、全体のヒストグラム(分散状況)が大切になってくる。極端な話、半分の人が年間14日消化して、もう半分の人が一日も消化しなかったという分散状況だったら、有給休暇を2日追加するのは(有給休暇をほぼ玄海まで使っている)半分の人がメリットを得られる可能性が高い。これだったら要求する価値はある。逆にほとんどの人が7日前後しか消化できないでいるんだったら、どうせほとんどの人が消化できない有給休暇をさらに1〜2日増やしてもらった所で、どうせ捨てることになるのだから、ほとんどメリットがない。だから「平均」なんてのを出して、議論のたたき台になると思ったら大間違いなんだよな。分かって言っているんだろうか?

ちなみに明日(といいつつ、もう今日だ(^_^;)は社員旅行なので、日記はお休み。といってもこのところ、週末は日記の更新をサボっているから、いつも通りといえばいつも通り。(^_^;

1998/10/29(Thu)

出社すると、いきなり上司のNさんから声をかけられる。Nさんは進捗報告代わりにこの日記を読んでいて(最近、過激なことが賭けなくなったのはそのせいだったりするかもしれない。(^_^; )、「ベイスターズの優勝を知らないなんていかんなぁ」と軽くジャブを繰り出してくる。

苦笑いをしていると、クラスタリングプログラムで困っている状況を見かねて、助け船を出してくれた。点の数が多すぎて、組みあわせの数が膨大になるからデバッグできなくなっているなら、点の数を8くらいに押さえれば組み合わせの数なんか、32個しかないからデバッグできるだろうという訳だ。考えてみれば当たり前の話で、頭に血が上っていて、そんな当然のことすら気がつかなくなっていたのが恥ずかしい。

で、早速文字数を絞ってデバッグをしてみたのだが、やっぱり結果が「だんご状態」になってしまって、1つのクラスタにほとんどの文字が集中してしまう。これは計算機に頼らず、自分で正解を出してみて、どこから計算が狂いはじめるのか調べるのが先だと思って、自分で紙と鉛筆を使ってクラスタリングをしてみたら、なんと計算機で出力したのと同じ(経過を含めた)結果が出てしまう。(-_-;げろげろ。

実はこのクラスタリングプログラムは、前に作った人がいてそのソースをもらっていた。比較的短いフィルタ系のプログラムだったのだが、ドキュメントもソース中のコメントもほとんど皆無。ソースプログラムをくれた人も、その人自身が書いた訳じゃないので、ほとんど分からないと来ている。中身を読むと、指定されたファイルを読み込んで、何かの操作をし、別のファイルに結果を書き込む位は読み取れたのだが、入力ファイルでの仮定とか、出力ファイルの形式とかのヒントもなかったし、ソースファイル中にaとかbとかの一文字変数が多用されていて、とにかく意味がつかめない。以前読んだ時は「こんな入力の仮定も分からずに内部のアルゴリズムを読むなんてのは無理だぁ!」と投げたのだが、仕方なしにもう一度そのソースファイルを読みはじめる。

で、最初からプログラムの実行順序に沿って眺めていったら、私の作ったプログラムとテーブル操作のパターンが非常に似ている部分があった。おや?と思って、「もしそのテーブルが私の書いたプログラムの該当部分と同じだったとすると」という仮定で、他のデータ構造を眺めていったら、おお、この変数はこんな意味に違いないぞ、という感じで、どんどんプログラムを読み進めていけた。で、一通りのプログラムの構造が分かって、何をやっているのかほぼ全部分かった所で…がっかりきた。元のプログラムと私のプログラムではクラスタリング手法が全然違うのである。(+_+;私の作ったプログラムは最近接法によるクラスタリング、元のプログラムは最遠接法によるクラスタリングだった。

これではクラスタリングの結果が違うのは当然。クラスタリングというのは「クラスタ距離の定義」、いってみればどのような基準でクラスタが近いと断定するかという「価値観」で決まるから、その価値観が違っているならクラスタリングの結果が違うのは当たり前だのクラッカーなのである。例えば、「人種的に同じグループ」に分けた場合と「宗教的に同じグループ」に分けた場合、おのずと結果は違うだろう。そういう間違いをしていて、あ〜だ、こ〜だと悩んでいた訳だ。バカだよなぁ。

私のプログラムでは巨大なクラスタが出来るのに、元のプログラムでは出来なかったのかも容易に説明がつく。最近接法では、(何とか効果という名前が付いていたのだが、名前を忘れた)大きなクラスタは、小さなクラスタよりも大きくなりやすい傾向があるので、それを何回も繰り返していると、やたらと大きいクラスタ1つと、その他小さなクラスタが沢山という状態になりやすい。(と、どこかの文献だかWWWページに書いてあった。)最遠接法の場合、逆に小さなクラスタほど大きくなりやすい傾向があるので、全体に分散したクラスタが得られることになる。分かってみれば「な〜んだ」の世界である。

で、早速最遠接法でプログラムを書き直す。書き直し自体はそれほど難しくはなかった。実際の作業は、最近接法に最適化した部分を全部元に戻して(ソースコード管理ツールを使っているから、戻すのは簡単。)、3行ほど書き直しただけで終わり。ついでに前のバージョンでは不必要になったメモリをなるべくシステムに戻すように、こまめにfree()していたのだが、以前そのfree()でやたらと時間を食っていたのを思い出したので、思い切ってこまめにfree()することも止めてしまった。(これは後で復活させるかもしれないが。)さらについでに前のプログラムでは、クラスタリンググラフの計算(どのクラスタが一番近いか)をしながら、クラスタリングセットの計算(あるクラスタにどのような点が含まれているか)をしていたのだが、同時にやると途中でメモリ確保とか解放を繰り返さなくちゃいけないのが分かったので、クラスタリンググラフの計算とクラスタリングセットの計算は完全に分離した。同時に巨大になるクラスタリング間の距離を記述したテーブルへのアクセスを減らせる場合が見つかったので、それについての最適化も同時に組み込んだ。副作用(?)で、仮想メモリから仮想メモリへのコピーがなるべく起こらないようにした。とはいっても400Mの仮想記憶へのアクセスを繰り返しているのだから、多少その巨大テーブルへのアクセスが減ったとしても。焼け石に水程度ではある。

で、デバッグに移った。しかし、実は最近接法と最遠接法とでは計算量が桁が違う。プログラムの流れを追うと同時に、12文字について最遠接法によるアルゴリズムで紙と鉛筆を使って、計算機のはじき出した結果と一致するか調べたのだが、検算する手間が半端じゃなかった。(^_^;結局12文字のクラスタリングについて「おかしそうな所」を検算し直すだけでも1時間ほどかかってしまう。一応検算結果と計算機のはじき出した答えが一致したので、あとは最適化かな?

ちなみに、前の担当者が作ったプログラム(以下Program A)と同じアルゴリズムにすると破綻するというのが分かっていたので、それは参考にしなかった。このクラスタリングプログラムでは2万点(≒20K点、以下N)のクラスタリングをするということを前提にした上での話なので念のため。ちなみにProgram Aはせいぜい6K点ほどのクラスタリングを意識して書いたもののようである。(そうでなければ、20K点の場合のメモリ消費量の説明がつかない。(^_^;)

まず、Program Aでは次のようなセルを点の組み合わせ分だけ作る。


struct tagCell1 {

    WORD nIndex1;

    WORD nIndex2;

    WORD wDistance;

}

Windows95だったら、sizeof(tagCell)は8(Paddingがあるから6にならない)で、Nの組み合わせの数は20K x 20K / 2 = 200Mだから、素直にファイルに格納したら1.6G(200M x 8)のファイルになる。で、こいつをwDistanceに関してソートしなくてはならない。1.6Gbyteのデータのソート…。当然、オンメモリのソートなんて考えられないから、分割ソートするんだろうが、それにしても考えるだけで頭が痛い。(^_^;最低一週間はハードディスクカリカリで終るはずだ。

で、ソートしたら、wDistanceは不要になるので、次のようなデータ構造に変換する。


struct tagCell2 {

    WORD nIndex1;

    WORD nIndex2;

}

元のtagCell1構造のファイルが1.6Gbyteファイルなら、tagCell2を使ったファイルは800M(200M x 4)ある。単に変換するだけでも、1.6Gbyte + 800Mbyte = 2.4Gbyteのディスクスペースが必要になる。すでにFAT16ドライブ1つ程度ではどうにもならないレベルになっている。(^_^;(で、実際はソートされたtagCell2並びがProgram Aの入力だったりする…。そんなのコメント無しに分かるかっての。(^_^;)

さらに続けよう。1.6Gbyteのデータのソートが出来たとして、さらにtagCell1からtagCell2への変換がうまくいったとして、この800Mバイト(組み合わせ数200M)のソート済みデータを一気に仮想記憶上に読み込み、ものすごく単純にゆがめれば、次のようなループを繰り返す。


for (int i = 0; i < 200M; i++) {

  //ちょっとした処理

  for (int j = i + 1; j < 200M; j++) {

    //何かの処理

  }

}

繰り返しの回数を計算してみると、200M x 200M / 2 って、20000 M x M = 40000 T x K = 20000 P。え?ギガの1つ上に、テラがあって、もう1つ上にペタがあるのは知っていたけど、そのもう1つ上の所まで行っちゃうの?(^_^;まさか生きているうちにこんな数字を相手にするとは思わなかった。(^_^;ところでペタの1つ上ってなんて言うのか知っている人がいたら、メールを下さい。(^_^;

もっともProgram Aでもそれなりに最適化されていたりして、ループの回数はもっと減っているし、20000Pの線形サーチなんてことはないのだが、どのみち800Mbyteの仮想メモリが必要なことは明らかなので、止めた。ちなみに私のアルゴリズムでは、400Mbyteの仮想メモリを使う。(計算しながら、必要でない値を捨てるというのが前回の高速化アルゴリズムの主眼で、それでメモリを大幅に節約できたのだが、残念ながらこれは最遠接法にはうまく適用できない。)最遠接法に特殊化して、ソートしながら「いらないデータ」は捨てていってアクセスしないようにしているので、もっと効率的に動いてもいいはずなんだが…。世の中うまくいかないね。(^_^;

なんかクラスタリングアルゴリズムばっかりに関っていたら、後から後からやんなきゃいけない仕事が目白押しだということがわかる。げろげろげろ。

1998/10/28(Wed)

出社してから、メールとか掲示板に目を通すという「お仕事前のお約束」行事をしていると、Iさんから「LoadLibrary()が成功しないんですけど…」という相談を受ける。相談を受けてから調べて気がついたんだけど、Win32だとLoadLibrary()って失敗した時にはNULLを返すんだ。確かWin16では32以下のエラーメッセージを返すんだと記憶していたのだが、いつの間にか仕様が変わっていたんだ。(^_^;今ごろ気がつくなんて間抜けだなぁ。

クラスタリングプログラム。気になる部分で途中経過のログを出力させながら、計算結果の妥当性を検証したが、とりあえずおかしな所は見つからない。というか見つけるにしても、ログ自体が5〜6M程度になっているのでまともに見る気が起こらないというのが本当のところ。何かいい検証手段はないものか…。

ログ出力のところで以前便利だから使ってみれば?と言われていたSTLライブラリを使ってみる。namespaceがどうのこうのというのはよく分からなかったし、iteratorとかいう概念もよく分からなかったのだが(テンプレートに関してまともに勉強していないのがばればれ(^_^;)、vectorテンプレートをサンプルの見よう見まねで使ってみたら結構さくさく動いてしまったので逆に驚いた。(^_^;これも一通り目を通しておかなくては行かんなぁ。いつになることやら。

「空想非科学大全」を読む。IQ600というのが、10^314人に1人の割合の天才だというのは結構笑えた。こんな奴、一人でもいたら大変なのに、これに成績でタメをはれるのが5人も小学校のクラスにいたんじゃ、たまんないよな。(^_^;

ネットスケープのセキュリティーホールに関する記事を読む。タイトルが「バグまみれのNavigator」。「バグまみれ」というからには、沢山バグがあって使い物にならないぜという記事かと思えば、SSLがらみの間抜けといえば間抜けなバグの件についての記事。内容とタイトルがマッチしていない。英文(原文)のタイトルは"Bug compromises Navigator"だった。一体どう訳せばここから「バグまみれ」なんて言葉が出てくるのだろう?("Bugs...ならまだしも。)直訳すれば「バグがNavigatorの信用に傷をつけた」だし、タイトルっぽく訳すんだったら、「Navigatorの信頼性にキズ」とか訳してもいい。翻訳ど素人の私からみても「バグまみれのNavigator」は原文の意味とかけ離れてしまっていて、はっきり誤訳だと思う。

個人でやっている訳じゃないだろうから、翻訳した人とテクニカルチェックなどの校正をやった人とは別のはず。で、両方とも内容とかけ離れたタイトルを許容してしまうというのは恐れ入る。沢山記事を扱っているだろうから、多少のミスは目をつぶるとしても、今回のミスは目に余ると思う。超訳するなら超訳するので構わないのだが、伝えている意味が全然違うんじゃ、超訳どころかもはや訳者の作文である。勘弁してもらいたい。

「韋駄天」シリーズのオーテックからベイスターズ優勝記念限定発売ということで、特別キャンペーン製品の広告が届いた。え、ベイスターズっていつの間に優勝したの?(^_^;興味のある人はオーテックのページを参照のこと。ちなみに私はしばらくマシンは買えない。(貧乏なのよ…。(^_^;)

1998/10/27(Tue)

定例会議での出来事。某社から最新鋭マシンを提供してもらえることになりそうだという。

Nさん「この課で一番スペックの低いマシンを使っているのは誰だ?」
vyama「はい!はい!はい!私です!新しいマシンは私に下さい!」
Nさん「じゃあ、その次にスペックの低いマシンを使っているのは?」
Oさん「僕ですね。」
Nさん「じゃ、そのマシンはOに決まり。」
vyama「え〜、なぜ?」
Nさん「だって、11月にMacを買うことになっているじゃん。」
がっくり。私はG3マシンを購入するつもりだったのだが、NさんからはiMacの購入を検討するといわれてさらにがっくり。いくらメモリを積んでも、ディスプレイのサイズといい、拡張性といい、あれが開発マシンになるとはとても思えない。だからMacは近づくなかれと私の第6感は言っていたんだ。(-_-;

クラスタリングの計算の結果が変だという指摘をNさんから受ける。結果を見てみるとクラスタの分割がいわゆる「チェーン効果」っぽくなっていて、1つのクラスタだけがやたらとぶくぶく太っている。バグなのか、正常な計算の結果「チェーン効果」が出てきたのかはよく分からないのだが、少なくとも正常な計算の結果だというなら、それを証明しなくてはならない。

最初は、アルゴリズム全体は正しいのだが最後の詰めのルーチンにひどいバグがあるんだろうなと思っていた。そこで、最後の詰めのルーチンの直前の中間結果をファイルに出力してざっと見てみるが、どうもその中間結果からは、1つのクラスタがぶくぶく太っている結果が導き出せるのはほぼ確認できた。そうすると、それまでの計算結果がおかしいんだろうなと思って、途中の計算結果を全てファイルに書きだしたら、これが80Mbyteもある。(^_^;こんなもの調べられるはずがない…。どうやって調べようかと思案しているうちに、一日が終る…。

海外の製品のローカライズ作業の進捗もかなり心配。読み返せば読み返すほど修正したくなる部分が増えてくるし(というか、全面的に書き直したくなる)、「いくらなんでもこいつはさっと読めば日本語として変だと分かるだろ」なんて所が結構ある。「…する場合があることがあります。」なんて文を目にした時には思わず泣けてきた。(なんで「…する場合があります」と訳さないの?)これがプロの翻訳?

もっとも翻訳している人の母国語が日本語じゃないかもしれないので、そこは割り切らないといけないかもしれない。でもね。翻訳を仕事にしている人だったら、文章作成ど素人の私に「ここの表現が変」なんて、指摘されるだけでも不名誉のはずだ。ところが、「とても指摘せずにいられない」指摘が1ページに何ヶ所もあるんだもの。勘弁してほしいと思う。(^_^;言っておくけど、私の英語力はせいぜい英語のマニュアルを辞書を引きながら四苦八苦しながら読むという程度なので念のため。

今日憶えていた笑える訳。"with simple process"→「単純な手順で」これって、普通「簡単な手順で」と訳そうと思わないか?翻訳の素人に揚げ足を取られるような仕事は勘弁してくれと思った。

1998/10/26(Mon)

朝、毎週開かれる定例会議に時間を合わせて出社したら、席に誰もいない。おかしいなと思って、社内を探してみたところ、会議室の予約リストに上司のNさんの名前が…。え?この会議って一時間前に始まっているじゃん!青くなって扉を開いたら、目の前に上司のNさんの苦笑いの顔が目に入る。がちょ〜ん。

後で聞いてみると、先週の定例会議で今日の会議の話をしていたとのこと。そういえばそうだった。臍を噛むけどもう手遅れ。(^_^;

その日はその会議でほぼ一日つぶれてしまった。

1998/10/25(Sun)

SF大会の準備会に久しぶりに出席。途中で企画を計画している団体の代表者がやってきた。結構面白そうな企画で、大会自体を巻き込んだ企画なんてのも、大いに結構だと思っていたので、内心大いにやりましょうと思っていたのだが、会長はポーカーフェイスだし、宿泊担当者が宿泊人員のキャパシティーに関する物理的な制限事項を強調するので、向こうも戸惑っていたようだ。もっともいつものSF大会と違って、「ポリシーのないのがポリシー」という変な運営方針なので、そのへんが一番戸惑っていた所かもしれない。(^_^;

とりあえずお互い円満に話し合いが進んだと思うし、「企画の予約」もしてもらったので、最初の滑り出しとしては上々かな、と思う。スタッフ登録も正式に済ませたし、これから忙しくなるぞ。(^_^;

1998/10/24(Sat)

なんか、「疲れをとろう」と気合を入れて寝ていたら、一日寝たままで終わってしまった。(^_^;

1998/10/23(Fri)

昨日届いたヘルプファイルをざっと見てみる…つもりだったのだが、ざっと見ただけでも英語をそのまま日本語訳にしただけという感じで、意味が分かりにくい所とか用語・用法に問題がある所が続出。まあ、まだβバージョン前だから辛うじて許せるけど、普通の日本人には意味が分からないような英単語をそのままカタカナで訳しているのにはまいった。この翻訳のレベルじゃ、私の拙い英語力でも役に立ちそうなくらい。(苦笑)

時々思うのだが、日本語ローカライズの作業でHELPとかマニュアルを訳す場合なんてのは、英語をそのまま訳すより、文の組み立て方とかをすっかりかえてしまって日本語の文の組み立て方をしたほうがいいのではないかと思う。正確で教科書的、英語の文構造を反映した翻訳も大切だとは思うが、読むのは日本人だというローカライズの特殊性を鑑みて、もっと内容を的確に伝えられるような翻訳は出来ないか。

1998/10/22(Thu)

懸案のクラスタリング処理アルゴリズムだが、途中経過のログを取りながら動作を確認してみると、どうもうまくいっていない。まあ、アルゴリズム自体もかなり「ばくち」的なアルゴリズムだし、短いプログラムだけれど、説明されなければほとんど解読不可能なアルゴリズムになっているので、本人も疑心暗鬼の部分がある。幸いちょっとした間接参照のミスがバグの原因だと判明して、それを修正してクラスタリングをやらせてみると、そこそこ満足の行く程度のグループ分けになっているようで安心する。これで懸案が1つカタが付く。

もう1つの懸案は、私が関っているモジュールが出力するRTF形式のファイルを一太郎9で読ませると、中身がぐちゃぐちゃになって読めないということ。しばらく調べてみたのだが、RTFを微調整しながら、調整済みのRTFファイルを一太郎9に読ませるという作業を繰り返した所、2時間ほどで一太郎9のバグだと判明して一安心。どういうわけだか、一太郎9で\paperwN\paperhN(用紙サイズの指定コマンド)をRTFファイルに入れると、段落設定がめちゃめちゃになって表示がおかしくなるらしい。「表示がおかしいRTFファイル」に「表示がまともなRTF」を近づけるように微調整しながら原因を探っていたので、原因が特定できたのと問題の解決方法を見つけるのが同時だった。

解決方法は単純で、スタイルシート指定の後に狂った段落指定状態を修正する\sectdキーワードを入れるだけ。修正も程なく済んだ。しかし、修正したプログラムを今見てもつくづくひどいなぁと思う。_write とかを使っているのはまだしも、素直に_write を使うと遅くなると思ったのか、自前でバッファリングをしていて、しかもそのバッファリングの制御変数(例えばどの程度今バッファリングをしていて、あとどの程度までバッファリングできるか)を上位のプログラムできっちり管理しないといけないような構造になっていて、ほんのちょっと修正するだけでもバッファ溢れを心配して前後の文脈にひどく気を使わざるをえない。こんなのfputsでも使えば、問題に対する最善のバッファリングではないにせよ、そこそこの性能のバッファリングをライブラリレベルでやってくれるのに。おまけに自前で用意したバッファリングアルゴリズムに大穴があって、それを取り繕うためにこまめに_write とかをこまめに呼ぶんじゃ何のためのバッファリングかとあきれてしまう…。つくづく書き直したほうがいいと思った。

絶対遅れるだろうと踏んでいたのだが、OEM提供元からHELP、リソースファイル、ライセンスなどに関する日本語訳のドキュメントが届く。マニュアルは一日、遅れることになったのだが、まあそれは許してやろう。明日からはその進捗具合、出来具合のチェック作業に追われることになる。

以前から読みたいと思っていた「封神演技」の単行本が手に入る。むさぼるように読む。読みにくい漢字の人名とかものの名前、地名が出てきて読みやすいとは言えないが、文句なしに面白い。でも少年ジャンプに掲載されているヤツとはかなり違うような気がする。(^_^;

1998/10/21(Wed)

スケジュールの打ち合わせを上司と行う。今までは私が作業する前の段階で色々やっていて、私のところまで仕事が回って来ないという状況だったのだ。で、手が空いている時間を使ってMacのプログラムの勉強をしたりしていた訳だ。

で、薄々分かってはいたのだが、11月になると、OEMの受入検査責任者(といっても実質作業するのは私一人)、今のプロジェクトのMac版の主席プログラマ(といってもMac版プログラムの経験というか勉強したことがあるのは私だけ(^_^;)、ついでにWindows版に関してもちょこちょこやることがあるという、3重苦状態になることが分かった。(^_^;フルタイムでWindows版だけやって、半年間ろくに成果をあげていない程度の実績なのに、これだけ負荷がかかるとは…。こいつはヘビーだなと思う。でもそれでも同じチームの人と比べると負荷が軽いように見えるのは何故なんだろう?(^_^;まあ、とりあえず、今日まではいいけど、明日から地獄のスケジュールだな。

私の担当分(といっても私が書いた訳じゃなくて、前任者から引き継いだだけなのだが)で、「どうせ次のバージョンでも大して工数は発生しないだろう」と高をくくっていた部分で、次期バージョンで仕様拡張した結果、とんでもなくでかい工数が発生することが判明する。どうしようか途方に暮れた。実際、その部分は前任者が「ここは他のプロジェクトからソースファイルを借用しただけだから、説明しろといわれても分からん。」と宣言されていた部分だったので、「前任者が分かんないんだったら読んで理解する必要はないよな」とソースの把握をサボっていた部分だったからちょっと修正するといっても手に負えそうもない。どうしよう…。

iMacとかMacOSの販売状況に関して、1998/10/12(Mon)に書いたのだが、その反論(バカなことを書くんじゃないというお叱りメールとも言う。(^_^;)が届く。届くといっても実際に届いたのは、その翌日なのだが、書くのをサボっていたり、書くのをサボっていたり、しかも書くのをサボっていたりという状況だったので、今ごろになって掲載。(^_^;メールを下さったのはコンピュータ関連の「社内便利屋」を自称するSさん。全文引用しようかと思ったのですが、引用するには長すぎるし、「ばらせない」ことも書いてあったので(^_^;、適当にはしょっています。(一応改変、引用は許可を得ているので、念のため)

言いたいことは山ほどあるのですが、まずはAppleの流通について説明したいと思います。

現在のAppleの体制は、Apple本社が全世界を掌握するといった形になってます。以前は世界各地で体制・対応がばらばらだったのですが、本社で統括し、全世界統一で活動を行うように変わりはじめました。そして、その本社のお膝元、アメリカの流通体制はあまり良くありません。例えば日本では、メーカ、販売店の強力な協力体制があり、モデルチェンジ前には「そろそろ在庫処分してね」というのを販売店にほのめかして、極力不良在庫を抱えないようにしています。ところがアメリカではG3が出始めた時期に、Intel系で言えば486クラスの604マシンの在庫を大量に抱えていたくらいです。

これは意外。アメリカのコンピュータ関係の市場って、日本よりずっと規模がでかいから、流通もずっとしっかりしているはずだと思ってました。アメリカでは今後10年程度でソフトウェアの販売はほぼ100%オンラインショッピングの形態になるだろうなんて予想も聞いたことがあるのですが、ひょっとすると流通の状態の悪さがその傾向に拍車をかけているかもしれません。

本社としては、このような流通状況を整理する為に、今年の春から色々やってまして、例えばiMacが特定店舗でしか販売されなかったのもその一環です。で、本社は日本の流通状態を知らないものだから、全世界に「流通を改革しろ」と号令を投げ、本社がアメリカでやったようなことをAppleJapanが日本でもやるように指示しました。その結果日本では色々な問題がでたわけです…。結局本社にきちんと日本の状態を伝えられないAppleJapanが悪いといえばそれまでですが(^^;…

ソーダ、ソーダ。やっぱりAppleJapanが悪いんだ。おいらは間違っていないぞ。(^_^;←と言い訳してみる。

Rhapsodyについても誤解があるようなので、少し説明します。Rhapsodyは Machの上に BSD互換機能を載せ、それをカーネルとしてます。そのOSに FoundationKitというクラスライブラリがのり、数値、文字列などの基本クラスを定義してます。

その基本クラスと 表示機構としてPostScriptを使ってApplicationKitというクラスライブラリが構築されており、これを用いてプログラムを書くんですが…要するに、"Macintoshのプログラムとは、構造や基底からしてまったく別"になります。多分現在のMacintoshのプログラム技法は全く役に立たなくなります。

また、これとは別にMach+ BSD部分の上に"Macintoshエミュレータ"を実装し、その上でMacOS8.xを実行し、既存のプログラムを動かす事ができます。これが BlueBoxと呼ばれているものです。BlueBoxの上ではほんものの MacOSが動いているので、非常に互換性は高いのですが…MacOS8.xからなんも進化しない訳です(^^;

BlueBox、YellowBox…。ああ、すっかり忘れていた。(^_^;そうですよね。Machカーネルですものね。MacOSとは全然別のOSになりますよね。(_ _;;

で、Macデベロッパからもユーザーからもそっぽ向かれました。

確かに1から書き直しじゃ、開発効率が上がったとしてもデベロッパもつらいし、1から買い直さないといけないユーザーもつらいですよね。

JobsがAppleに戻って、少し変わりました。まず、MacOS8.xをがんがん修正し始めました。MacOSをもう数年使おうというわけです。逆にRhapsodyは(表向き)捨てられました。MacOS X Serverという名前を冠されとりあえず発売はされますが、次期OSではなくサーバOSとしてトーンダウンされ、ひっそりとリリースされる事でしょう。

次期OSは MacOS Xという名前で、来年リリースと発表されました。内部的に見ればRhapsodyそのものですが、MacOS互換APIセットの提供だとか、画面まわりが、画面回りがPostScriptから QuickDraw/PDFベースに変更されているなど、今までのデベロッパ、ユーザーを取り込むような姿勢を見せています。

う〜、ノンプリエンピティブなマルチタスクOSの方が絶対プログラムは組みやすいのにぃ。それはMacOS Xであって、MacOSクライアントじゃないんだ。(;_;)今ごろになって、「協調的マルチタスクでプログラムを組む」なんて時代遅れだよ〜。シクシク。(もっとも数年後にはMacOSもノンプリエンピティブなマルチタスクOSに変身するらしいが、そんなの待っていられないしなぁ。(^_^;)

ちなみに、この引用メールだが、原文はもっと長くて詳細に書いてあったので念のため。一応改変許可は取っているのだが、改変した以上文責は私にあるので、非難、批判などは私にどうぞ。また、このメールを送ったのが誰かなんて邪推も無用。例えば、私のMacの師匠が送ってきたメールなんだろうと考えるのは、考えることさえ止めていただきたい。(^_^;

古いゲームのエミュレータを某知人から教えてもらう。よく出来ているし、エミュレート可能なゲームの数も多い。エミュレート可能なゲームのリスト眺めているだけでも、そのゲームがゲームセンターに並んでいた当時の状況が思い出されて、ひたすら感動。中でも感動したのがStar Wars。これは高校生くらいの時に手持ちのこずかいを使い果たすくらいはまったゲームだ。もう二度と出来ないゲームだと思っていたので、動かしてみた時には涙が出てくるかと思った。でも、このゲーム、こんなに難しかったっけ?(^_^;昔は10面位までは楽々クリアーしていたはずだけど、今やってみると3面クリアーでもかなりきついぞ。(^_^;

1998/10/20(Tue)

この前から取り掛かっているクラスタリングの計算プログラム。何とかコーディングが終って、デバッグ作業に入る。ループの境界条件が1違いで無限ループに入ったりとか、初期化すべき変数を初期化し忘れて一般保護エラーが起きたりとかいったありがちなエラー(^_^;が数個見つかったが、何とか動いているようだ。

で、一通り最初から最後まで動かしてみたら、700個の点を200クラスタに(最近接法で、というか新しいアルゴリズムは最近接法に特殊化したアルゴリズムだったのだが)分割するのに、前は、1分近くかかっていたのが、10秒ほど(10秒縮まって50秒じゃないぞ。(^_^;)に縮まった。クラスタリングの結果をざっと眺めてみたが、致命的なことにはなっていないようだ。厳密に計算結果を検証するのは明日以降にするとして、今度は3000点を200クラスタに分割してみる。

ある程度時間がかかるのは覚悟していたのだが、処理時間およそ1分。以前は10分以上かかっていたし、素直にプログラムを組めば、処理時間は点数のおよそ3乗以上に比例するので、点数が4倍以上に増えたら、10分以上かかってもおかしくないのだが、予想よりもずっと速い数字が出せて大満足。大体以前(多分4年くらい前)はミニコンクラスのマシンを3週間ぶんまわしてやっと3000点のクラスタリングが出来たといっていたから、新しいアルゴリズムはマシン性能が上がったのを考えても相当速い。ちなみに素直に組めば点数の4乗に比例するだけの計算時間がかかるはず。もともとのアルゴリズムも点数のおよそ3乗程度に計算時間の増加を押さえたという点では評価していいが、今度のアルゴリズムは結構時間をかけただけあって、我ながら相当速いと思った。(ちょっと自慢)

で、早速20000点を200点にクラスタリングしてみる。さすがにこれは時間がかかって、計算の進捗具合を示す表示がちょっとずつしか動かない。この割合で計算が進行したらどの程度かかるか手元でぱっと計算してみたら、あと3週間必要となって、また落ち込む。もう一度アルゴリズムを考え直しじゃ。(;_;)

あまりに悔しかったので、とりあえず、そのプログラムは動かしっぱなしにして、別のマシンを使って、WWW上で参考になりそうな所を探してみたのだが、高速クラスタリングをしているプログラムのソースファイルなんてのは探せなかった。う〜む、一体どうしたらいいんだろう?

あれこれ探してみたり、作ったプログラムで余計なことをして計算時間を食いつぶしていないか必死で探してみた。しかし、アルゴリズムが分かりにくい割には、大した行数じゃない(200行程度)で、特に変な処理をしている所も見つからない。あ〜あ。どうしよう…。

30分ほどあれこれ悩んで、ふと先程のプログラムの進捗具合を見てみたら、なんか妙に進捗している。おまけに進捗具合が最初に比べて妙に早くなっている感じだ。確かに計算が進めば進むほど計算のペースが速くなるアルゴリズムだというのは分かっていたのだが、予想したよりも進捗が早くなるペースが速い。まあ、このペースで行けば3日くらいで計算が終るなとざっと見積もる。アルゴリズムを差しかえる前は3ヶ月経たないと計算が終らないという悲惨な状況だったので(^_^;、それに比べれば随分マシとちょっとだけ慰められる。

で、計算の進捗状況をぼ〜と眺めながら、どうやったらもっと速いアルゴリズムが出来るんだろうか?と考えていた。で、ぼ〜と眺めていると、やっぱり変。私の予想では進捗が進んでもせいぜい進捗具合に比例する程度にしか計算ペースが上がらないはずなのだが、どうみても私の予想以上に比例して計算ペースが上がっている。おかしいなぁと思ってソースコードをよくよく読んでみたら、fail safeのつもりで何気なく入れた3行ほどのifブロックコードが、最初は計算時間を増やす程度にしかならないのだが、後になればなるほどテキメンに効いていて、予測ではNを点の数として、O(N^3 x logN)程度かかるはずの計算量がO(N ^ 2)程度には収まっていることが分かった。更に詳しく読んでみると、O(N ^ 2)かかるのは、距離の計算の部分だけで、クラスタリングの計算に関してはせいぜいO(N)、最悪O(NlogN)程度の計算量で済むことが分かった。これは速いはずだ。(^_^;もう鼻タカダカ。(^_^;

いつもだったらこんなfail safeのコードは入れたとしても関数I/Fの部分だけだし、せいぜい入れたとしてもASSERT程度だ。どちらかと言えば、命令パイプラインを円滑に流したいということを考えたら、外してしまったかもしれないifブロックである。事実調べたら入れなくてもちゃんと動くようなのだが、入れないと飛びっきり計算速度が遅くなる(ただし当初予測程度だが(^_^;)ことも同時に判明。スペシャルラッキーとしかいいようがない…。(^_^;やっぱり神様って日ごろの行いがいい人には幸運をくれるものだ。(^_^;

実際終ってみれば計算時間は3時間ちょいで終了。最後の辺りは、実際の計算処理よりも計算結果の進捗表示処理のほうが重いんじゃないのか?と思えるくらいに計算スピードが上がった。いくら速くなったからといっても、一晩は絶対かかると思っていたのだから、かなり満足できる結果である。偶然に近いんだけど、出来てしまえばこっちのものよ。(^_^;

あとは検算結果が無残なものにならないように…(^_^;。

1998/10/19(Mon)

前に作ったプログラムが、設計した段階での想像以上の規模での動作をしなくちゃいけなくなった。で、動かしてみると、仮想記憶のトリックにべったりのプログラムで、メモリのアクセスパターンにも全然配慮していないプログラムだったので、swapしまくりで「これはプログラムを作り替えたほうがいい」レベルになってしまった。(あとメモリが500Mくらいあれば事情が変わっていただろうが…)いくら社内ツールだからといって、あのペースでは全部の計算に半年以上かかる。これでは、話にならない。後の計画ではこれを一般ユーザーが使えるレベルまで持っていこうとしているのだし。

最初はBUGかと思ったのだが、結局はやたらとスワップが発生して実行速度が極端に低下しているのだと分かった。理論的には、仮想メモリ400Mbyteほど使わなくてはいけない。まさかそんなに仮想メモリを消費すると思わなかったから、あのプログラムを作ったけど、現実的にそんな入力をされてしまったのなら仕方がない。新たな高速アルゴリズムを考えないと…、というのがここ2〜3日の仕事である。まあ、それをバグというのならそれもいいけど…。まさかあんなにでかい試料を与えるなんて思わなかった…。(;_;)

とりあえず、あのアルゴリズムが成功すれば、オンメモリでほぼ実用的な速度になるだろうが…。いまいちあのアルゴリズム、自分でもちゃんと計算できているか心配なんだよなぁ。(_ _;;)

1998/10/18(Sun)

二日酔い〜、二日酔い〜、これは持病の二日酔い〜。と言う訳で死にそうになりながら松本に帰着。布団に入った途端、名古屋ではしゃいだ分の疲れが一気に出て、午後明るいうちに帰ったのに、帰宅後、死んだように眠る。

1998/10/17(Sat)

M氏の壮行会。4人だけだったが大学時代の気のおけない仲間で楽しい時間を過ごす。あれ?去年会った時にはもうちょっと落ち着いた雰囲気のお店だったような気がするんだけど…、S氏もM氏もここだっていっているからここなんだろうな…。なんかあのお店には初めていった気がするのだが…。まあ、悪い店じゃなかったからどうでもいいんだけど、ちょっと私の記憶力の減退が心配。(^_^;

私なんかはぺーぺーの社員だから、話せないことなんてのは少ない方だと思うのだが、それでもやっぱり話せないことはある。(それはこのWWWページにしても同じ。)それでもお互い話せる範囲でではあるだろうが、色々情報交換が出来てよかったと思う。再会を約束してお開き。再びM氏と共にS氏の住居に転がり込む。

1998/10/16(Fri)

今日はキックオフ。要するに前期の総括をして後期の計画を正式に発表するという場+懇親会だ。とりあえずマネージャーの話をじっと聞いているが、一生懸命発表の準備をしてくれた人には悪いのだが、ほとんど右から左の上の空という感じ。ぼ〜と聞いているつもりだったのだが、ぼ〜と聞こうとするほど、今懸案の問題に関するアルゴリズムに関する疑問・アイデアがどんどん浮かんでくる。

これは単なるクセなんだけど、アルゴリズムを頭の中で考えている時には手が勝手に動いてしまう。(^_^;アルゴリズム中で、なぜるように手を動かしている時は大体データの初期化プロセスの部分について考えている時。右手が水平に前後するのは、データコピーの部分に関して考えている時だ。何か別のデータ構造に変換しながらコピーする時は、手首をひっくり返しながら右手が動く。配列構造のデータから、特定の状況にあった要素をPickUpする時には、人差し指を立ててそれを上下に激しく動かし、ここはループになるなと思ったら、そこで同じく人差し指を立ててぐるぐる回す…。で、それがアルゴリズムの完成あたりになっていると、机の上にやたらと爪を立てて「あっちの領域からこっちの領域にデータをコピーして云々」なんてことを考えるようになる。

で、こんな動作はハタからみると変人以外の何者でもない。(^_^;なるべくひっそりやったつもりだったが、やっぱりまわりからは気になるらしい。まあ無理もないのだが、近くに座っていた人から「酒の飲み過ぎで手が震えているんだろう?」とか言われる。言い返そうと思ったが、指摘自体はもっともなので反論できず。(^_^;

キックオフの後、懇親会があるのだが、今回は初めてパスして名古屋に一路向かう。松本始発だと思っていたら、長野始発らしくて自由席はほぼ満員。結局名古屋まで立ちっぱなし。死ぬほど疲れた。名古屋駅で予定通り友人のS氏に会って、そのままS氏の住処に転がり込む。


1998/11 前半のぶつぶつ

1998/10 前半のぶつぶつ

日々のつぶやき 目次

作者(vyama_at_janis_dot_or_dot_jp)への感想・意見など。
spamよけのため、_at_や_dot_は適宜@や.に入れ替えてください。

目次ページ