2012-10-28

非同期入出力の残念な現状

asynchronous disk I/O | libtorrent blog
Libtorrent experience - the poor state of async disk IO | Hacker News

libtorrentの作者が、ディスクI/Oをパフォーマンスを向上させるために非同期I/Oを試した結果、どの環境でも残念なので、ブロックI/Oをスレッドプールで行う擬似非同期I/Oで実装したとブログを書いている。その問題について、Hacker Newsでも議論されている。

非同期I/Oは、話を聞くとたのもしい機能に思える。読み書きが完了するまでブロックせずに、完了したらOSが通知するという仕組みだ。

問題は、その実装がどの環境でも貧弱だという事だ。

環境というのは、主にOS側のことだ。多くのモダンなOSは非同期I/Oを提供している。特に著名なのがみっつある。

  • Linux AIO(Linuxカーネルが提供している)
  • Posix AIO(Posix互換のほとんどのOSが提供している。Linux、Max OS X、BSDなど)
  • MS WindowsのIO完了ポート(MS Windowsが提供している)

移植性を高めるには、この三種類のAPIによる実装をそれぞれ用意しなければならない。

ところが、Posix AIOは、標準で定める機能があまりに貧弱であり、近代的な用途には使えない。そのため、環境依存の拡張機能を使わなければならない。さらに実装が膨れ上がる。

Linux AIOを使うには、ファイルをO_DIRECTでオープンしなければならない。また、読み書きやバッファやサイズなどは、512バイトに正しくアライメントされていなければならない。これを正しく行うのは、恐ろしい手間がかかる。

Posix AIOでは、完了通知の方法が、実質シグナルしかない。シグナルはプロセスのどれかのスレッドに送られるのであり、非常に使いづらい。それに、ライブラリとしてシグナルを使うのは難しい。というのも、ユーザー側でも独自のシグナルハンドラを使っているかもしれないからだ。

シグナルではない方法で、どれかのスレッドに通知される機能もあるが、どのスレッドが通知を受け取るか指定できないので、非常に使いづらい。ライブラリとは関係ないプログラム中のスレッドも通知を受け取ってしまう。

Mac OS Xなどは、スレッド通知を実装していない。そのため、そのような環境ではシグナルを使うしかない。

いくつかの実装では、完了通知のユーザー定義の情報を含めることができる。これにより、どの入出力が完了したのか総当たりで確かめる必要がない。Mac OS Xは、この機能を提供していない。そのため、Mac OS Xでは、完了通知は、すでに発行した入出力のどれかが終わったということを告げるに過ぎず、自分で総当たりして、完了した入出力がどれであるか確かめなければならない。これはパフォーマンス上、非効率的だ。

aio_suspendにより、完了したかどうか確認することもできる。これはselectと同じであり、selectと同じパフォーマンス上の問題がある。

Linux AIOは、Posix AIOよりいくらか改良されているものの、やはり問題はある。

WindowsのIO完了ポートが、APIのインターフェースとしては一番優れているように思える。ところが、本当の問題は、実装が貧弱だという事だ。

LinuxもMac OS XもWindowsも、実装が貧弱である。API上からはブロックしない非同期処理のはずだが、実際に使ってみると、なぜかブロックするような自体が頻発する。

そして、どの非同期入出力APIを使っても、非同期化できるのは読み書きだけである。open(), close(), stat(), rename()などの操作は、非同期ではない。

そういうわけで、ブロック入出力をスレッドプールで使い、擬似的な非同期処理を行ったほうがマシということになる。ブロック操作なので実装が理解しやすい。移植性が高い。すべての操作を非同期にみせかけることができる。

libtorrentライブラリも、ネイティブな非同期入出力を使うのは諦めて、スレッドプールの実装にしたそうだ。

Hacker Newsなどでも議論されているが、非同期入出力の実装の質がどの環境でも等しく悪いという問題は深刻である。スレッドプールはスレッドスケジューラーやスレッド切り替えのコストがかかるものの、現在主流のストレージは十分に遅いため、無視できる。大規模データベースなどのソフトウェアは、実装の質が悪く移植性の低いネイティブな非同期入出力より、スレッドプールを使っている。

非同期入出力が使われないという事は、実装を改良する需要もないという事だ。実装が改良されないので、ますます使われないという悪循環に陥っている。

No comments: