# Understanding Host Network Stack Latency > [!abstract] 概要 > Linux ホストネットワークスタックの最も頻繁に指摘される欠点の一つは高いレイテンシであり、近年の研究はミリ秒規模のテールレイテンシを示している。 > この観察はユーザー空間スタックや専用ホストネットワークハードウェアの設計を促したが、Linux のテールレイテンシの真の根本原因を理解しないままでは同じ問題を繰り返すおそれがある。 > 本稿は Linux ネットワークスタックのテールレイテンシの根本原因を調査し、支配的なボトルネックはパケット処理そのものではなく、ホストがネットワーク処理のために CPU 資源を管理する方法にあるという意外な結論を示す。 > 広範な測定から、CPU スケジューラによる処理時間の誤帰属、CPU runtime を公平性の抽象として使う限界、予測できないパケット到着下での割り込み調整の非効率という三つの要因を特定する。 > これらに対処すると、同程度のスループットを保ちながら性能を最大 5.3 倍改善できる。 > 低レイテンシネットワーキングには、ホスト CPU スケジューリングとホスト・NIC 間相互作用の再考が必要である。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] Abstract) ## 論文情報 - 著者: [[Tianyu Zuo]](University of Virginia)、[[Jaehyun Hwang]](Sungkyunkwan University)、[[Ao Tang]]・[[Rachit Agarwal]](Cornell University)、[[Qizhe Cai]](University of Virginia) - 媒体: *ACM SIGCOMM 2026* - 会議日: 2026-08-17〜2026-08-21、Denver - DOI: https://doi.org/10.1145/3789240.3829115 - 再現用コード: https://github.com/Terabit-Ethernet/understand_latency ## 概要 本稿は、Linux の高いテールレイテンシをネットワークスタック内部のパケット処理コストだけに帰する見方を検証し、ホスト CPU 資源の競合と管理方式を三つの主要因へ分解する。 単一スレッドが孤立して動く場合、Linux の P99.9 レイテンシはポーリングなしで 19 マイクロ秒、ビジーポーリングで 14 マイクロ秒に収まり、ユーザー空間スタック TAS の高速経路との差も 5 マイクロ秒に過ぎない。 一方、多数のスレッドや複数コアを使うと、softIRQ の CPU 時間が実行中スレッドへ誤って課金され、キャッシュ・処理量・割り込み到着の差がスケジューリング待ち時間を増幅する。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] Abstract, §1, §3) ## 問題設定 既存研究の多くは多数の接続・スレッドを用いて Linux のミリ秒規模テールレイテンシを示してきたが、ネットワークスタックのパケット処理自体と、ホスト資源を共有する仕組みの寄与を分離していない。 本稿は 64 バイト RPC の ping-pong ワークロードを使い、NIC 受信からアプリケーションの読み出し、応答送信までを 12 コンポーネントへ分解する。 評価対象は、孤立したスレッド、単一コア上のスレッド競合、1 接続あたりの in-flight 要求数、単一 NUMA ノード内のマルチコア、RPC サイズと通信パターン、EEVDF、Redis の実アプリケーションである。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §1–§2) ## 測定方法 ### 実験環境 2 台のサーバーを 400 Gbps リンクで直接接続した。 各サーバーはデュアルソケット Intel Xeon Gold 6530、ソケットあたり 32 コア、1,024 GB DRAM、L1 データキャッシュ 48 KB・L2 2 MB・L3 160 MB、ConnectX-7 NIC を備える。 基本環境は Ubuntu 22.04、Linux kernel 5.10、既定 CPU スケジューラ CFS であり、比較用に Linux kernel 6.12 の EEVDF 結果も測定した。 TSO、GRO、9,000 バイトのジャンボフレーム、aRFS、ハイパースレッディングを有効にし、irqbalance と負荷分散は実験ノイズを抑えるため無効にした。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §2) ### レイテンシ分解 カスタマイズした Netperf で、クライアントとサーバーのスレッド対ごとに専用 TCP 接続を持つ 64 バイト RPC を生成した。 カーネル内の各 `skb` にタイムスタンプを保持し、NIC のハードウェアタイムスタンプ、`phc2sys`、`ftrace` を組み合わせて同一 RPC のクライアント・サーバー側プロファイルを対応づけた。 計装のオーバーヘッドを抑えるため、タイムスタンプは 100 要求ごとにサンプリングした。 **図1 (Figure 1): Linux ネットワークスタックの要求単位レイテンシ分解** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig01-latency-breakdown.png]] (Figure 1. NIC、デバイスドライバ、ネットワークサブシステム、IP、TCP、アプリケーションを通る受信・送信経路と、12 コンポーネントの計測位置を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 1.) Table 1 は、受信側 6 区間、アプリケーション処理、送信側 5 区間からなる 12 コンポーネントの分類である。 | Component | Description | From | To | |---|---|---|---| | `rx_irq` | IRQ 処理 | NIC | `skb` 確保 | | `rx_napi` | 受信 NAPI 処理 | `skb` 確保 | Rx NAPI 終了 | | `rx_ip` | 受信 IP 処理 | Netdev 開始 | Rx IP 終了 | | `rx_tcp` | 受信 TCP 処理 | Rx TCP 開始 | Rx TCP 終了 | | `rx_sched` | アプリケーション起床 | wake-up signal | `read` 再開 | | `rx_data_copy` | 受信データコピー | データ読み出し開始 | データ読み出し終了 | | `app` | アプリケーション処理とシステムコール | ユーザー空間復帰 | `write` 呼び出し | | `tx_data_copy` | 送信データコピー | データ書き込み開始 | データ書き込み終了 | | `tx_tcp` | 送信 TCP 処理 | Tx TCP 開始 | Tx TCP 終了 | | `tx_ip` | 送信 IP 処理 | Tx IP 開始 | Tx IP 終了 | | `tx_queue` | 送信パケットスケジューリング | qdisc 処理開始 | qdisc 処理終了 | | `tx_xmit` | パケット送信 | xmit 開始 | xmit 終了 | (Table 1. レイテンシ分解の分類。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Table 1.) ## 提案した対処 ### ACCa: IRQ 時間の正確な計上 Linux の CFS はスレッドごとの virtual runtime に基づいて公平性を実現するが、既定では softIRQ の処理時間を、処理したパケットの所有者とは無関係に現在実行中のスレッドへ課金する。 さらに既存の IRQ 時間計上オプションは softIRQ 処理の完了後に IRQ 時間を更新するため、途中の CPU accounting event で発生した時間を現在のスレッドへ誤って残す。 ACCa は各 accounting event で IRQ 時間を更新し、`schedule` 呼び出し時の時間も次に起床するスレッドへ誤帰属しないようにする。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §3.2) ### PCSched: 要求数を公平性の単位にするスケジューリング ACCa で softIRQ 時間を除いても、処理量、データコピー、キャッシュ状態の差による virtual runtime の差は残る。 そこで PCSched は CPU 時間をそのまま進捗の代理にせず、送受信した要求・応答数をネットワークワークロード向けの公平性単位として使う実証用スケジューラである。 要求数を基準にすると、キャッシュミスやメモリ待ちの影響を受けた実行時間をそのまま「より多く仕事を進めた」と解釈する問題を緩和できる。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §3.2) ### AutoDIM: 予測可能なトラフィックに合わせた割り込み調整 DIM は到着トラフィックに応じて割り込み率を動的に調整するが、バースト性トラフィックでは過去履歴から最適点を予測しにくい。 ping-pong では in-flight パケット数と処理時間を事前に知れるため、AutoDIM は単一論理コア上の in-flight パケット数の半分を最小パケット閾値に、対応する処理時間を最大タイムアウトに設定する。 この単純な予測型設定は、44 スレッドの knee point で P99.9 レイテンシを 215 マイクロ秒まで下げ、PCSched からさらに 22% 改善した。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §3.2) ## 実験結果 ### 孤立時の基準線と単一コア競合 孤立した 1 スレッドでは、Linux の平均エンドツーエンドレイテンシは 12.9 マイクロ秒、P99.9 は 19 マイクロ秒である。 ビジーポーリングを使うと P99.9 は 14 マイクロ秒になるが、両端の CPU 使用率は約 2.28 倍になる。 テール領域では `rx_irq`、`rx_ip`、`rx_tcp`、`rx_sched` など受信側処理とスケジューリングが支配的である。 **図2 (Figure 2): 競合なしのレイテンシ** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig02-no-contention.png]] (Figure 2. 平均・P99.9 エンドツーエンドレイテンシと P99.8〜P100 のコンポーネント分解を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 2.) 単一コアへスレッドを増やすと、`rx_sched` がテールレイテンシの最大要因になる。 48 スレッドの knee point で Linux の P99.9 は 1,139 マイクロ秒に達し、ACCa は 415 マイクロ秒、PCSched は 276 マイクロ秒まで低下させた。 IRQ 時間計上オプションだけを有効にした Linux + IRQa は、48 スレッドで既定 Linux より P99.9 が 4.7%増加した。 **図3 (Figure 3): 単一コア上のスレッド数増加** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig03-thread-contention.png]] (Figure 3. Linux、IRQa、ACCa、PCSched のスループットと P99.9 レイテンシをスレッド数の増加に対して比較する。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 3.) **図4 (Figure 4): knee point のテールレイテンシ分解** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig04-knee-breakdown.png]] (Figure 4. ACCa と PCSched がクライアント側の `rx_sched` 寄与を大きく減らす。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 4.) **図5 (Figure 5): virtual runtime と softIRQ 処理量** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig05-runtime-and-packets.png]] (Figure 5. virtual runtime のスレッド間差と、softIRQ 中に処理したパケット数と `rx_sched` の相関を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 5.) ACCa 適用後もサーバー側には virtual runtime の差が残り、`rx_data_copy`、アプリケーション処理、送信側処理の差が主因となる。 処理時間は stall cycle とほぼ線形に対応し、クライアント側では L1 データキャッシュミスが stall の主要因である。 **図6 (Figure 6): IRQ 時間計上のタイミング不整合** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig06-irq-accounting.png]] (Figure 6. CPU accounting event の途中に発生した IRQ 時間が IRQa で誤って計上され、ACCa で修正される過程を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 6.) **図7 (Figure 7): stall cycle と処理時間の関係** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig07-stall-cycles.png]] (Figure 7. `rx_data_copy`、アプリケーション、`tx_data_copy` の処理時間と総 stall cycle、L1 データキャッシュミス由来の stall を比較する。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 7.) ### 割り込み調整と in-flight 要求 DIM は 44 スレッドの knee point で最適な割り込み設定へ到達せず、`rx_sched` を大きくする。 AutoDIM は ping-pong の予測可能性を利用して P99.9 を 215 マイクロ秒まで改善し、通常の DIM による「最初に増えてから減る」レイテンシ曲線を消した。 **図8 (Figure 8): 割り込み調整の影響** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig08-interrupt-moderation.png]] (Figure 8. ACCa 下の DIM の影響、割り込み数、トラフィック特性に合わせた AutoDIM の性能を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 8.) スレッド数を増やすより、1 コアあたり少数スレッドで in-flight 要求を増やす方が、バッチ処理を保ちやすい。 2 スレッド構成では 128 in-flight 要求まで P99.9 の増加が小さく、32 in-flight 要求の Linux + PCSched は 1.28 million IOPS と 90 マイクロ秒の P99.9 を達成した。 一方、スレッド数が増えると同じ in-flight 要求数でも 1 セグメントあたりの要求数が減り、GRO・TSO・TCP Nagle の集約効率が下がる。 **図9 (Figure 9): in-flight 要求数の増加** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig09-inflight-performance.png]] (Figure 9. 2、8、32、48 スレッドで in-flight 要求を増やしたときのアプリケーション性能を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 9.) **図10 (Figure 10): in-flight 要求数と `rx_sched`** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig10-scheduling-latency-inflight.png]] (Figure 10. 高い I/O depth でも `rx_sched` が P99.9 エンドツーエンドレイテンシを支配することを示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 10.) **図11 (Figure 11): セグメントあたりの要求数** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig11-segment-batching.png]] (Figure 11. 同じ in-flight 要求数ではスレッド数増加がバッチを小さくし、同じスループットでは追加要求が受信バッファに滞留することを示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 11.) ### マルチコアと通信パターン 16 物理コアへ拡張すると最大スループットは約 13.21 倍になるが、パケットが複数コアへインターリーブするため DIM の調整が難しくなり、同じ knee point で `rx_irq` と `rx_sched` が増える。 単一 NUMA ノード上で 2 スレッド/コア、48 in-flight 要求を使うと、1 コアあたり約 1 million IOPS、P99.9 210 マイクロ秒となり、単一コアの結果に近い。 ACCa と PCSched はマルチコアでも既定 Linux に対して、それぞれ最大 6.4 倍、18.6 倍のテールレイテンシ改善を示す。 **図12 (Figure 12): マルチコア拡張のコスト** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig12-multicore-scaling.png]] (Figure 12. 16 コアへの拡張でスループットが増える一方、テールレイテンシが増加し、`rx_irq` と `rx_sched` が膨らむことを示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 12.) **図13 (Figure 13): マルチコアでの in-flight 要求** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig13-multicore-inflight.png]] (Figure 13. マルチコアでも in-flight 要求数とスレッド数を適切に選べば単一コアに近い性能を得られる。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 13.) 64〜1,024 バイトの RPC サイズを変えても、IRQ 時間計上、要求数ベースの公平性、予測型割り込み調整の効果は概ね維持された。 RPC とストリームを混在させると、RPC パケットがストリームの head-of-line blocking を受けるため低負荷でもテールレイテンシが高いが、ACCa はスレッド数増加によるレイテンシ膨張を抑える。 incast と outcast は one-to-one よりボトルネック側のスケジューリング機会が増えるため、knee point の P99.9 は 1/2 未満になる。それでも ACCa、PCSched、AutoDIM はそれぞれ改善を続ける。 **図14 (Figure 14): RPC サイズの影響** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig14-rpc-size.png]] (Figure 14. 128、256、512、1,024 バイトの RPC で、4 つのスケジューリング・割り込み設定を比較する。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 14.) **図15 (Figure 15): 通信パターンの影響** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig15-communication-patterns.png]] (Figure 15. 混合 RPC サイズ、ストリーム混在、incast、outcast の各通信パターンで知見を検証する。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 15.) ### EEVDF と Redis Linux kernel 6.12 の EEVDF は、スリープ中のスレッドの lag を消去する現在の実装により、異なる I/O depth のスレッドへ不均等な CPU 時間を与える。 この lag evaporation は virtual runtime の差を偶然縮めるため、CFS よりテールレイテンシを改善するが、公平性の問題を解決したわけではない。 ACCa は EEVDF 上でも最大 1.15 倍、AutoDIM は最大 1.25 倍の改善を示す。 **図16 (Figure 16): EEVDF の性能** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig16-eevdf.png]] (Figure 16. lag evaporation の挙動と、EEVDF、ACCa、AutoDIM の性能を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 16.) 実アプリケーション検証では Redis に標準 YCSB の 4 KB 要求を与え、100% read と 95% read / 5% write を測定した。 ACCa は既定 Linux に対して knee point のテールレイテンシを最大 2 倍、PCSched は最大 2.2 倍改善し、AutoDIM は PCSched から最大 1.42 倍さらに改善しながらスループットも最大 1.08 倍にした。 **図17 (Figure 17): Redis の性能** ![[_attachments/Understanding_Host_Network_Stack_Latency/fig17-redis.png]] (Figure 17. Redis の 100% read と 95% read / 5% write で、スケジューリングと割り込み調整の効果を示す。Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]], Figure 17.) ## 考察 本稿の三つの対処は、ネットワークスタックをカーネル外へ移すのではなく、ホスト資源の公平性と到着制御の単位をネットワークワークロードに合わせて変える。 softIRQ 時間を誤ってスレッドへ課金すると、パケット到着の偶然の偏りが virtual runtime の差となり、その差が起床順序と処理量の差をさらに広げる正のフィードバックになる。 softIRQ 時間を除いても、キャッシュミスや TLB ミスなどのプロセッサ側状態は runtime を変えるため、CPU 時間だけを公平性の代理にすることには限界がある。 したがって、ネットワーク処理の進捗をパケット数・要求数・応答数などで表す柔軟なスケジューリング単位と、受信側が到着トラフィックを予測・制御できるトランスポートが今後の設計候補になる。(Source: [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §3, §5) ## 強み / 弱点・課題 ### 強み - Linux の 12 区間を要求単位で計装し、エンドツーエンドのテールレイテンシを `rx_sched`、`rx_irq`、キャッシュ由来の処理時間へ分解した点 - IRQ 時間の誤計上、runtime 公平性の限界、DIM の予測困難性を独立の実験で切り分けた点 - RPC サイズ、in-flight 要求、マルチコア、incast/outcast、EEVDF、Redis へ知見を広げた点 - ACCa、PCSched、AutoDIM という具体的な対処を実装し、同程度のスループットを保ったレイテンシ改善として示した点 ### 弱点・課題 - 基本評価は 400 Gbps 直結、Xeon Gold 6530、ConnectX-7、Ubuntu 22.04、Linux 5.10 の構成に依存する - PCSched は要求数を公平性単位にする実証用方針であり、異種要求、ストリーム混在、複数アプリケーションを横断する一般的な公平性定義ではない - AutoDIM は ping-pong の in-flight 数と処理時間を既知とする単純なヒューリスティックであり、予測不能な本番トラフィックへの一般化は未検証である - 計装の ftrace ring buffer 書き込みなどのオーバーヘッドが残り、コンポーネント合計とアプリケーション報告値に小さな不一致がある - Linux の将来カーネル、異なる NIC、DPU、実ネットワーク輻輳、より複雑な実アプリケーションで三つの原因が同じ強さで現れるかは未確認である ## 横断的な位置づけ 先行する [[@2021__SIGCOMM__Understanding Host Network Stack Overheads]] は高帯域 Linux の主なコストを受信側データコピー、DCA・キャッシュ、NUMA、フロー多重化として示した。 本稿はその測定系をテールレイテンシと CPU 資源管理へ寄せ、同じ Linux スタックでもパケット処理より `rx_sched` と `rx_irq` が支配的になる条件を明らかにする。 両者を合わせると、ホストネットワークスタックのボトルネックは固定的ではなく、帯域・フローサイズ・接続数・in-flight 数・CPU 競合によって、データ移動からスケジューリングへ移りうる。(Source: [[@2021__SIGCOMM__Understanding Host Network Stack Overheads]], [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] §3) ## 未解決の問い - CPU runtime、パケット数、要求数、キャッシュ状態を組み合わせたネットワークワークロード向け公平性単位を、異種要求とストリーム混在でも安全に定義できるか。 - 現行 Linux、異なる NIC 世代、DPU、SmartNIC、ユーザー空間スタックで、`rx_sched` と `rx_irq` の相対的な支配性はどう変わるか。 - 受信側主導トランスポートと AutoDIM を組み合わせ、将来のパケット到着を制御しながら割り込み閾値をオンラインで決定できるか。 - `rx_sched` の削減と受信側ゼロコピー、NUMA 配置、キャッシュ分離を同じ評価で比較すると、どの順序で最適化すべきか。 ## 出典 - [[.raw/papers/Understanding_Host_Network_Stack_Latency.pdf]] - [[.raw/papers/Understanding_Host_Network_Stack_Latency.txt]] - [ACM DOI](https://doi.org/10.1145/3789240.3829115) - [ACM SIGCOMM 2026 Accepted Papers](https://conferences.sigcomm.org/sigcomm/2026/accepted/) - [再現用コード](https://github.com/Terabit-Ethernet/understand_latency)