昨年からずーっと書いている研究のプログラムは、マルチプロセスで動作して、 シグナルやらmutexやらcondやらがフクザツに絡み合いながら動作するので結構デバッグがしんどいです。 基本的な構造としては、マスタープロセスが1ついて、ワーカープロセスが複数いて、 付加的なプロセスがその周りを取り囲むように動作しているので、 ワーカー1匹で動かして動作確認してからワーカー数を増やして動作確認、 という手順を機能追加/修正の度に行うことになります。 ワーカー1匹のときに再現するバグの場合は比較的バグ取りが簡単なのだけれど、 複数のワーカーが動いているときに確率的に再現するバグや、 複数のワーカーがある特定のタイミングで特定の動作をした直後に周りの付加的なプロセスが落ちる、 みたいなバグを取るのに苦労しています。 複数のプロセスのステートをバグが再現するように全てコントロールした上で、 対象プロセスにgdbでアタッチしにいかなければならないので、 デバッグ用に一時的にプログラムの制御構造を変えたりしてなんとかやりくりしているのだけれど、 もっと汎用的に複数のプロセスの動作をまとめてコントロールできるような方法がないだろうか、 と日々思いを馳せています。
あとはそのプログラムを実行すると大量の動作トレースログを出力するので、 それを解析するほうのプログラムについても結構悩ましい問題がありまして。 Rubyで解析用スクリプトを書いているのですが、 解析の目的ごとにスクリプトを分けていて、だいたい現状で10個近くのスクリプトがあります。 それで、1個のスクリプト実行でそこそこメモリを食うので、 手元のノートPCだと4つくらい一気に実行するとスラッシングが発生してしまう。 でも同時実行数を2くらいに絞っておくと、メモリが潤沢なサーバ上で同じスクリプトを動かしたときにはCPUもメモリも余りまくりになってしまう。 使用するメモリ資源量とCPU資源量に応じて、自動的に最適な同時実行数を割り出してくれるシステムとかがあると割と便利だなあ、 とこちらもそんな方法がないか日々思いを馳せています。 使用するCPU資源量は、Rubyの場合はシングルスレッドなので1プロセス100%で見積もっておいて大外しすることはないけど、 メモリ資源量は入力データを全部メモリ上に展開するという方法を採用しているせいで、 入力データによって動的に資源利用量が変わってくるので事前に見積もるのが容易ではないんですよね。 同じプログラムで、環境によってほどよくCPU、メモリ資源を最大限に使って実行してくれるような制御系、 うまく作れるとこれはこれで論文ネタになったりしないかな? スパコンのジョブスケジューラ系だと既に色々やられていそうだけど、Rubyみたいな動的言語だとどうだろう。
耳鳴りは今日も続く。 どうも寒い時期になると耳鳴りがする、という人々もいるらしいので、近いうちにイヤーウォーマーを買ってみようかと思います。 最近は無音環境だと耳鳴りが邪魔をして作業に集中できないので、録音したラジオをiPodで聞きながら作業していたりします。
ツイート