性能と可搬性に配慮した TCP/IP スタック実装

2024年08月21日 水曜日


【この記事を書いた人】
安形

研究所でシステムソフトウェアの研究に取り組んでいます。

「性能と可搬性に配慮した TCP/IP スタック実装」のイメージ

この記事について

この記事では、技術研究所の研究員が SIGCOMM Computer Communication Review (CCR) から発表した、性能と組み込みやすさ・可搬性に配慮した TCP/IP スタック実装の論文について説明します。この実装は過去のブログ記事「Linux カーネルをバイパスして TCP 通信を 10 倍速くする」(2023 年 12 月 15 日)で触れられているものです。

SIGCOMM CCR は ACM SIGCOMM が発行しているレターで、査読有りの研究論文と、査読無しの論文の投稿を受け付けています。査読有り論文の採択率は CCR 編集部公開の情報によると 15% 程度とされており、採択の難易度は比較的高くなっています。今回の論文は、査読の上、採択・掲載されています。

また、年間の優秀論文に選んでいただいて、国際学会 SIGCOMM 2024 の Best of CCR セッションで発表させていただきました。

論文、TCP/IP スタックの実装、発表資料は以下のリンクからご参照ください。

    この記事では、論文の内容について、大まかな日本語訳を元に解説します。

    簡単なポイント

    • 過去のブログ記事にもある通り、研究コミュニティではカーネルをバイパスすると、一般的に広く利用されている機構と比較して、TCP の通信性能を大幅に向上できることが示されてきました。
    • 一方で、個人的に、これまで研究コミュニティから提案・公開されてきた実装は、使いやすさに課題があると感じていました。
    • 本論文では、それら課題の根本的な原因について考察するとともに、その原因を取り除いた実装を提案しています。

    論文の内容

    概要(Abstract)

    • この論文では iip という、性能と組み込みやすさの両方に配慮した TCP/IP スタックを提案します。
      • 本研究は、高速な TCP/IP スタック実装を自分のプロジェクトに組み込みたいと考えている開発者・研究者にとって、使いやすく気軽に利用できる実装を提供すること目指しています。
    • iip を新しく開発するに至った動機は、
    • 本論文は、TCP/IP スタック実装と、TCP/IP スタック実装を利用する開発者が実装するコードが、それぞれどのような機能を提供すべきかという境界線について再考し、
    • それをもとに iip が性能と組み込みやすさを両立できるようにする API を提案します。
    • 更に、iip で取り入れられている性能への配慮が実際にどのような影響があるかの評価結果を報告します。

    1 導入(Introduction)

    • 背景
      • TCP/IP は標準化された通信プロトコル群であり、TCP/IP スタックはその標準に則って通信を行う手順を実装したソフトウェアで、典型的に OS、特にカーネルの一部として実装されてきました。
      • 一方、10 Gbps を超えるような速度での通信を可能にするネットワークインターフェースカード(NIC)が一般化するにつれ、既存の OS に実装されている TCP/IP スタックではそれら高速な NIC の性能を十分に活かすことが難しくなってきました。
      • 研究コミュニティにおいては、このような状況を打開する策として、性能に最適化された TCP/IP スタック [1, 8, 10, 12, 17, 19, 25, 27, 29, 32, 33] を実装すると、既存の OS の TCP/IP スタックより遥かに高い通信性能を達成できるということが示されてきました。
      • しかし、既存の性能に最適化された TCP/IP スタック実装は高速な反面、多くの場合で他のシステムへ組み込む際の複雑性が高い、という課題があります。
      • また、組み込みやすさ・可搬性に配慮した TCP/IP スタック実装 [4, 5, 6, 28] は存在するものの、それらは高い性能を発揮するために重要な要素についての配慮が不足していることから、性能について課題があります。
    • 問題
      • 上記のことから、この論文が問題としているのは、これまで組み込みやすさ・可搬性に配慮しつつ、高い性能を発揮できる TCP/IP スタック実装がなかった、ということです。
      • この問題の結果として、ある開発者が、高速な TCP/IP スタック実装を自分のプロジェクトで採用して実装の性能を向上したいと考えた場合に採用できる選択肢が、
        • 既存の TCP/IP スタック実装を大幅に変更する [3, 11, 13, 14, 16, 18, 21, 22, 27]、
        • 新しく TCP/IP スタックを実装し直す、
        • 既存の可搬性に配慮した TCP/IP スタック実装の性能面での制約を受け入れる、
        • 高速な TCP/IP スタック実装を利用するのを諦める、というような困難の多いものしかないという状況が引き起こされています。
    • 本論文

    2 既存実装(Previous Work)

    2.1 性能に最適化された実装 (Performance-optimized TCP/IP Stacks)

    2.1.1 外部要素への依存 (Dependencies on other components)
    • 既存の性能に最適化された TCP/IP スタック実装は、多くの場合で、様々な、例えば CPU、NIC、OS、ライブラリ、コンパイラ等についての依存関係があり、結果として、他のシステムとの統合に際して複雑度が高くなりがちです。
      • 例えば、近年発表された Luna [33] という TCP/IP スタック実装についての論文では、既存の性能に最適化された TCP/IP スタック実装を利用せず、新しく Luna を実装した理由として、既存実装の互換性や依存要素の課題を挙げています。
        • 具体的には、VPP [1] というシステムの TCP/IP 実装は Mellanox 製 NIC の特定の機能をうまく利用することができなかったり、
        • IX [3] というシステムの TCP/IP 実装を利用するには、Dune [2] と呼ばれる Linux にはマージされていないカーネルモジュールが必要であり、また、Dune が特定の Linux のバージョンでしか動作しないことから、利用可能な範囲が限定的である、ということが述べられています。
      • また、既存の性能に最適化された TCP/IP スタックの利用しづらさを示す別の例として、多くの既存の通信性能のために重点的な最適化を施されているシステム [3, 11, 13, 14, 16, 18, 21, 22] が、既存の性能に最適化された TCP/IP スタック実装ではなく、lwIP [5] のような組み込みやすさ・可搬性に配慮した TCP/IP スタック実装を適宜改変の上採用している、ということも挙げられます。
    2.1.2 機能の干渉 (Functionality conflicts)
    • 既存の性能に最適化された TCP/IP スタック実装の多くは、TCP/IP のプロトコル処理以外、例えば固有のスレッドのランタイム等を含んだアプリケーション開発フレームワーク [19, 25, 27] や、新しく設計された OS [3, 21, 32] の一部として発表されています。
    • そのような TCP/IP スタック実装自体も、フレームワークや新しい OS 固有の機能に依存している場合が多く、これらは機能の干渉を引き起こし、他のシステムとの統合を難しくする場合があります。
      • 例えば、あるアプリケーション開発フレームワーク付属の TCP/IP スタック実装を、ある新しく設計された OS の上で利用したいとします。
        • その TCP/IP スタック実装がフレームワーク固有の例えばスレッドランタイムに依存していると、そのスレッドランタイムも新しい OS に移植される必要があります。
        • 一方で、新しい OS 自身が固有のスレッドランタイムを保有している場合が多くあります。
        • このような場合、二つのスレッドランタイムが機能面で干渉し合うため、アプリケーション開発フレームワークのスレッドランタイムか、新しく設計された OS のスレッドランタイムのうち、どちらかをもう一方で置き換える等の作業が必要となり、TCP/IP スタック実装移植の複雑性を高めます。
    2.1.3 CPU コア割り当てモデルの制限(Limited choices for CPU core assignment models)
    • TCP/IP スタック実装の処理と、アプリケーション固有の処理についての CPU コア割り当てモデル(パターン)は主に3通りが考えられます。この論文では、過去の研究 [30] からいくつか用語を借り、それぞれを、split、merge、unified と呼ぶこととし、それぞれを以下のように定義します。
      • split モデル
        • split モデルでは、TCP/IP スタック実装の処理と、アプリケーション固有の処理を別々のスレッド(ここでのスレッドは、OS が pthread_create 等を通して提供する機能を指し、Java や Python 等のような言語ランタイム等が提供するスレッドとは異なります)で実行し、それぞれを別々の CPU コアで実行します。
        • このモデルの適用には最小で2つ CPU コアが必要で(1つはアプリケーション用、もう一方は TCP/IP スタック実装用)、更に多くの CPU コアが利用可能な場合に、アプリケーション用、TCP/IP スタック実装用にいくつ CPU コアを割り当てるかについては、典型的に利用者の設定によります。
      • merge モデル
        • merge モデルでは、split モデルと同じく、TCP/IP スタック実装の処理と、アプリケーション固有の処理を別々のスレッドで実行しますが、それらを同一の CPU コアで実行します。
        • merge モデルを採用するために必要な最小の CPU コア数は1で、マルチコア環境では、1CPU コア時の設定を、利用可能な CPU コア全てに対して適用します。
      • unified モデル
        • unified モデルでは、TCP/IP スタック実装の処理と、アプリケーション固有の処理を、同一のスレッドで実行します。
        • このモデルの採用に必要な最小 CPU コア数は merge モデルと同じく1で、マルチコア環境では、1CPU コア時の設定を、利用可能な CPU コアに対して適用します。
    • 上記の3つのモデルは以下の点において、異なる特性を持ちます。
        • CPU 利用率
          • split モデルでは、TCP/IP 処理とアプリケーション処理を別々の CPU コアで動作しているため、片方が使わなかった CPU リソースをもう一方が利用する、ということができず、結果として、CPU 利用率が上がりきらない(CPU リソースを全て利用できない)ことから、利用可能な CPU コア数に対して十分な性能を発揮できない場合が多くあります。
          • 一方、merge、unified モデルでは TCP/IP 処理とアプリケーション処理のうち、片側が使わなかった CPU リソースをもう片方が利用することが可能なため、split モデルより高い CPU 利用率を達成することができます。
        • スレッド間のやり取りに付帯する負荷
          • split、merge モデルは、TCP/IP 処理とアプリケーション処理を別々のスレッドで実行するため、それらスレッド間のやり取りに際しての性能面でのコストが付帯します。
          • 特に、同一の CPU 上で TCP/IP 処理とアプリケーション処理を行う merge モデルでは、片方からもう片方の処理への切り替えにカーネルのスケジューラによるスレッド切り替えが必要となり、これは CPU にとって比較的負荷の高い処理であることから、性能劣化の原因になります。一方、split モデルは、TCP/IP 処理とアプリケーション処理が別 CPU コアで動作するため、処理の切り替えに際して、スレッド切り替えは必ずしも必要ではなく、結果として、merge モデルの方が split モデルよりスレッド間のやり取りのコストが高くなりやすいです。
          • ただ、split モデルは、CPU コア間でデータの受け渡しが必要なため、CPU コア間でのデータの整合性を担保するためのハードウェア水準での同期が性能を制限する場合があります。
          • これらに対して、unified モデルでは TCP/IP 処理とアプリケーション処理のためにスレッドを分割しないため、merge、split モデルにあるようなスレッド間のやりとりに際しての性能面でのコストは付帯しません。
        • 追記:上記要素をテーブルにまとめると以下のようになります。
      モデル アプリ・通信用スレッド アプリ・通信用 CPU コア CPU 利用率 スレッド間のやり取りに付帯する負荷
      split 分割 別々 低い 小さい
      merge 分割 同一 高い 大きい
      unified 同一 同一 高い なし
    • 本論文が既存の実装の課題の一つとして指摘するのは、上記のように、CPU コアの割り当てモデルは性能に大きな影響を与える要素でありながら、多くの既存の性能に最適化された TCP/IP スタック実装は、TCP/IP スタック実装利用者が任意の CPU コア割り当てモデルを適用することを許容するような設計になっておらず、本来達成可能な性能を発揮できない構成を強要することです。
      • 例えば、mTCP [10] という実装では unified モデルは採用できず、TAS [12] という実装では、split モデル以外適用できません。

    2.2 組み込みやすさ・可搬性を考慮した実装 (Portability-aware TCP/IP Stacks)

    2.2.1 NIC オフロード機能への配慮の欠如 (Unaware of NIC hardware offloading features)
    2.2.2 メモリコピー削減への配慮の欠如 (Lack of zero-copy I/O capability)
    • 大きなデータを転送するようなワークロードで高い性能を発揮するためには、アプリケーションの管理するメモリ領域と NIC に紐づけられたメモリ領域の間でのデータコピーを削減することが重要ですが、既存の可搬性を考慮した TCP/IP スタック実装の多くはそのような機能を実装していません。
    • 既存の可搬性を考慮した TCP/IP スタックの設計では、送受信データを、NIC に紐づけられたメモリ領域とは別のメモリ領域に保存するようにしており、その結果、データの送受信に際して、NIC に紐づけられたメモリ領域と、TCP/IP スタック実装が管理しているメモリ領域の間でデータのコピーが必要になります。
    • また、もう一点、あるメモリ領域に保存されたデータ(ペイロード)を、メモリコピーを行うことなく、かつ並列で複数のホストへ向けて送信できるようにするためには、非連続的なメモリ領域に配置されたヘッダとペイロードを NIC がパケット送信時に接続する scatter-gather 機能を使うことが一般的ですが(送信対象データ(ペイロード)が配置されている直前のメモリ領域にヘッダを配置しようとすると、(ロックがなければ)その領域が並列で操作されてしまうため)、先述の通り既存の可搬性を考慮した TCP/IP スタック実装は、scatter-gather を含めた NIC 固有機能を利用する想定をしていない、という点もメモリコピー削減機構が十分に実装されない要因の一つと考えられます。
    2.2.3 マルチコア環境への配慮の欠如 (Lack of multi-core scalability)

    3 設計 (Design)

    3.1 概観 (Overview)

    3.1.1 依存要素 (Dependencies)
    • 2.1.1 で述べられた依存関係の課題へ向けて、iip では以下の点に配慮します。
      • プログラミング言語の選択
        • プログラミング言語は排除し難い依存要素です。今回は、幅広い実行環境のための成熟したコンパイラが存在しているということから C 言語を採用しました。
          • また、古いバージョンや今後新しくリリースされるバージョンのコンパイラが難なく iip の TCP/IP 実装をコンパイルできるように、C89 という古い標準に従います。
          • さらには、C++ のプログラムの一部としてもコンパイル可能であるように C++98 という標準にも従います。
      • 外部要素への間接的なアクセス
    • 上記の配慮には、iip は既存の標準の POSIX のようなインターフェースにも依存しないということも含まれており、結果として、POSIX 非互換の OS や固有ランタイムを採用しているシステムとの統合も可能です。
    3.1.2 機能 (Functionality)
    • 2.1.2 で述べられた機能の干渉をできるだけ回避するため、iip では TCP/IP 機能のみを提供するようにするとともに、3.1.1 記載の通り、iip が利用する外部機能への依存を最小限にする努力をします。
    • 一方で、ある開発者が iip を特定のシステムに採用したとしても、そのシステムが、また他のシステムと統合される必要が発生し、更にそれ自体が別の TCP/IP スタック実装に依存していた場合には、機能が干渉してしまう、ということには注意が必要です。
    • なので、我々は、このような場合を想定して、iip 実装を他の TCP/IP スタック実装と簡単に置き換えられるような抽象化の層を当初より実装に組み込んでおくことを推奨します。
    3.1.3 CPU コア割り当てモデル (CPU core assignment models)
    • 2.1.3 で述べられた CPU コア割り当てモデルの制限が発生する主な要因は、既存の性能に最適化された TCP/IP スタック実装が、TCP/IP 処理を実行するループを実装してしまう、ということにあります。
      • 具体的には、開発者は(TCP/IP スタック実装に改変を加えないという前提において) TCP/IP スタック実装内にハードコードされたループを改変することができないため、同一ループ内で TCP/IP 処理とアプリケーション処理を行う unified モデルを実装することができません。
          • 追記:
            • 既存の性能に最適化された TCP/IP スタックは以下のようなループを一般的に実装していますが、
    while (1) {
      // ...
      tcpip_processing();
      // ...
    }
            • unified モデルの適用は以下のように、同じループの中に、TCP/IP 処理とアプリケーション処理を含める必要があり、上の例のように TCP/IP 処理を実行するループがハードコードされている場合には、適用できなくなっています。
    while (1) {
      // ...
      tcpip_processing();
      // ...
      appilcation_processing();
      // ...
    }
    • これを避けるため、iip は TCP/IP 処理を実行するループを実装せず、任意のループから呼び出されることを想定した関数のみを提供します。これにより、開発者は任意のループの中で iip の TCP/IP 処理を実行できるようになります。
        • 追記: iip では上のプログラムの例の tcpip_processing の箇所だけを提供し、それ以外の箇所は開発者が実装することを想定します。
    3.1.4 NIC のオフロード機能の利用 (Use of NIC hardware offloading features)
    • 2.2.1 にあるように、NIC のオフロード機能の利用は TCP/IP 実装の性能において重要です。
    • 既存の可搬性に配慮した TCP/IP スタック実装が NIC のオフロード機能を利用しない利用の一つは、それらが単純な I/O 機能と比べて一般性が低いからであると考えられます。
    • iip も全ての現存する NIC のオフロード機能へ対応するわけではありませんが、比較的一般的に実装されている、チェックサムオフロード、scatter-gather、TSO、Large Receive Offload (LRO)、等が利用可能である場合には利用するようにします。
    • iip の TCP/IP 実装は API の一部として定義された、開発者が実装するコールバック関数を通して、これら NIC のオフロード機能へアクセスします。
    3.1.5 メモリコピーの削減 (Zero-copy I/O capability)
    • 2.2.2 で述べられたように、メモリコピーの削減は大きなデータの転送時に重要になります。
    • メモリコピーの削減を可能にするため、iip は以下の点に配慮します。
      • パケットバッファ確保
        • API の定義で、NIC に紐づけられたパケットバッファの確保は開発者が行うものとします。
          • 開発者はパケットバッファをアプリケーションプログラムが直接アクセス可能な領域に用意することで、TCP/IP スタック実装が管理するメモリ領域とアプリケーションプログラムが管理するメモリ領域の間でのデータコピーを削減することができます。
      • NIC の scatter-gather 機能の利用
        • NIC の scatter-gater 機能が利用可能な場合には、ヘッダと送信対象データ(ペイロード)を非連続的なメモリアドレスに配置します。
          • これにより、データコピーを伴わず、また、メモリ領域についてのロックを実装することなく、同一の送信対象データ(ペイロード)を並列で複数ホスト・コネクションへ向けて送信することができるようになります。
    3.1.6 マルチコア環境への配慮 (Multi-core scalability)
    • 2.2.3 で触れたように、複数 CPU コアを効果的に利用することは、高速な NIC の性能を、小さいデータをやりとりするワークロードで活かすために重要です。
    • iip は、過去の研究  [7, 10, 15, 20, 25] で有効性が示されている、CPU コア間で共有されるメモリ領域(オブジェクト)をなるべく少なくするというアプローチを踏襲します。
    • 具体的には、TCP/IP 処理自体は内部で状態を保持せず、API で定義された状態保持のための構造体(のメモリ領域)への参照を受け取り、その構造体の状態に応じた処理を行う、また、構造体の状態情報を更新します。
      • この場合、ある CPU コアが実行する TCP/IP 処理は、参照を渡された構造体以外へアクセスしないため、開発者が各 CPU コアに対してそれぞれ別々の状態保持用構造体を用意することで、TCP/IP 処理時に CPU コア間における干渉は発生しません。
      • 一方、このアプローチを採用した場合、ある TCP コネクションに対応する構造体(オブジェクト・メモリ領域)は、CPU コアごとに用意された状態保持用構造体の中の一つだけにしか存在しないため、特定の TCP コネクションの受信パケットは、常に同じ CPU コアで受信処理が行われる必要があります。
        • TCP パケットと CPU コアの紐付けについては、開発者側が配慮すべき事項としており、開発者は RSS のような NIC の機能を利用する、もしくは任意のソフトフェアによる紐付けを適用することができます。

    3.2 プログラミングインターフェース (API)

    3.2.1 引数 (Common arguments)
    • API が定義する関数は以下のオブジェクト(メモリ領域)への参照を引数として取り、開発者の実装と iip の実装の間でやり取りを行います。
      • 状態保持用構造体
        • 3.1.6 で述べられたように、iip 実装自体は内部に状態を保持せず、全ての状態は開発者が確保した状態保持用の構造体に保存されます。
        • iip の実装は、引数で与えられた状態保持用構造体以外操作しないため、開発者はこの構造体を各 CPU コアごとに用意することで、TCP/IP 処理中の CPU コア間での干渉を避けることができます。
        • また、この構造体は主にマルチコア環境での性能に配慮して設計されていますが、同一メモリアドレス空間に複数の独立した TCP/IP 処理を行うインスタンスを存在させることができる特性から、同一メモリアドレス空間に複数 TCP/IP 処理を行うノードを配置する ns-3 [24] のようなシミュレータとの統合が容易になり、例えば Direct Code Execution (DCE) [26] フレームワークが採用している dlmopen を利用する等のテクニックは不要になります。
      • パケット
        • パケットを表現するデータ構造 (例えば、Data Plane Development Kit (DPDK) [9] の rte_mbuf) は開発者側の実装に依存する要素です。
        • iip では、開発者が任意のデータ構造をパケットの表現のために利用可能にするための抽象化を行います。
          • 具体的には、開発者側のプログラムは任意のパケットを表現するデータ構造 (例えば DPDK を使っている場合では rte_mbuf) への参照を API を通して iip の実装へ渡し、iip 内部では iip 固有のパケットを表現するデータ構造に開発者側の実装から渡された参照を内包させます。
          • iip 内部から、開発者側が利用しているパケットを表現するデータ構造についての操作(データ構造が参照しているパケットのデータ長の設定等)を行うことが可能なように、iip の API では、開発者が実装すべきコールバック関数の一部に、開発者固有のパケット表現データ構造を操作するための関数を定義しています。
      • 開発者が確保した任意のオブジェクト
        • 開発者がコールバック関数を柔軟に実装可能なように、iip 内部からコールバック関数を呼び出す際には、開発者が指定した任意のオブジェクトへの参照を渡すようになっています。
    3.2.2 開発者が実装することを想定したコールバック関数 (Callback functions to be implemented by developers)
    • iip は以下の機能を開発者側が API の一部として定義されたコールバック関数を実装することで提供するものと想定します。
      • 汎用メモリアロケータ
        • malloc や free に代表されるメモリ確保についての機能は、OS 固有の mmap のようなシステムコールや並列での未使用領域管理のために CPU 固有のアトミック操作命令の利用が必要なため、実行環境依存な要素です。
        • iip はこれらについての依存関係を発生させないために、開発者が実装したコールバック関数を通してメモリ確保・解放を行います。
      • NIC 操作
        • パケットの送信、オフロード機能の利用を含めた NIC の操作の実装は NIC 依存であるため、これら機能は開発者がコールバック関数を通して提供します。
      • パケット管理
        • 3.2.1 で述べられたように、パケットを表現するデータ構造は開発者依存であるため、開発者が利用するパケットデータ構造の操作(確保、解放、メタデータ操作等)は開発者側がコールバック関数を通して提供します。
        • パケット表現のデータ構造とは別に、3.1.5 に記載のあるように、送受信データを保持する、NIC に紐づけられたパケットバッファの確保・解放についての機能も開発者側がコールバック関数を通して提供します。
        • また、iip はこれら開発者が提供するパケット管理に関する機能は、特にパケットの clone (shallow copy) を実現するためにリファレンスカウント機能を内包していることを想定しています。
      • 基礎的な実行環境固有機能
        • iip は現在時刻取得等の基礎的な実行環境固有機能は、開発者側が実装し、コールバック関数を通して提供することを想定しています。
      • 入力イベントハンドラ
        • iip は新しい TCP 接続が確立されたり、TCP ペイロードが受信されたり等の入力イベントに際して、対応する特定のコールバック関数を呼び出すようになっています。
        • 開発者はこれらの入力イベントのコールバック関数実装を通じてアプリケーション固有の処理を実現できます。
    3.2.3 iip が提供する関数(Functions provided by iip)
    • iip は以下の機能を実装した関数を提供します。
      • 定期的な呼び出しを想定した関数
        • 3.1.3 で述べられた通り、iip 自身は TCP/IP 処理を実行するためのループ・スレッドを実装しないため、タイマーを起点としたイベント(TCP の再送タイムアウト等)を自ら処理できないため、代わりに、開発者側の実装から定期的に呼び出してもらうことを想定した関数を実装しています。
        • この関数は、数値の変数への参照を引数に取り、その変数へ値を設定することで、次回の呼び出し時刻を開発者側の実装へリクエストします。
      • 受信パケットの iip への引き渡し
        • 開発者側の実装から受信パケットを iip へ引き渡すための関数は、受信処理の起点として機能し、多くのコールバック関数がこの中から呼び出されます。
      • パケット送信操作
        • iip は ARP、ICMP、TCP、UDP データ送信、TCP 接続を確立する、閉じる等のパケット送信を含む操作の起点となる関数を提供します。
        • これら送信処理は、3.2.2 で述べられたコールバック関数を用いて NIC の scatter-gather 機能が利用可能である場合は、2.2.2 で触れられているような並列でのデータ送信が可能であるように、ヘッダと送信対象データ(ペイロード)を非連続的な領域に保存します。
    3.3 欠点・制約(Limitations)
    • 統合のためのエンジニアリングコスト
      • iip は統合のためのエンジニアリングコストを排除することはできません。
      • iip の統合に際して、開発者に必要な作業は主に、3.2.2 で述べられたコールバック関数の実装し、3.2.3 に記載されている定期的な呼び出しを想定した関数を呼び出すスレッドの実装、コールバック関数を通したアプリケーション固有の処理を実装、になります。
      • 我々は、コールバック関数の多くが、単純な既存の実行環境依存の機能呼び出しで十分であるため、エンジニアリングコストは必ずしも膨大ではないと考えています。
    • 既存のプログラムとの互換性
      • iip は多くの OS が採用している POSIX のようなインターフェースに準拠していないため、それら多くの OS のために作られた既存のプログラムとの互換性がありません。
      • 互換性を付与する潜在的な方法として、LD_PRELOAD や zpoline [31] のような仕組みを用いて、通信関連のシステムコールをフックした後 iip で通信処理をエミュレートすることが考えられます。
    • 実装の成熟度
      • iip は新しく実装されたものであるため、実装の成熟度は既存の汎用 OS に実装されているような TCP/IP スタックと比較すると劣ります。
      • ですが、成熟度の最たる要因は開発に費やされた時間であり、我々は継続的な改善を通して iip 実装の品質を向上できると考えています。

    4 評価(Evaluation)

    • 以下の設定のマシン2台の NIC を直接でケーブルで接続して実験を行いました。
      • CPU:Intel Xeon Gold 6326 CPU 2.90 GHz (16 core) x 2 (合計 32 CPU コア)
      • NIC:Mellanox ConnectX-5 (100 Gbps)
      • OS:Linux 6.2
    • ベンチマークに利用したプログラムは、iip を DPDK [9] の上で動作させます。
    • 特に記載のない場合は、2.1.3 で述べられた unified モデルを適用し、更に、一般的に利用可能な NIC のオフロード機能を有効にするとともに、メモリコピーを介さない I/O を行う設定を適用します。

    4.1 小さいメッセージの交換(Small Message Exchange)

    • 3.1.6 で述べられた、マルチコア環境への性能の配慮がどのように影響するかについて、小さいメッセージを交換するワークロードを用いて評価します。
      • ベンチマーク
        • 上記の2台のマシンの間で TCP コネクションを確立し、各 TCP コネクションが1バイトのデータをピンポン ping-pong のように交換し続けるワークロードを実行します。
        • 2台のうち、一方をピンポンを始動する pinger、もう一方を ponger と呼び、pinger はこのワークロードを実行するため常に 32 CPU コア全てを利用するようにします。
      • スループットの計測と結果
        • ponger が利用する CPU コア数を変化させながら計測を行います。
        • 各試行にあたり、2台のマシンの間で確立される TCP コネクションの数は、ponger が利用する CPU コアひとつあたり 32 コネクションになるように pinger 側を調整します。

        • 結果は上のグラフのようになりました。
          • default が全ての NIC オフロード機能と scatter-gather 機能を使った送信時のメモリコピー削減機構を適用した基本設定です。
          • w/o NIC scatter-gather は、ponger 側で scatter-gather 機能を使った送信時のメモリコピー削減機構を利用しない場合の結果です
          • w/o NIC checksum の場合は ponger 側が NIC のチェックサムオフロード機能を無効にします。
        • poinger 側で NIC の scatter-gather 機能を利用せず、データコピー削減機能を適用しない場合の方が、データコピー削減機能を適用した場合より高い性能が観測されました。
          • 一見、この結果は直感的ではありませんが、過去の研究 [23] においても同様の結果が報告されており、その研究の中ではデータのサイズが十分に小さい場合であれば、メモリコピーのほうが scatter-gather 機能を利用するための操作よりもキャッシュ効率が良く、結果として scatter-gather 機能を利用しない方が性能が高くなると説明されています。
        • 一方、NIC のチェックサムオフロード機能を利用しない場合、利用した場合と比較して 11~26% 程度の性能の低下が見られました。
      • 遅延の計測と結果
        • 2台のマシン間の TCP コネクション数を変化させながら ponger が 32 CPU コアを利用する場合の遅延を計測しました。

        • 結果は上のグラフのようになりました。
          • 各線の意味は、上のスループット計測の場合と同じです。
        • スループット計測の結果と同じく、NIC の scatter-gather 機能を使ってデータコピーを削減した場合よりも、しない場合の方が高い性能が観測されました。
        • また、NIC のチェックサムオフロード機能を利用しない場合には性能の低下が観測されました。

    4.2 CPU コア割り当てモデルの影響調査(CPU Core Assignment Models)

    • 3.1.3 で述べられた CPU コア割り当てモデルの影響を評価します。
      • ベンチマーク
        • 4.1 で利用したのと同じ TCP 経由でピンポンのようにメッセージ交換を行うワークロードを利用します。
        • 2 CPU コアを利用し、split, merge, unified モデルを適用して性能を計測します。
      • 結果

        • 計測結果は上のようになりました。
          • 各線はそれぞれ、split、merge、unified モデルの場合の結果を表します。
          • このグラフでは、各負荷(TCP コネクション数)時に観測されたスループットを横軸、99 percentile の遅延の値を表示しています。
            • 遅延の値は負荷に応じて変化することから、負荷が高い時と低い時で、遅延がどのように変化するかを見るためにこのような表示を用いました。
            • 横軸について unified の線が右端まで伸びている一方で、split と merge の線が途中で止まってしまっているのは、pinger 側で負荷を上げても(ponger 側の性能の限界により)split と merge の場合では 100 万リクエスト毎秒より少し上からスループットが増えなかったことを示しています。
        • split と merge 間の比較において、負荷が小さい時には、split モデルの方が低い遅延が観測されました。これは、アプリケーション処理と TCP/IP 処理間の以降に merge モデルではカーネルのスケジューリングが含まれることが要因であると考えられます。
        • 一方、split と merge 間の比較において、観測された最大のスループットは、merge モデルの方が高くなるという結果になりました。これは、カーネル空間でのスケジューリングコストがあったとしても、merge モデルの方が split モデルより高い CPU 利用率を達成できる、という特性が寄与していると考えられます。
        • また、unified モデルにおいてはこれら split、merge 両モデルの欠点を含まないため、3つのモデルの中で最も高い性能を達成していると考えられます。

    4.3 大きなデータの転送(Bulk Data Transfer)

    • NIC のオフロード機能の影響を、大きなデータの転送を行うワークロードを通して評価します。
      • ベンチマーク
        • 上記2台のマシンのうち、1台を受信用、もう一台を送信用として利用します。
        • 2台のマシンの間で1TCP コネクションを確立し、特定のサイズのデータを繰り返し送信します。
      • 結果

        • 結果は上のグラフのようになりました。
          • default は、全ての NIC のオフロード機能を利用している場合です。
          • sender w/o NIC scatter-gather は、scatter-gather 機能を利用せず、送信時にデータコピーを行う場合の結果です。
          • sender w/o NIC TSO では、送信用マシン側の TSO を無効にしています。
          • sender w/o NIC TSO and NIC checksum の場合では、送信用マシン側の TSO とチェックサムオフロードが無効になっています。
          • receiver w/o NIC LRO の場合では、受信用マシン側の LRO を無効にしています。
          • receiver w/o NIC checksum は、受信用マシン側のチェックサムオフロードを無効にした場合の結果です。
        • 全ての NIC のオフロード機能を利用した基本設定ではほぼ NIC の限界性能に達しました。
        • scatter-gather 機能を利用せず、送信時にデータコピーを行う場合に、送信するデータサイズに応じて右肩下がりの性能劣化が観測されました。これは、送信対象データのコピーによって、処理時にアクセスしなければならない総合のデータ量が CPU キャッシュ領域を上回り、適宜 CPU キャッシュ上のデータが捨てられ、結果、キャッシュに存在しないデータを DRAM から取ってくる頻度が増加してしまうためであると考えられます。
        • 送信側で TSO を無効にした場合、スループットは基本設定に比べ概ね半減しました。
        • 送信側で TSO に加え、チェックサムオフロードも無効にした場合には、記法設定に比べ、性能が十分の一程度まで低下しました。
        • 受信側の LRO を無効にしても、NIC の限界性能を観測しました。これは LRO が性能に貢献しないということではなく、このワークロードであれば LRO はなくても、実験に利用した NIC の限界性能は発揮できる、ということのみを意味します。
        • 受信側のチェックサムオフロードを無効にすると、送信側でチェックサムオフロード機能を無効にした場合と同じく、基本設定と比較して、性能が十分の一程度まで低下しました。

      5 まとめ (Conclusion)

      • この論文では、高性能な TCP/IP スタックを採用したいと考えている開発者や研究者にとって使いやすい・採用しやすい選択肢を提供することを目指した iip という TCP/IP スタック実装を提案しました。

      参考文献(References)

      • [1] David Richard Barach and Eliot Dresselhaus. 2011. Vectorized software packet forwarding. Patent No. US7961636B1, Filed May 27th., 2004, Issued Jun 14th., 2011.
      • [2] Adam Belay, Andrea Bittau, Ali Mashtizadeh, David Terei, David Mazières, and Christos Kozyrakis. 2012. Dune: Safe User-level Access to Privileged CPU Features. In 10th USENIX Symposium on Operating Systems Design and Implementation (OSDI 12). USENIX Association, Hollywood, CA, 335–348. https://www.usenix.org/conference/osdi12/technical-sessions/presentation/belay
      • [3] Adam Belay, George Prekas, Ana Klimovic, Samuel Grossman, Christos Kozyrakis, and Edouard Bugnion. 2014. IX: A Protected Dataplane Operating System for High Throughput and Low Latency. In 11th USENIX Symposium on Operating Systems Design and Implementation (OSDI 14). USENIX Association, Broomfield, CO, 49–65. https://www.usenix.org/conference/osdi14/technical-sessions/presentation/belay
      • [4] Andrej Butok. 2005. FNET. https://fnet.sourceforge.io/.
      • [5] Adam Dunkels. 2003. Full TCP/IP for 8-bit architectures. In Proceedings of the 1st International Conference on Mobile Systems, Applications and Services (San Francisco, California) (MobiSys ’03). Association for Computing Machinery, New York, NY, USA, 85–98. https://doi.org/10.1145/1066116.1066118
      • [6] egnite Software GmbH. 2001. Ethernut. http://www.ethernut.de/.
      • [7] Sangjin Han, Scott Marshall, Byung-Gon Chun, and Sylvia Ratnasamy. 2012. MegaPipe: A New Programming Interface for Scalable Network I/O. In 10th USENIX Symposium on Operating Systems Design and Implementation (OSDI 12). USENIX Association, Hollywood, CA, 135–148. https://www.usenix.org/conference/osdi12/technical-sessions/presentation/han
      • [8] Michio Honda, Felipe Huici, Costin Raiciu, Joao Araujo, and Luigi Rizzo. 2014. Rekindling network protocol innovation with user-level stacks. SIGCOMM Comput. Commun. Rev. 44, 2 (apr 2014), 52–58. https://doi.org/10.1145/2602204.2602212
      • [9] Intel. 2010. Data Plane Development Kit. https://www.dpdk.org/.
      • [10] EunYoung Jeong, Shinae Wood, Muhammad Jamshed, Haewon Jeong, Sunghwan Ihm, Dongsu Han, and KyoungSoo Park. 2014. mTCP: a Highly Scalable User-level TCP Stack for Multicore Systems. In 11th USENIX Symposium on Networked Systems Design and Implementation (NSDI 14). USENIX Association, Seattle, WA, 489–502. https://www.usenix.org/conference/nsdi14/technical-sessions/presentation/jeong
      • [11] Kostis Kaffes, Timothy Chong, Jack Tigar Humphries, Adam Belay, David Mazières, and Christos Kozyrakis. 2019. Shinjuku: Preemptive Scheduling for μsecond-scale Tail Latency. In 16th USENIX Symposium on Networked Systems Design and Implementation (NSDI 19). USENIX Association, Boston, MA, 345–360. https://www.usenix.org/conference/nsdi19/presentation/kaffes
      • [12] Antoine Kaufmann, Tim Stamler, Simon Peter, Naveen Kr. Sharma, Arvind Krishnamurthy, and Thomas Anderson. 2019. TAS: TCP Acceleration as an OS Service. In Proceedings of the Fourteenth EuroSys Conference 2019 (Dresden, Germany) (EuroSys ’19). Association for Computing Machinery, New York, NY, USA, Article 24, 16 pages. https://doi.org/10.1145/3302424.3303985
      • [13] Simon Kuenzer, Vlad-Andrei Bădoiu, Hugo Lefeuvre, Sharan Santhanam, Alexander Jung, Gaulthier Gain, Cyril Soldani, Costin Lupu, Ştefan Teodorescu, Costi Răducanu, Cristian Banu, Laurent Mathy, Răzvan Deaconescu, Costin Raiciu, and Felipe Huici. 2021. Unikraft: fast, specialized unikernels the easy way. In Proceedings of the Sixteenth European Conference on Computer Systems (Online Event, United Kingdom) (EuroSys ’21). Association for Computing Machinery, New York, NY, USA, 376–394. https://doi.org/10.1145/3447786.3456248
      • [14] Simon Kuenzer, Anton Ivanov, Filipe Manco, Jose Mendes, Yuri Volchkov, Florian Schmidt, Kenichi Yasukata, Michio Honda, and Felipe Huici. 2017. Unikernels Everywhere: The Case for Elastic CDNs. In Proceedings of the 13th ACM SIGPLAN/SIGOPS International Conference on Virtual Execution Environments (Xi’an, China) (VEE ’17). Association for Computing Machinery, New York, NY, USA, 15–29. https://doi.org/10.1145/3050748.3050757
      • [15] Xiaofeng Lin, Yu Chen, Xiaodong Li, Junjie Mao, Jiaquan He, Wei Xu, and Yuanchun Shi. 2016. Scalable Kernel TCP Design and Implementation for Short-Lived Connections. In Proceedings of the Twenty-First International Conference on Architectural Support for Programming Languages and Operating Systems (Atlanta, Georgia, USA) (ASPLOS ’16). Association for Computing Machinery, New York, NY, USA, 339–352. https://doi.org/10.1145/2872362.2872391
      • [16] Filipe Manco, Costin Lupu, Florian Schmidt, Jose Mendes, Simon Kuenzer, Sumit Sati, Kenichi Yasukata, Costin Raiciu, and Felipe Huici. 2017. My VM is Lighter (and Safer) than your Container. In Proceedings of the 26th Symposium on Operating Systems Principles (Shanghai, China) (SOSP ’17). Association for Computing Machinery, New York, NY, USA, 218–233. https://doi.org/10.1145/3132747.3132763
      • [17] Ilias Marinos, Robert N.M. Watson, and Mark Handley. 2014. Network stack specialization for performance. In Proceedings of the 2014 ACM Conference on SIGCOMM (Chicago, Illinois, USA) (SIGCOMM ’14). Association for Computing Machinery, New York, NY, USA, 175–186. https://doi.org/10.1145/2619239.2626311
      • [18] Joao Martins, Mohamed Ahmed, Costin Raiciu, Vladimir Olteanu, Michio Honda, Roberto Bifulco, and Felipe Huici. 2014. ClickOS and the Art of Network Function Virtualization. In 11th USENIX Symposium on Networked Systems Design and Implementation (NSDI 14). USENIX Association, Seattle, WA, 459–473. https://www.usenix.org/conference/nsdi14/technical-sessions/presentation/martins
      • [19] Amy Ousterhout, Joshua Fried, Jonathan Behrens, Adam Belay, and Hari Balakrishnan. 2019. Shenango: Achieving High CPU Efficiency for Latency-sensitive Datacenter Workloads. In 16th USENIX Symposium on Networked Systems Design and Implementation (NSDI 19). USENIX Association, Boston, MA, 361–378. https://www.usenix.org/conference/nsdi19/presentation/ousterhout
      • [20] Aleksey Pesterev, Jacob Strauss, Nickolai Zeldovich, and Robert T. Morris. 2012. Improving network connection locality on multicore systems. In Proceedings of the 7th ACM European Conference on Computer Systems (Bern, Switzerland) (EuroSys ’12). Association for Computing Machinery, New York, NY, USA, 337–350. https://doi.org/10.1145/2168836.2168870
      • [21] Simon Peter, Jialin Li, Irene Zhang, Dan R. K. Ports, Doug Woos, Arvind Krishnamurthy, Thomas Anderson, and Timothy Roscoe. 2014. Arrakis: The Operating System is the Control Plane. In 11th USENIX Symposium on Operating Systems Design and Implementation (OSDI 14). USENIX Association, Broomfield, CO, 1–16. https://www.usenix.org/conference/osdi14/technical-sessions/presentation/peter
      • [22] George Prekas, Marios Kogias, and Edouard Bugnion. 2017. ZygOS: Achieving Low Tail Latency for Microsecond-scale Networked Tasks. In Proceedings of the 26th Symposium on Operating Systems Principles (Shanghai, China) (SOSP ’17). Association for Computing Machinery, New York, NY, USA, 325–341. https://doi.org/10.1145/3132747.3132780
      • [23] Deepti Raghavan, Shreya Ravi, Gina Yuan, Pratiksha Thaker, Sanjari Srivastava, Micah Murray, Pedro Henrique Penna, Amy Ousterhout, Philip Levis, Matei Zaharia, and Irene Zhang. 2023. Cornflakes: Zero-Copy Serialization for Microsecond-Scale Networking. In Proceedings of the 29th Symposium on Operating Systems Principles (Koblenz, Germany) (SOSP ’23). Association for Computing Machinery, New York, NY, USA, 200–215. https://doi.org/10.1145/3600006.3613137
      • [24] George F. Riley and Thomas R. Henderson. 2010. The ns-3 Network Simulator. Springer Berlin Heidelberg, Berlin, Heidelberg, 15–34. https://doi.org/10.1007/978-3-642-12331-3_2
      • [25] Cloudius Systems. 2014. Seastar. http://www.seastar-project.org/.
      • [26] Hajime Tazaki, Frédéric Uarbani, Emilio Mancini, Mathieu Lacage, Daniel Camara, Thierry Turletti, and Walid Dabbous. 2013. Direct code execution: revisiting library OS architecture for reproducible network experiments. In Proceedings of the Ninth ACM Conference on Emerging Networking Experiments and Technologies (Santa Barbara, California, USA) (CoNEXT ’13). Association for Computing Machinery, New York, NY, USA, 217–228. https://doi.org/10.1145/2535372.2535374
      • [27] Tencent. 2017. F-Stack. https://www.f-stack.org/.
      • [28] Maxime Vincent. 2014. PicoTCP: the reference TCP/IP stack for IoT. In FOSDEM 2014 (Brussels, Belgium). https://archive.fosdem.org/2014/schedule/event/deviot03/
      • [29] Kenichi Yasukata, Michio Honda, Douglas Santry, and Lars Eggert. 2016. StackMap: Low-Latency Networking with the OS Stack and Dedicated NICs. In 2016 USENIX Annual Technical Conference (USENIX ATC 16). USENIX Association, Denver, CO, 43–56. https://www.usenix.org/conference/atc16/technical-sessions/presentation/yasukata
      • [30] Kenichi Yasukata, Felipe Huici, Vincenzo Maffione, Giuseppe Lettieri, and Michio Honda. 2017. HyperNF: building a high performance, high utilization and fair NFV platform. In Proceedings of the 2017 Symposium on Cloud Computing (Santa Clara, California) (SoCC ’17). Association for Computing Machinery, New York, NY, USA, 157–169. https://doi.org/10.1145/3127479.3127489
      • [31] Kenichi Yasukata, Hajime Tazaki, Pierre-Louis Aublin, and Kenta Ishiguro. 2023. zpoline: a system call hook mechanism based on binary rewriting. In 2023 USENIX Annual Technical Conference (USENIX ATC 23). USENIX Association, Boston, MA, 293–300. https://www.usenix.org/conference/atc23/presentation/yasukata
      • [32] Irene Zhang, Amanda Raybuck, Pratyush Patel, Kirk Olynyk, Jacob Nelson, Omar S. Navarro Leija, Ashlie Martinez, Jing Liu, Anna Kornfeld Simpson, Sujay Jayakar, Pedro Henrique Penna, Max Demoulin, Piali Choudhury, and Anirudh Badam. 2021. The Demikernel Datapath OS Architecture for Microsecond-scale Datacenter Systems. In Proceedings of the ACM SIGOPS 28th Symposium on Operating Systems Principles (Virtual Event, Germany) (SOSP ’21). Association for Computing Machinery, New York, NY, USA, 195–211. https://doi.org/10.1145/3477132.3483569
      • [33] Lingjun Zhu, Yifan Shen, Erci Xu, Bo Shi, Ting Fu, Shu Ma, Shuguang Chen, Zhongyu Wang, Haonan Wu, Xingyu Liao, Zhendan Yang, Zhongqing Chen, Wei Lin, Yijun Hou, Rong Liu, Chao Shi, Jiaji Zhu, and Jiesheng Wu. 2023. Deploying User-space TCP at Cloud Scale with LUNA. In 2023 USENIX Annual Technical Conference (USENIX ATC 23). USENIX Association, Boston, MA, 673–687. https://www.usenix.org/conference/atc23/presentation/zhu-lingjun

        安形

        2024年08月21日 水曜日

        研究所でシステムソフトウェアの研究に取り組んでいます。

        Related
        関連記事