
2026/10/28 23:27
Redox:リングバッファプロジェクト概要
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Redox チームは、従来の手法を大幅に上回る画期的なユーザースペースベースの I/O システム「Redox Rings」の成功裏な導入を発表しました。Horizon Europe、NLnet Foundation および他からの助成金により資金が供給された本プロジェクトは 2026 年 9 月に完了し、リングバッファ機構およびパフォーマンス向上における Ibuki Omatsu、Anhad Singh、Jacob Lorentzon の功績に対し称賛を表します。Linux io_uring に着想を得た Redox Rings はタスク単位で動作し、共有メモリ領域を利用して DMA(Direct Memory Access)により高コストなカーネル側メモリーコピーを排除します。新しい
redox-rings クレイトは FFI サポートを提供し、Linux の liburing をモデルとした relibc に対応する API が導入されました。同期には futex が使用され、SQ(Submission Queue)および CQ(Completion Queue)はカーネルへのアクセスを行わずにユーザースペースプロセスとスキーム間でのみ共有されます。ベンチマークでは、Redox Rings は redox_syscall などの同期的システムよりも 14 から 15 倍高速であることを示しており、これはスケジューラを迂回した直接的なコンテキストスイッチングの実装、不要なロックの排除、ベクトルレジスタ保存オーバーヘッドの削減、physmap をhuge ページとしてマッピングといった最適化によるものです。本システムは大幅にレイテンシを低減し(IPC 往復時間が〜5800 サイクルから〜2700 サイクルへ)、強力な非同期機能を備えており、NVMe ドライバで更新された新しい非同期実行器を提供します。将来的には virtio のサポートが予定されています。今後、プロジェクトは IPC 原語のさらなる簡素化と支援範囲の継続的拡大を目指しています。本文
Redox チーム:io_uring 類似リングバッファ機能の実装とパフォーマンス最適化について
2026 年 10 月 25 日(日曜日) 関係者: 伊吹大松、アヌード・シング、ヤコブ・ローレンツォン、ロン・ウィリアムズ氏
プロジェクトの完了と感謝辞
昨年、Redox チームはアプリケーションとシステムサービス間のリングバッファ通信を実現するための第一段階を完了しました。開発の成功に心より感謝申し上げます。
-
資金支援への感謝
- NLnet ファウンデーション、NGI Zero Commons Fund、Horizon Europe の多大なサポートに敬意を表します。
- NGI Zero Commons Fund の助成期限を迎えていますが、NLnet(Restack および Code Supply を含む新資金源)や小規模テーマ基金での申請を受け付けています。
- 次回応募期: 2026 年 11 月 3 日(以降約 2 ヶ月ごと)。
-
達成された成果
- リングバッファ機構の実装と、それを活用できるシステムサービスおよびドライバの開発。
- アプリケーション向けに
およびio_uring
に準じた API の完成と実証。liburing - システムサービス間の切り替え速度の大幅な向上。
技術的な詳細については各担当者より解説いたします。
リングバッファの概要
(アヌード・シング氏)
背景と課題
- Linux における従来型の非同期 I/O(カーネル固有 AIO)は複雑で、パフォーマンスに懸念がありました。
- POSIX AIO は実装が未熟・低速であり、代替案(fibrils, syslets/threadlets)はマージされませんでした。
- Jens Axboe 氏によって提案された
は、「効率的」「拡張可能」「使いやすく誤用が難しい」という設計思想で Linux 5.1 で採用されました。io_uring
Redox Rings の特徴
Redox(マイクロカーネル)では、I/O をユーザースペースのスキームプロセス内で処理します。開発された非同期 I/O インターフェース「Redox Rings」は以下の特性を持ちます。
- io_uring 類似機構の採用: アプリケーションがブロックされずに、適切なスキームへ直接リクエストを提出可能。
- 共有メモリの活用: スキームとアプリケーション間で別々の共有メモリアリーフを提供し、DMA 対応メモリを含めメモリーコピーなしで I/O リクエスト発行が可能。
- 移植性設計:
に類似しており、プロセス間通信(例:RedoxFS ↔ NVMed)でも利用可能。liburing
用語解説
リングバッファは配列をバックエンドとする循環キューです。本インターフェースでは以下の共有要素を使用します。
- SQ (Submission Queue): アプリケーションから書き込み、スキームが読み取るキュー(リクエスト用)。
- CQ (Completion Queue): スキームから書き込み、アプリケーションが読み取るキュー(レスポンス用)。
- SQE / CQE: 各キュー内のエントリ。
- Buffer Pool: アプリケーションとスキームで共有する連続メモリアリーフ(データバッファ割り当て領域)。
- Data Buffer: リクエスト単位のスライス(単一データのみサポート、オフセットと長さにより定義)。
排他的なアクセス制御: 各キューは生成元と消費元が 1 つずつであるため、共有ロック機構の排除と高パフォーマンスを実現。
redox-ring API
redox-ring API(伊吹大松氏)
Redox OS 初となるリングバッファ実装を完了しました。Linux の
io_uring と異なり、SQ と CQ はユーザースペースプロセス間で排他的に共有され、カーネルからはアクセスしません。
- 技術スタック:
- クリート名:
(FFI 用途のデータ構造も提供)。redox-rings - 同期機構:主に
、オプションで pipe ファイル記述子支援。futex - FFI サポートに基づき、Linux の
に着想を得た **「redox-ring API」**をliburing
に導入。relibc
- クリート名:
主要な関数一覧
リングバッファ、共有メモリ、リクエスト管理の機能を提供します。
// リンクバッファ接続の初期化 redox_ring_queue_init_with_path() // 共有メモリアリーフからバッファを割り当てる redox_ring_alloc_buf() redox_ring_alloc_sized() // 提出キューエントリ(SQE)を取得 redox_ring_get_sqe() // 待機中のリクエストをデーモンへ提出(バッチ提出可) redox_ring_submit() // 完了キューエントリ(CQE)を待ち受け redox_ring_wait_cqe() // CQE を処理済みとしてマーク redox_ring_cqe_seen()
- その他:ファイル記述子登録、バッファ解放、インスタンス撤廃等の関数も用意されています。
共有メモリの使用法
redox-rings 実装では SQE、CQE、I/O データの交換に共有メモリを使用します。
- 初期化時に
システムコール(fmap
モード)で各領域をアプリケーションアドレス空間へマッピング。MAP_SHARED - 結果: 両側が同じメモリへアクセスでき、プロセス間での I/O データコピーを回避。
バッファ割付戦略
API は以下の 2 つの戦略をサポートします。
- フォックスサイズ割付
- 共有メモリプールの単一割り当てるを使用。
- 固定サイズチャンクへ分割し、利用可能なオフセットリストを維持。
- ダイナミック割付
クリートを使用。redox-buffer-pool- 様々なサイズとアライメントのバッファを割り当て(B 木を用いて解放済み/占有済み領域を管理)。
両戦略とも、ポインタおよび共有メモリアリーフ内でのオフセットを返します。完了後、アプリケーションによるバッファ解放でメモリが再利用されます。
セッションの作成と管理
(アヌード・シング氏)
redox_ring_queue_init_with_path() 関数はスキームリングハンドルを開き、SYS_CALL システムコールを用いてセッションを構築します。
- 返されるもの: SQ、CQ、共有バッファプールのファイル記述子(アプリケーションアドレス空間へマッピング済み)。
- 動作フロー:
- アプリケーション:キューを直接使用してリクエスト提出・完了受信。
- スキーム側:ワーカータスクが SQ エントリを待ち受け、非同期処理を行い、完了時に通知。
実装例:RamFS へのデータ書き込み手順
リングバッファ支援は RamFS および NVMed に追加され、テストも完了しています。
- 初期化:
で目標ファイルをオープンし、RamFS インスタンスを起動。redox_ring_queue_init_with_path() - 登録: ファイル記述子を登録し、以降のインデックス参照が可能に。
- 割り当て: 共有メモリアリーフからバッファを割り当ててデータ書き込み。
- SQE 作成: 書き込み操作、ファイルインデックス、バッファオフセット、長さ、ファイルオフセットを指定。
- 提出:
で SQE を提出(バッチ可能)。redox_ring_submit() - 完了処理: CQE を待ち受け結果を確認し、完了したリクエスト関連のバッファを解放。
最終的にリングバッファ接続を撤廃します。
非同期実行器
(アヌード・シング氏)
デバイスドライバ用の非同期実行器を開発し、以下を実現しました。
- アーキテクチャ: 1 つの割り込みベクトルと 1 コアあたりの SQ/CQ ペアを持つ設計。
- 現状: 単一コア利用中(マルチスレッド・パーコア支援は進行中)。
- 拡張性: NVMe ドライバへの更新完了。virtio などの他のデバイスも追随予定。
動作原理:
- Redox Rings をサポートするスキームでは、各 I/O リクエストを独自非同期タスクとして処理。
- セッションごとにワーカースレッド起動(撤廃時に停止・キャンセル・クリーンアップ)。
パフォーマンス改善
図 1 に示すベンチマーク結果より、新しいインターフェースの優位性が明確です。
比較結果:
は従来のredox_ring(同期システムコール)に対し、約 14〜15 倍高速。redox_syscall
カーネルおよび IPC の最適化
(ヤコブ・ローレンツォン氏)
IPC は依然として低速な部分があり、リングバッファによるオーバーヘッド緩和と共に重要課題です。以下のような多角的な最適化を行いました。
インフラ改善
- ベンチマークスイート拡張:
テストスイートに IPC レイテンシを測定するターゲット済みベンチマーク(acid
,acid_ipc_latency_simultaneous
)を追加。acid_heavy_forking - 統計機能向上: 反復測定と適切な統計収集に対応し、変化の有意性を把握可能に。
Miscellaneous リファクタリング
- 冗長なロックの排除、ハッシュマップルックアップ削減。
- IPC 用の低オーバーヘッドコール(seL4 の「reply-wait」に似た機能)導入。
ベクトルレジスタを用いない高速パス切り替え
フレイムグラフ分析により、
XSAVE / XRSTOR 命令による数百サイクルのオーバーヘッドを特定しました。これらはベクトルレジスタの保存/復元を行うものです。
- 最適化手法: コール側とキャリー側がシステムコール経由で入る場合、レジスタを保存・復元せず、カーネル内でゼロクリアすることでコスト削減。
- ABI の変更: Redox がシステムコール ABI を不安定化し、
のrelibc
シンボルを優先した結果、System V ABI によるベクトルレジスタ汚染を回避し、ほぼゼロコストに改善。libredox
直接切り替え(Direct Switching)
スケジューラー呼び出しが IPC の主要ボトルネックでした。スケジューラは BTreeMap アクセスや多数のロック取得によりブロックしがちです。
- 実装: カーネル MR 694 で「直接コンテキストスイッチング」を実装。
- 効果: IPC レイテンシを15〜20% 削減。
- 仕組み: 現在のコンテキストとスケジューリングされたコンテキストを分離し、クライアントプロセス(通常
)が準備できている場合はスケジューラーをバイパスして直接スキームへ切り替え。SYS_CALL
ヒューージページ導入
以前はカーネルで 4K ページのみでしたが、2M ページへのマッピングを実現しました。
- 効果: TLB の使用量が理論上最大 512 倍削減可能(重負荷 CoW でも)。
- 実績:
ベンチマークで L1DTLB ミス率が**-75%**向上。acid_heavy_forking
今後の改善目標
(ヤコブ・ローレンツォン氏)
現在の課題
- IPC ラウンドトリップレイテンシは約 5800 サイクルから約 2700 サイクルへ削減されましたが、seL4 などの高速マイクロカーネルと比較すると依然として高めです。
類似ベンチマークでは、コールあたりのオーバーヘッドは少なくとも約 32K サイクル。dd bs=4k if=/dev/zero of=/dev/null
次のステップ
追加の最適化としては以下の点が検討・実装予定です。
- ロック数の削減 とシステムコールエントリオーバーヘッドの削減(IPC プライミティブの簡略化)。
- 要求バッファなど不必要な部分の削除。
- ユーザースリングバッファの有無を問わず、より現実的なワークロードにおけるオーバーヘッド分布の詳細調査。