« Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 3 | トップページ | Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 5 »

2014年11月25日 (火)

Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 4

 Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野子,久野靖訳 1 から続く。

17章 もう一段階の間接参照(ディオミディス・スピリネス)

コンピュータサイエンスにおける問題のすべては、もう一段の間接参照によって解決できる
  ――バトラー・ランプソン(Butler Lampson)

 FreeBSDで、NTFS や ext35fs や ISO-9660 などの様々なファイルシステムを、統一的に扱う話。言語はもちろんc。まずは関数ではなく、関数へのポインタにする。ここまでは思いつくけど、次が凄い。デバイスによって、引数の数も型も違う。これを解決するために、引数も引数のポインタにしちゃった。

 やはり感激するのが、ロックの所得と解放を扱う部分。ドメイン固有言語(Domain Specific Language, DSL)なる専用言語を作り、awk でcのコードを生成しちゃう、という手口。確かに lex と yacc も似た手口を使ってるけど、うーん…と思ったら、私も似た手口を使った事があったw いや言語と言うよりプリプロセサとかフィルタとか言うのが妥当なレベルだけど。

 改めて考えると、Unixのファイルの仮想化ぶりは相当なもので。私は初めてソケット通信を使った時、普通のファイルと同じようにreadで読めるのに感激したなあ。これもチャンと考えれば、パイプで fgets() が使えてるんだから、理屈は同じようなモンなんだよね。

 しかしコレ、「間接参照」ってのはデータ構造から見た発想で、設計的には「もい一段の抽象化」となるのかな。そう考えると、昔作ったシロモノで直したいモノが沢山あって、それを思い出すとなかなか読み進めないのだった。

 なお、先の引用にはオチがついていて。

しかしそうすることで、たいてい、新たな問題が作り出されるのだ
  ――デビッド・ウィーラー(David Wheeler)

 うん、旧MacOS のハンドルにはトコトン苦しみました、はい。

18章 Pythonの辞書実装:すべての人々にすべてのものであること(アンドリュー・クッヒリン)

 Python の辞書(連想配列)をc言語で実装する話。ちなみにデータ構造はハッシュ表。

 辞書は様々な使い方がされて。大きいデータを扱う場合があるのはもちろんだけど、小さい辞書も頻繁に使う。処理系を作るにも使ってて、ここでは関数のキーワード引数を例に挙げてる。こういうのは実行速度に大きな影響を与えるんで、小さい辞書はなるたけ軽くしとかにゃならん。ってんで…

PyDictObject 本体には8スロットのハッシュ表のための領域があります。要素数が5以下の小さな辞書はこの表に格納することができ、余分な malloc() を呼び出す時間コストを節約できます。これは同時にCPUキャッシュの局所性も改善します。

 という事で、関数のキーワード引数は5個以下にしましょう。ちなみに表の拡張は、2/3が埋まった時だとか。キー値が衝突した時の処理とか、結構泥臭い話が出て来て、これも楽しかった。また、辞書のメモリ領域は単純に malloc()/free() してるワケじゃなくて、独自に管理して巧くリサイクルしてるとか。まあ、当然か。

19章 NumPyの多次元イテレータ(トラビス・E・オリファント)

 Python の多次元配列のイテレータを、c言語で実装する話。

 単純な配列のイテレータならそんなに難しくないけど、Python の場合は配列のスライスとかがあって。スライスってのは、例えばビットマップ画像の配列から一部分の矩形領域を抜き出したとか、RGBのフルカラー画像からRだけを抜き出したとか、そんな風に配列の一部分を抽出したシロモノのこと。これを配列と同じように扱いたいわけ。

 私はあまりイテレータを使った経験がない(というかプログラムをバリバリ作ってた頃はイテレータって手法を知らなかった)んだけど、今から思えばイテレータを使えばスマートに書けたプログラムが沢山あるんだよなあ。何より、扱うデータの構造から、プログラムの構造が解放されるのが大きい。

 大昔の事務処理でよく有った、複数の整列済み順編成ファイルの突き合わせとか←若者にはわかりません

