Parallelを読んだ

Rubyでお手軽に複数CPUによる並列計算を実行するライブラリParallelの仕組みが気になって仕方がなかったのでソースコードを拾い読みしてみた。背伸びして大人の小説を読んでいる小学生の気分になった。思ったより短かったから短編小説。
https://github.com/grosser/parallel

Parallelというのは、こんな感じでmapするだけで、並列計算してくれるすごいやつ。

・Parallelに限った話ではないが、プロセスをforkすると、メモリは全部コピーされる。つまりmnistをやろうとするとmnistのデータもforkの数だけ消費される。つらい。(たとえスペック的には辛くなくても精神的につらい。)
・要素はMarshal.dumpして子プロセスのパイプの中に投げる。基本的にはindexだけ投げて向こう側でindexを参照して要素を拾ってくれるみたい(pack と unpuckメソッド)。つまり行きはメモリや通信の時間的コストを心配をしなくてよさそう。
・しかし、帰りはresultはmarshal.dumpしたものがパイプを通って返ってくる。NArrayはMarshal.dumpできないなのでエラーが出る。Ruby Arrayを経由してMarshal.dumpすると遅い(推測)から、直接NArrayから文字列に変換する。これはParallel使わなければ不要な操作であり、時間的コストがかかる。
・たとえば、ニューラルネットワークでバッチ処理を80個単位でやるとする。20個のデータを、4つのCPUに割りふる。20個のデータからforwardとbackwardを計算して、重みWの更新を平均するなり足し合わせるなりして(どうすればいいかよくわかっていない)NArray1個だけに情報量を圧縮して、stringに変換して親プロセスに戻す。dotしてから3次元行列をつかってsumなりmeanなりすればいいはず。
・親プロセス側で返却されてきた4つの重みの更新をstringからNArrayに変換子て、平均するなり足し合わせるなりする。
・stringに変換してパイプを通すコストが十分に小さければ、バッチ処理である程度早くなるはずだ。
・子プロセスでOpenBLASを使っても大丈夫なのだろうか。numo-narrayにはinstall OpenBLAS from source and enjoy multithread acceleration.と書いてあるがスレッドって何? 時間をみつけて試してみる。

無知をさらす
・StandardError って継承して使うんだ…
・workerをreplaceすると何が違うのだろう
・IO.pipeってwriteとかreadがあるのか。
・rbconfig というものがあるのか…
・attr_reader :hoge で@hogeがローカル変数みたいに使えるのか。眼から鱗。
・mutexって何だ?
・地味にプログレスバーの機能がついている
・ラムダって何だ? -> -> 変な記号! 勉強した方がいいのかな?
・適宜 nil をreturnするようにしたらRubyの負担って下がるのかな?

最後に一言。Parallelはとてもかっこいいgemです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です