libpioの件

初版は8月27日に作ったものだったりする。mixiに貼ってある。2ヶ月前の着想をここに来て実装。


非同期IOでスループットがどうのとベンチマークをしてもちょっと視点がずれていると思うのだけど、実はあまりスループットも落ちていないんじゃないか。ソースの中にテストプログラムを入れてあるのだけど、ddと比べてもそれほどスループットは落ちない…と言っても、ddとlibpioで条件が違うぞーというツッコミがあるに違いない。どうやって測ったらいいのかワカランのです…。


非同期IO+シングルスレッドのサーバーを書きたくなるのは、クライアントの挙動によってサーバーの状態が変わる場合。
こういう場合、コネクションごとに変数を共有しないとうまくいかないので、クライアントごとにプロセスを立ち上げるのはまず除外。クライアントごとにスレッドを割り当てるか、シングルスレッドでイベントループを回すかのどちらかになるけど、マルチスレッドは排他処理がやってられないので、シングルスレッドで書きたい。でも複数のクライアントからの処理を並列して処理できないので、IO(やIOに付随する処理)のブロック時間がスケーラビリティに直結する。
こういうときに非同期IOがあると、IOがブロックしないので嬉しい。本流の処理をやっている間も、他のIOはそのまま進行する。スバラシイ。


…スバラシイのだけど、いざ非同期IOを使おうとすると、いろいろと困る。Linux AIOはファイルにしか使えない。ソケットには使えないので、全部のIOを非同期にしようとするとlighttpdみたいなトリックを使わないといけない。これは苦しい。
POSIX AIOは、少なくともaccept()ができない(ソケットも使えない?)。困る。それにLinuxでのPOSIX AIOは、Linux AIOの上にユーザーランドでシグナルやスレッドをやりくりして実装してあって、それはどうなんだろうか…。その意味ではlibpioも同じか。



Linuxにsyslet/threadletが入れば万事解決だーという話もあるわけですが…まだ出てきていないモノに過度の期待をするのは良くない良くない。
libpioはIOの粒度を任意の大きさにできるのがポイント。もしかしたらsyslet/threadletが出てきても、それよりスケールするかもしれない…IOごとに行わないといけない処理が多い場合は、なきにしもあらず。クライアントからの要求ごとに、大きくて同期処理しかできない(あるいは非同期にするとオーバーヘッドが大きすぎる)ようなデータ構造を参照しないといけない場合とか。
IO粒度を大きくしておけば、データを参照している間に進められるIOの量が多くなる。syslet/threadletはIO粒度はシステムコールごとに限定されるはず。