各タスク毎に独立して組んだほうが効率が良い!?

私が高校生の時・・・2004年度の全国高校生プログラミングコンテストの出品作品と共に密かにgoogle:SuperConという東工大で開かれる高校生対象のスーパーコンピューターとMPIを使うプログラミングコンテストに出ようという企画があった。
しかしながら、私は凡ミスを犯してしまい予選を通過できなかったわけだが^^;;;;;
ってか 今でもちょっと引きずっていて悔しい ヽ(`Д´)ノむきぃ


そのスパコンに出場した方から聞いたお話だ。(スミマセン、すでにアドレスとか紛失してしまっていて・・・名前とか思い出せないです。)
本選問題の概要はとにかく早く処理すればいいらしい。
優勝した人のプログラムはなにもがんばって並列化したプログラムではなくて1タスク1CPUで計算させたのが一番速かったとの事。
このMPIという奴を触ったこと無いので良く分からないのだが、この結果は意外だった。
私であれば

  • 1タスク1CPUで計算させて
  • 1タスクが終わり次第あまっているタスクがあればそれにアタッチして
  • あまっていなければ今計算しているタスクからタスクを分けてもらう

という形がベストだなと勝手に思っていたのだが・・・。


最近になってこの法則があっているなといった出来事があった。

zipファイルを大量にダウンロードしたので、一気に解凍しようとしてエクスプローラーでそれらのファイルを「Lhaplusで開く」と言う風に選択したらLhaplusが数十個開いて解凍処理をはじめた。
しかし、数時間たっても一向に解凍されない。

確かにLhaplusやWindowsは数十個ソフトを立ち上げてもバグらずにがんばって仕事をしてくれていたのだ。
一つずつ選択して解凍したほうが圧倒的に処理時間は短かった。(処理速度は速かった)
単純に考えると一つずつ解凍してもすべて並列に解凍しても処理時間は同じように思える。
しかし、これが現実なのだ。*1
また、この
http://d.hatena.ne.jp/studiokingyo/20051228#p1
最適化したはずが全然最適かされていなかった事件もわずかながらそんな法則が当てはまるような気がする。


ここ数年、沢山ライブラリを組んだり読んだりしてきたが 今になって私は思うのだ。
今の時代のプログラミング戦略としてこのタスクという概念をうまくプログラムできる者がWizardではないか!?

タスクを細かく分けすぎるのもコードの肥大、処理速度の低下を招くし。ライブラリとしては簡潔な設計ではない。
タスクを大きくしすぎると制御を返さなくなってしまう。ライブラリとしては様々な状況に対応できる設計が破綻してしまう。

この「タスク」という概念をなるたけ排除して楽に組むためにスレッドやらコルーチンがあるわけで・・・。

最近google:マルチコアプロセッサ]とか[google:Dual CPUとかが一般的になり始めているので私も以下のような本を読んでそろそろ並列化をがんばるかなぁと感じていた所だった。

via http://q.hatena.ne.jp/1137708903

しかしながらタスクの分け方を間違えるとまったくもって最適化されないどころか処理速度が遅くなってしまうなんて恐ろしい限りである。(CPU開発者は普通にプログラム組んでいても早く処理するように設計してくれているという話も聞くが・・・)

ちょっと考えてみたが、
生成スレッド数を制限するくらいしか思いつかない。

また、私がライブラリを組む事に専念する動機の概略として二度とRewriteしたくない!!!というのがある。
また間接的に皆にも無駄なRewriteはさせないというのがある。
やっぱり私は様々な環境でもプログラムの変更はなしに動くようなプログラムを書きたいので、組み込み系とか考えるとやはりスレッドやらコルーチンという高級な機構は無い事を前提で動くものにしたい。
なので、コルーチン等を使わないタスク毎に処理(関数)を分けるシングルスレッドベースのコーディングスタイルは現役かな?と思ったりする。
ちなみに私のお手本のコーディングスタイルのライブラリはglibである。*2

*1:なので、今、このような現象が起きないようにする解凍ソフトを製作中だったりする^^;この現象の場合は私はキューに実行するタスクをぶちこんで1タスク毎に1処理というふうにすれば処理は速くなると思う。

*2:このスタイルを元にdkutil_cを書いている