20章 NASAの火星探索機計画のための高信頼エンタープライズシステム(ロナルド・マック)

 NASA の火星探索機(MER, Mars Exploration Rover)ミッションでの、主に地球側のサービス・システムを Java Beans で作る話。ここでは、主に地球にデータが伝送されてからの話が中心。つまりMERが送ってきたデータを、どう全世界に配信し、また全世界からデータを受け取るか、という問題。

 いきなり宇宙を感じさせるのが、時刻管理。地球じゃ世界中の人が関係してる上に、探索機は火星の2箇所にあるんで、世界中のタイムゾーンに加え火星の二つのタイムゾーンが必要になってくる。SFファンとしてはワクワクする話もあって。

火星の1日は地球より約40分長いため、ミッション関係者たちは、地球時間で生活している家族や同僚たちと比べて、毎日その時間だけ時刻を遅らせていくことになりました。

 多くの Bean が同時に稼動するシステムなんで、デバッグも大変。そこで講じた対策が、こまめにログを取ること。これはデバッグを楽にするだけでなく、「クライアントアプリケーションがそのサービスをどのように使っていたかの情報も、提供してくれたのです」。これ見ればチューニングが必要な部分もわかるわけ。

 ログをどれぐらいの頻度で取るかは設計する際のちょっと悩ましい問題で、あまし取りすぎるとディスクがすぐにパンクしちゃうし、しないとデバッグが難しくなる。マメに取るようにして、煩すぎるようなら後で調整する方が大抵の場合はいいのかも。

21章 ERP5:最高水準の適応性に向けた設計(ロジェリオ・アテム・デ・カルバルホ、ラファエル・モネラ)

 Python ベースのフレームワーク Zope を使い、ERP(Enterprise Resource Planning)システムを作る話…って、よくわかんなかった。興味を惹かれたのが、「関係マネージャ」。よくあるでしょ、単方向リストで充分だと思ってたら、実は双方向リストが必要だった、とか。その辺を巧く処理してくれるんなら、嬉しいなあ。笑ったのが、以下のくだり。

ERP5 Project の最初の利用は、ERP のインスタンス生成プロジェクトをサポートする「内部的な」プロジェクト管理のためでした。

 うんうん、やっぱり、最初の試運転は自分が乗らないと。

22章 スプーン一杯の汚水で(ブライアン・キャントリル)

 Solaris のカーネルのロック機構で見付かった、しつこいバグを退治する話。当然、サンプルはc言語。

 元々の問題は、資源のロックとスレッドの優先順位の話で、優先度逆転という状況。スレッドA・B・Cがあって、優先順位は高い順にA→B→Cとする。高優先のAが欲しい資源を、低優先のCが掴んでる。この時、Cは優先順位が低いから順番が回ってこず、AはCが放さないから待たされる。結果、中優先のBがズンズン進んでしまう。

 これを解決するのが、優先度継承。Cが終わらないからAが待たされる。なら、Aを待たせているCにも、Aと同じ優先順位を(一時的に)与えよう、という発想。ところが、これが難しくて、しまいにゃコアダンプする始末。OSがコアダンプしちゃ話にならん、しかも納期は迫るという極限状態で…

 スレッドなんて言葉が出てきたんで分かるように、ここでは並列処理の面倒くさい話が次々と出てくる。しかもマルチCPUだったりするんで、話は更にややこしい。

 ちょっと以外だったのが、ロック処理の重さ。私は滅多に使わないからシンドイ処理だと思ってたけど、少なくとも Solaris では軽い処理らしい、曰く、小さい単位で頻繁に同期され頻繁に解放される、結果として競合は滅多に起きない、だから競合がない場合に向けて最適化した、とか。

 コアダンプの原因を特定し、再現するあたりは、多くのプログラマが頷いてしまう場面。そして解決法も、ちょっと意外で拍子抜け。やっぱり、人って、疲れてくると発想パターンが一つに収斂しちゃうんだよなあ。

