1 ポイント 投稿者 GN⁺ 2024-08-27 | 1件のコメント | WhatsAppで共有

vmspliceは_あまりにも_速い

  • 一部のプログラムは、データをパイプ経由でより高速に移動させるために vmsplice というシステムコールを使用する
  • vmsplice を使わない場合、Linuxパイプが予想より遅いことを発見した
  • モールス符号を高速にエンコード/デコードするプログラムを書いており、そのためにパイプを使っている

理想的な環境でのデータ書き込み

  • 以下のプログラムは、システムコールなしでデータをコピーする
  • AVX-512 を使用して 167 GB/s の速度で実行される
  • AVX-512 を無効にして AVX2 および SSE2 でテストした場合でも、同じ速度(167 GB/s)を記録した
  • ベクトル化が使われている限り、167 GB/s の速度を達成できる

実際にパイプへデータを書き込む

  • パイプにデータを書き込むプログラムを書いて測定したところ、17 GB/s の速度を記録した
  • これはバッファに書き込む場合より 10 倍遅い
  • プロファイリングの結果、ほとんどの時間が write 呼び出しに費やされていた
  • pipe_write 関数でメモリページを割り当てるのに多くの時間がかかっている
  • データコピー自体は CPU 時間の 20% しか占めていないが、それでも __memset_avx512_unaligned_erms より 2 倍遅い

vmsplice の助け

  • vmsplice は、ユーザー空間からカーネルへバッファをコピーせずに移動させる
  • vmsplice を使うと 210 GB/s の速度を達成できる
  • vmsplicewrite システムコールの高コストな部分を回避する

まとめ

  • パイプへの書き込みは、生のメモリへの書き込みより 10 倍遅い
  • これはバッファをロックするコストと、SIMD コンテキストの保存・復元コストによるものだ
  • splicevmsplice はこれらのコストを避け、データを効率的に移動させる

GN⁺の要約

  • この記事は、vmsplice を使って Linux パイプの性能を最大化する方法を説明している
  • vmsplice はデータをカーネル空間へコピーせず直接移動させることで、性能を大きく向上させる
  • モールス符号のエンコード/デコードのような高速データ処理プログラムに有用だ
  • 似た機能を持つ他のプロジェクトとしては、splicesendfile などがある

1件のコメント

 
GN⁺ 2024-08-27
Hacker Newsの意見
  • JMPRET に置き換えられないのは、CONFIG_RETHUNK オプションのため

    • objdump の逆アセンブリでは、RETJMP __x86_return_thunk に置き換えられた結果を確認できる
    • 関連リンク: リンク1, リンク2
  • 関数の先頭と末尾にある NOP 命令は、ftrace がトレース命令を挿入できるようにしている

    • ASM_CLAC と ASM_STAC マクロに由来する
    • X86_FEATURE_SMAP が検出されると、実行時に CLAC 命令と STAC 命令で埋められる
    • 関連リンク: リンク3, リンク4, リンク5
  • あるユーザーのサイドプロジェクトでは、ファイルディスクリプタ向けのリングバッファを提供するシステムコールを提案している

    • パイプの両端がリングバッファをサポートしていれば、同じリングバッファをマッピングしてカーネル呼び出しなしでゼロコピー I/O を可能にする
    • 協力者を募集中
    • 関連リンク: リンク6
  • Linux のパイプを「遅い」と呼ぶのは、Toyota Corolla を「遅い」と呼ぶのと同じ

    • ほとんどの場合は十分に速い
    • 極端なケースでなければ、より速いものを探す必要はない
  • 現代の CPU では、rep movsb は最速のベクトル化バージョンと同等に速い

    • カーネル関数名 copy_user_enhanced_fast_string がそれを示唆している
    • CPU 機能である ERMS と FSRM がそれを可能にしている
  • AVX512 は消費電力が大きく、CPU の周波数スケーリングを引き起こす

  • Hacker News の「hug of death」を再び体験している

    • キャッシュされた WordPress ページのおかげで状況は改善したが、それでも数秒かかる
  • io_uring を使ったバージョンを見るのは興味深そう

    • カーネルと事前共有バッファを使ってコピーを避け、システムコールのオーバーヘッドを減らせる
  • ブログの読み込み時間が約 20 秒かかるというのは大胆な主張

  • ほぼあらゆる形の IPC は「遅い」

    • 安全性のために性能コストを支払うと決めたということ
  • もともと splice がなぜあれほど遅いのか理解できなかった

    • vmsplice より遅い理由は指摘されていたが、なぜそうなるのかは明確でない
    • vmsplice で再実装できない理由があるはず