続編書きました io_uringで高速IO処理(!) | κeenのHappy Hacκing Blog keens.github.io/blog/2021/02/2…
2021-02-24 10:18:22@blackenedgold 前回の記事、へのリンクが 404 のようです。 それはともかく、とても興味深く拝見しております。 Rustよめないんですが、io_uring だとデバイスへの書き込み(時間かかる)への複数のリクエストをまとめるから速い、って結論なんですかね。というか、std毎回同期しないとこんなに早いってすごいですね
2021-02-24 10:41:21@_ko1 ありがとうございます、404修正します。多分5GBはOSのページキャッシュに載ってしまうのであとはメモリに書き出す速度の勝負で、仕組みが単純な分普通のwriteの方が速いのかなって思ってます。Linux 5.12でio_uringが速くなるらしいのでそこも期待ですね。
2021-02-24 11:00:45シングルファイルならシンプルにwritev使った方が速いと思うんですが、それはそれとしてio_uringでもwritevが使えます。
2021-02-24 11:26:09@blackenedgold 確かに、ある程度ページキャッシュに載ってしまえば、io_uring とやること変わんないすね。C10Kだと、例えば socket read が multiplexing されるので変わるんですかねぇ。でも、スレッド 10K 個作ってもあまり変わらない気も(100K だと作れないで変わる)。
2021-02-24 11:48:54@_ko1 そうですね、本来io_uringは非同期化のためのAPIなので多重化で効いてくると思います。スレッドを使った実装との差分はパフォーマンス上かなり違うらしいです。 qiita.com/tmsn/items/0b9…の問題点
2021-02-24 11:55:30@blackenedgold あ、Posix AIO じゃなくて、コネクションごとにスレッド作るようなサーバ実装を考えていました。コネクションごとにオーバヘッドがかかりますが、中での IO はどうなんかなと
2021-02-24 11:58:33@blackenedgold コンテキストスイッチは重くないと思いますよ... と思うんだけど、どうなんだろ自信がなくなってきました。主に、生成・終了のコストが問題だと思っていました。プロセスコンテキストスイッチのオーバヘッドが、OSレベルでやるかユーザレベルでやるか。タイムスライスが邪魔といえば邪魔かな...
2021-02-24 12:04:32@blackenedgold あ、固定長プールじゃなくて1万個プールできるってやつならいいのか。だいたい1mbメモリ食うので1万個で10gb、昔c10kが騒がれた当時だと、この辺もネックかもしれませんね(ページテーブル管理も
2021-02-24 12:18:11@blackenedgold @_ko1 c10k屋さんです。スレッドのコンテクストスイッチ遅くはないですが、スタック使用量と、スタック切替でreturn address予測が外れるのはちょっと痛いのかなと思ってます。c10k用途だと、リクエストあたりのバイト数がよほど小さくない限りはsyscallのオーバーヘッドは問題にならない印象なので...
2021-02-24 12:41:52@blackenedgold @_ko1 io_uringを使うメリットが一番あるであろうところは、メモリに載っていないかもしれないfile readが発生する場合だと思います
2021-02-24 12:43:05@_ko1 @blackenedgold 複数の何かがよくわかりませんが、cpuコアごとにスレッドたてて、スレッドごとにイベントループのかわりにio_uringまわす感じになると思います
2021-02-24 13:00:28@_ko1 @blackenedgold netflixさんはレスポンスサイズ大きいし、レイテンシの問題ないし、io_uringの必要性薄いユースケースだと思います。というか、公開情報が正しければfreebsdでtcpのsendfileでカーネル内tlsしてるはず
2021-02-24 13:03:20io_uringのインパクト、僕の理解が正しければ、第一に、従来のfile i/oは高速な非同期実装が難しかったのを、メモリにすでに載ってる場合も含めて高速に動くような解になってるところ。第二は、従来方式でsyscallのオーバーヘッドが相対的に大きくなる小サイズのi/oが頻発する場合に、それを隠蔽...
2021-02-24 13:11:31できるところだけど、それが問題になるほど最近のcpuはネットワークと比べて遅くない(ことが多い)し、file i/oでディスクでブロックされるのはパフォーマンスガタ落ちになるので第一の点が大きいでしょうなぁみたいな
2021-02-24 13:11:31h2oはファイルからコンテンツサーブする仕組みあるし、小サイズのi/oやらないこともないからio_uring対応してみたらいいんだろうなと思ってるけど、キャッシュに載っていないかもしれないファイルからコンテンツサーブするみたいな運用してる利用者がいるか問題ですね
2021-02-24 13:14:23dpdkやらないの?→やりません(メリットが薄そうだしユースケースが限られるから) netmapやらないの?→やりません(dpdkより良いけど以下同文) って感じできたけど、io_uringは、やってもいい気がするのよね
2021-02-24 13:17:41@kazuho @blackenedgold 単一リクエストは論外だなと思った次第でした。ところで ir_uring instance (用語は blogs.oracle.com/linux/an-intro… で見ました)って、スレッドごとにもつんですかね、それとも複数スレッドが一つを共有するんでしょうか。どっちでもできる気もしますが...(IOが属すスレッドが固定なら前者の方が速そう)
2021-02-24 13:20:42io_uringはRust界隈ではhotなトピックで、ファイル操作の効率的な非同期化ができなかったのが有名ライブラリがio_uringに取り組んでファイル操作をスレッドを使わない非同期化する方針を出した。そこで非同期の話題は今後たくさん出るだろうからそれ以外の側面掘ってみようかなという文脈だった
2021-02-24 13:22:17@kazuho @blackenedgold 話があっちゃこっちゃいきますが、つまり C10K が最初問題視していた1万コネクションさばきたいって奴は、read 待ちの epoll で起きたときには、多分データ届いた後だから、io_uring でも大して違わんって感じですかね
2021-02-24 13:26:11なぜか io_uring を ir_uring に typo するんだけど、intermeddiate representation にそんなに思い入れないのだけどなあ
2021-02-24 13:27:27@_ko1 @blackenedgold サーバ屋さんとしては、ネットワークをサチることができればそれでいいのですが、フルサイズパケット(あるいはTCPだと複数パケット分)ごとにi/oするようなケースだとepollベースでサチれるのでio_uringに移行するメリットがない。ただ、file readでディスク待ちが発生してると別、という感じです
2021-02-24 13:29:55@kazuho @blackenedgold cpu usage って減りそうですか。仕様・実装知らないんですが、io_uring に登録した userland のバッファに直接 kernel が書き込めて、kernel -> user copy が減るとか?
2021-02-24 13:34:43