23章 MapReduceでの分散プログラミング(ジェフ・ディーン、サンジェイ・ゲマワト)

 Google で大規模な並列処理を実現している MapReduce の話。プログラム言語は c++ っぽい。

 やはり日頃から自分が使っているシロモノの話は興味深い。一般の人には Google って検索とかのサービスの便利さで印象深いけど、そのサービスを支える並列処理技術こそが Google のキモだったりする。

 そのキモが、ここで紹介する MapReduce。お題としては「4章 ものの見つけ方」にちょっと似てる。つまり、数十億個の文書から、キーとなる単語が何回出てくるかを数える、という問題。モロに Google 検索の仕事そのもの。

 これを一つのマシンでやってたらキリないんで、大量のマシンに分担させて解くのが Google 流。MapReduce は二つのモノ、つまり多くのマシンに仕事を分担する Map と、その結果を収集する Reduce からなってる。

 後半はスケジューリングの話が中心で、これもなかなか面白い。個々の仕事をする部分をワーカと呼んでて、つまり労働者だね。各マシンは複数のワーカを抱えてる。ワーカが仕事を終えると、マスタ(労務管理者)がワーカ(を抱えるマシン)に仕事を割り振る。単にこれだけで、性能の違う複数のマシンにバランスよく仕事を割り振れてしまう。

 護送船団方式で問題になるのが、「のろまなカメ」問題。大半のワーカが仕事を終えてるのに、小数のトロいワーカが仕事を終えず、全体の処理がなかなか終わらない。じゃ、どうするか。残った仕事が2~3個ぐらいになったら、別のワーカに同じ仕事を割り振ってしまう。これで、トロいマシンに待たされずに済むわけ。

 他にも死んでるマシンの見つけ方とか、クラッシュするデータの扱いとか、Google 独自のファイル・フォーマットの話とか、楽しいネタが一杯。全般的に荒っぽい手法が多いのも、Google の文化を感じさせてくれる。

24章 美しきかな、並列(サイモン・ベントン・ジョーンズ)

 リレーショナル・データベースじゃありがちな銀行口座のお金の振込み処理を例に、Haskell のソフトウェア・トランザクショナル・メモリSTM(Software Transactional Memory)を解説する。

 ここでは肝心のトランザクションの話より、Haskell 言語そのものが面白かった。いや使った事ないし。文法が特異なので、ちょっと慣れるまでは大変そうだけど。関数の宣言で、関数内で引数の中味が変わるか否かを示すのが、ちょっと昔風。またセミコロンが文の終わりではなく、文の区切りを示すのは Pascal の影響かな?

 「アクションが第1級の値」って、よくわからん表現だなあ、と思ったら、どうも「文のカタマリを値として扱える」という事らしい。つまりは LISP の lambda 式や JavaScript の無名関数みたいな。きっとスコープはサキシカル・スコープなんだろうなあ。ところで似た問題の解決法としてイテレータがあるけど、アクションとイテレータ、どう場合分けしたらいいんだろう?

 あと、関数を呼び出す際にパターンマッチして、同名の関数が複数あった時は適切な関数を選んじゃうあたりが卑怯。これじゃまるで Prolog ではないか。

おわりに

 次の記事に続く。

【関連記事】

|

« Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 3 | トップページ | Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 5 »

パソコン・インターネット」カテゴリの記事

書評:科学/技術」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/201750/60707761

この記事へのトラックバック一覧です: Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 4:

« Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 3 | トップページ | Andy Oram, Greg Wilson編 Brian Kerninghan, Jon Bentry, まつもとゆきひろ他著「ビューティフルコード」オライリージャパン 久野禎子,久野靖訳 5 »