はじめに
• ネットワークの高速化に伴って
ハード・ソフト両面でネットワークIOの実装 が繰り返し見直されてきている
• これがLinuxカーネルの実装にも大きく影響し
ている
• 厳密にはルータではなくサーバの話だが
Vyattaで用いられるPCルータにも大きく関係
旧来のパケット受信処理
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
パケット受信 プロトコル処理
ソケット 受信処理
ユーザ プログラム
user buffer
input queue socket queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み ユーザ空間へコピー
ハードウェアの進化
• NIC性能の急激な向上
• NIC:1GbE→10GbE
• CPU:1GHz→3.2GHz・メモリ:CPUの1/10のペース
• マルチコアCPUの普及
• 1CPUコアの性能を上げる→コア数を増やしていく
• ソフト・ハードの設計をマルチコア環境で性能が 出るように変えていく必要が出てきた
割り込みが多すぎる
• NICの性能向上によって、一定時間に
NICが処理できるパケット数が飛躍的に 増加
• 1パケット毎に割り込みが来ると、通 信量が多いときにコンテキストスイッ チ回数が増えすぎ性能が劣化
割り込みが多すぎる
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
パケット受信 プロトコル処理
ソケット 受信処理
ユーザ プログラム
user buffer
input queue socket queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み ユーザ空間へコピー
Interrupt Coalescing
• ハードウェアでの対応
• パケット数個に一回割り込む、
或いは一定期間待ってから割り込む
• 割り込みを間引く
• デメリット:レイテンシが上がる
ソフトウェアでの対応
• ポーリング
• NICの割り込みを使わずに、タイマーを使って定期 的にNICのレジスタをポーリング、パケットが有っ たら受信処理
• ハイブリット方式
• 通信量が多く連続してパケット処理を行っている時 のみ割り込みを無効化、ポーリングで動作
→NAPI(Linux) 解説:http://tinyurl.com/LinuxNAPI
NAPI
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システムコール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる まで繰り返し
プロトコル処理が重い
• 高速なNICを用いる環境では、ホストCPUで パケットを一つづつ処理する作業が大きな オーバヘッドになっている
→CPUがボトルネック
• 例:全二重な1Gbpsの通信を行うと、
Pentium4 2.4GHzでCPU時間を80%消費
• CPUをプロトコル処理から開放したい
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システムコール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる まで繰り返し
プロトコル処理が重い
(TCP Offload Engine)TOE
• NICに実装されたTCP/IPスタックへプロトコル処理を フルオフロード
• デメリット
• セキュリティ:TOEにセキュリティホールが生じて も、OS側から対処が出来ない
• 複雑性:OSのネットワークスタックをTOEで置き換 えるにはかなり広範囲の変更が必要であり、更に
メーカによってTOEの実装が異なる
(TCP Offload Engine)TOE
• Linux:サポート予定無し
• Windows:コネクションはOSで管理
解説:http://bit.ly/offload
• 特定用途:RDMA, iSCSI HBA
部分的なオフロード
• TCP Checksum Offload
TCPのチェックサム計算
• Large Segment Offload
大きなパケット(例:64KB)をまとめて渡す と、NICでMTUに合わせて分割送信する
• Large Receive Offload
LSOの逆で、NIC上でパケットを結合し大きな パケットにしてカーネルに渡してくれる
Linux
の対応状況
• TCP Checksum Offload
TCPのチェックサム計算
• Large Segment Offload
大きなパケット(例:64KB)をまとめて渡す と、NICでMTUに合わせて分割送信する
• Large Receive Offload
LSOの逆で、NIC上でパケットを結合し大きな パケットにしてカーネルに渡してくれる
対応
ソフトウェアで実装
マルチコアが活用出来ない
• マルチコア環境においても一つのNICの 受信処理は一つのCPUでしか行えてい ない
• 通信量が多いときにパケット処理の負 荷が特定のコアへ大きく偏り性能に悪 影響を及ぼす
複数の
CPUでパケット処理したい
cpu0
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システムコール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる まで繰り返し
cpu1
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システムコール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる まで繰り返し
Receive Side Scaling
• パケットヘッダのハッシュ値を元にパケットを 複数の受信キューへ振り分け
• 受信キューはそれぞれのCPUコアに対応、
それぞれのCPUへ割り込む
• CPUごとに並列にパケット処理が行えるようになる
• 同一フローは一つのCPUへ振り分けられる
→データローカリティを考慮
Receive Side Scaling
NIC
パケットパケットパケット
ハッシュ計算
パケット着信
hash queue
ディスパッチ 参照 RX
Queue
#0
RX Queue
#1
RX Queue
#2
RX Queue
#3
cpu0 cpu1 cpu2 cpu3
受信処理 割り込み
受信処理
■
■
0 1
Receive Side Scaling
• MicrosoftがScalable Network Initiativeで提唱 解説:http://bit.ly/ReceiveSideScaling
• Windows・Linuxでサポート
• ハードウェア対応が必要
• PCIバスのMSI-Xサポート
• NICへのRSS実装
RPS(Linux)
• RSS非対応のオンボードNICをうまくつかってサー
バの性能を向上させたい
• ソフトでRSSを実装してしまおう
• ソフト割り込みの段階でパケットを各CPUへばら まく
• CPU間割り込みを使って他のCPUを稼動させる
• RSSのソフトウエアによるエミュレーション
cpu3 cpu2
cpu1 cpu0
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システム コール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込み
パケット受信 ハッシュ計算 ディスパッチ
プロトコル処理 ソケット 受信処理
ユーザ
プログラム user
buffer
socket queue
backlog
#1 hash queue
■ 参照
■ 01
CPU間 割り込み
backlog
#2
backlog
#3
RFS(Linux)
• 受信待ちプロセスがいるCPUへパケッ トをディスパッチ出来る仕組みをRPSに 追加
• データローカリティの向上、レイテン シの削減
RPS
のワーストケース
NIC
デフォルトCPUへ割り込み
CPU0 CPU1 CPU2 CPU3
割り込みハンドラ
ネットワーク スタック プロセス起床
ポーリング
バッファ
プロセスB プロセス起床
プロセスがいる
CPUへ転送
NIC
デフォルトCPUへ割り込み
CPU0 CPU1 CPU2 CPU3
割り込みハンドラ
ネットワーク スタック プロセス起床
プロセスA
ポーリング
バッファ
ネットワーク スタック プロセス起床
プロセスB
それでも遅い
• Intelの取り組み:http://bit.ly/IOATJ
• 何故、高速なNIC、CPU・最適化されたOSを使用している
にも関わらずサーバのパフォーマンスは上がらないのか?
• 最も深刻なボトルネックはCPUにネットワークI/O処理を 行わせていることが原因ではなく、データ移動に伴うオー バヘッドだった
• メモリの速度はCPUよりはるかに低速であるため、メモリ アクセス時のメモリ・フェッチにはかなりの時間がかる
TOE
は要らない子
• TOEではごく僅かな性能改善しか出来ず、レイテン シの根本的な問題を解決していない
• 何故、CPUより性能の低いオフロードエンジンが CPUよりも速いと考えられていたのか?
→TCP/IPのデータ操作に最適化されている為
• 最適化されたTCP/IPスタックをCPU上に実装、
性能測定を行いTOEより高速化される事を確認
→オンロード
Intel I/O Acceleration Technology
• Intel QuickData Technology
• Direct Cache Access
• Receive Side Scaling
• Large Receive Offload
• Low Latency Interrupts
+最適化されたネットワークスタック
• NICのバッファ→アプリケーションの
バッファへパケットをDMA転送
• CPU負荷を削減
• チップセットに実装、OSから利用
Intel QuickData Technology
Process(User)
Process(Kernel)
HW Intr Handler SW Intr Handler
割り込み無効化
プロトコル処理 ソケット 受信処理
ユーザ プログラム
user buffer
socket queue
パケット
システムコール
プロセス起床
ハードウェア割り込み ユーザ空間へコピー
パケットパケット
ソフトウェア割り込みスケジュール
パケット受信
パケットが無くなる まで繰り返し
Intel QuickData Technology
Direct Cache Access
• NICからメモリへDMA転送されたパケットを
CPUからアクセスする時、キャッシュへ
フェッチする為にレイテンシが発生している
• NICからキャッシュへ直接転送したい
• 難しいので、必ずprefetchが掛かるように
ハードの実装を変更、フェッチコストを隠蔽
DCA
無し
I/O Device Memory Controller
CPU
Cache
Memory
DMA Write
Snoop invalidate Writeback
Memory Wirte Fetch
DCA
有り
I/O Device Memory Controller
CPU
Cache
Memory
DMA Write
Snoop invalidate Writeback
Memory Wirte
HW Prefetch +hint
仮想化環境でも
パフォーマンスを出したい
• Intel VT-c
• SR-IOV
• 複数のゲストOSとNICを直接接続
• VMDq
• VM間のIOスケジュール
従来の仮想ハードウェア
VM1
Hypervisor
フロントエンド ドライバ
VM2
フロントエンド ドライバ
バックエンド ドライバ デバイス ドライバ
デバイス
Intel VT-d
による
PCI PassthroughVM1
Hypervisor
デバイス ドライバ
VM2
デバイス
SR-IOV
VM1
Hypervisor
VFデバイス ドライバ
VM2
VFデバイス ドライバ
PFデバイス ドライバ
デバイス
仮想 デバイス
仮想 デバイス
VMDq
VM1
Hypervisor
VFデバイス ドライバ
VM2
VFデバイス ドライバ
PFデバイス ドライバ
デバイス
仮想 デバイス
仮想 デバイス RX1
RX1 RX1
RX2 RX2
RX1 RX1 RX1 RX2
RX2
まとめ
• ソフトウェア・ハードウェア双方で最適化を進 めないとならない
• ある時点で正しかった答えがずっと正しいとは 限らない
• 一つの解決策だけで問題が解消するとは限らな い
• Intelがんばるなぁ