Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
マルチコアとネットワー
クスタックの高速化技法
@syuu1228
13年4月23日火曜日
はじめに
• ネットワークの高速化に伴って
ハード・ソフト両面でネットワークIO
の実装が繰り返し見直されてきている
• これがOSの実装にも大きく影響
13年4月23日火曜日
NIC性能の急激な向上
• NIC:1GbE→10GbE
• CPU:1GHz→3.2GHz
• メモリ:CPUの1/10のペース
→CPUやメモリの速度がネットワーク
IOのボトルネックに
13年4月23日火曜日
マルチコアCPUの普及
• コア数は増えていっている
• 1コアあたりの性能は不足
→ネットワークIOをマルチスレッドで
処理する必要が出てきた
13年4月23日火曜日
今日のお題
1. 割り込み頻度の問題
2. オフローディング
3. データ移動に伴うオーバヘッド
4. プロトコル処理の並列化
13年4月23日火曜日
ちょっとおさらい
13年4月23日火曜日
Network stack in
4.3BSD
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年4月23日火曜日
1. 割り込み頻度の問
題
13年4月23日火曜日
割り込みが多すぎる
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年4月23日火曜日
割り込みが多すぎる
• 割り込みの頻度が高すぎて、他の処理
の実行が阻害される
• 割り込みに伴うコンテキスト切り替え
のコストが高い
13年4月23日火曜日
Interrupt Coalescing
• ハードウェアでの対応
• パケット数個に一回割り込む、
或いは一定期間待ってから割り込む
• 割り込みを間引く
• デメリット:レイテンシが上がる
13年4月23日火曜日
Interrupt Moderation
on ixgbe(4)
• hw.ixgbe.enable_aim
流量に応じ動的に割り込み頻度を調整
• hw.ixgbe.max_interrupt_rate
割り込み頻度を指定
• hw.intr_storm_threshold
割り込みが多すぎると警告が出るようにな
っているので、警告上限を上げる必要がある
13年4月23日火曜日
Interrupt Moderationを切っ
てみる
• Linux, ixgbeで実験
• modprobe ixgbe InterruptThrottleRate=0,0
• iperf -s / iperf -c <IP>
• 24000 - 31000 interrupts/sec for 1CPU
(これでも後述のハイブリッド方式の為、
ソフト的に割り込み抑制をかけている)
13年4月23日火曜日
どれくらいの頻度に設定さ
れているのか
• 10GbEだと頻度が低すぎてもバッファ
れやレイテンシ増大の原因になる
• Linuxのe1000eやixgbeでは8000
interrupts/secがデフォルトの閾値
(但し最新のixgbeだと動的調整がデフ
ォルトになっている)
13年4月23日火曜日
Polling
• ソフトウェアでの対応
• NICの割り込みを無効化
• タイマーを使って定期的にNICのレジスタをポーリン
グ、パケットが有ったら受信処理
• デメリット
• タイマー周期分のレイテンシが発生
• タイマー割り込み間隔を上げるとオーバヘッドが増大
13年4月23日火曜日
polling(4)
• options DEVICE_POLLING
options HZ=1000
• sysctl kern.polling.enable=1
sysctl kern.polling.user_frac=50
• CPUが遅い場合は効果がある
• 後述のマルチキューNICに非対応
HZ=1000程度では10GbEには不足
→新しいサーバには不向き
13年4月23日火曜日
ハイブリッド方式
• ソフトウェアでの対応
• 通信量が多く連続してパケット処理を
行っている時のみ割り込みを無効化、
ポーリングで動作
• Ringバッファからパケットが無くなった
ら割り込みを有効化
13年4月23日火曜日
netisr direct dispatch
• LinuxのNAPIと同様
• 割り込みコンテキストから
直接プロトコル処理を実行
• Ringバッファにパケットが
ある間、NICの割り込みを
禁止
• Ringバッファが空になった
ら割り込み再開
Process(User)
Process(Kernel)
HW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システムコール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
13年4月23日火曜日
Low latency interrupt
• ハードウェアでの対応
• Interrupt Coalescingを行った結果レイテ
ンシが増大
• 低レイテンシで処理したいパケットを
判別
Coalescingを無視して即時割り込み
13年4月23日火曜日
LLI on ixgbe
• 以下のようなフィルタで即時割り込みするパケットを指定
• 5-tuple(protocol, IP address, port)
• TCP flags
• frame size
• Ethertype
• VLAN priority
• FCoE packet
• 但しFreeBSDのixgbeドライバでは非サポート
13年4月23日火曜日
2. オフローディング
13年4月23日火曜日
プロトコル処理が重い
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年4月23日火曜日
プロトコル処理が重い
• 特に小さなパケットが大量に届く場合
にプロトコル処理でCPU時間を大量に
使ってしまう
13年4月23日火曜日
TOE
(TCP Offload Engine)
• NIC上のTCP/IPスタックへプロトコル処理をフルオフロード
• デメリット
• セキュリティ:TOEにセキュリティホールが生じても、OS側から対処
が出来ない
• 複雑性:OSのネットワークスタックをTOEで置き換えるにはかなり広
範囲の変更が必要
メーカによってTOEの実装が異なり、TOE用の共通APIを作るのが困難
OSのプロトコル処理をバイパスするのでパケットフィルタと相性が悪
い
• 対応NICは少ない
13年4月23日火曜日
toecore
• Chelsio 10GbEのみサポート
• options TCP_OFFLOAD
• ifconfig cxgbe0 toe
• カーネルはmbuf アプリ間のデータコ
ピーのみを行い、プロトコル処理はNIC
が行う
13年4月23日火曜日
TOEよりも更に丸投げ
• iWARP
NICによるゼロコピー通信(RDMA)のサポート
InfiniBandと同じインタフェースでリモートノードへア
クセス
通信にはTCP/IPが使われているが、NICがプロトコル
を喋る
• iSCSI・FCoE
OSに対してはSCSIコントローラのように振る舞う
NICがiSCSI・FCoEプロトコルを喋る
13年4月23日火曜日
Checksum Offloading
• IP・TCP・UDP checksumの計算をNICで
行う
• フルオフローディングと異なりOSでの
対応が容易
13年4月23日火曜日
FreeBSDでの
Checksum Offloading
• ifconfig -m ix0|grep capabilities
どんな種類のchecksum offloadingをサポ
ートしているか確認
• ifconfig ix0 rxcsum txcsum rxcsum6
txcsum6
checksum offloadingの有効化
• TOEと異なり多くのNICが対応している
13年4月23日火曜日
Checksum Offloadは
どれくらい性能に影響するのか
• Linux, ixgbeで実験
• ethtool -K ix0 rx off
• iperf -s / iperf -c <IP>
• 有効:7.99 Gbits/sec
• 無効:6.66 Gbits/sec
13年4月23日火曜日
Large Segment Offload
(TCP Segmentation Offload)
• パケット送信時の分割処理をNICへオフ
ロード
• OSはパケット分割処理を省略出来る
13年4月23日火曜日
FreeBSDでの
Large Segment Offload
• ifconfig -m ix0|grep capabilities
TSO4が表示されていればTCPv4
TSO6が表示されていればTCPv6のLSOに対応
• ifconfig ix0 tso4 tso6
Large Segment Offloadの有効化
• カーネルからはMTUサイズがとても大きな
NICへパケットを送信しているように見える
13年4月23日火曜日
Large Segment Offloadは
どれくらい性能に影響するのか
• Linux, ixgbeで実験
• ethtool -K ix0 tso off
• iperf -s / iperf -c <IP>
• 有効:8.96 Gbits/sec
• 無効:9.00 Gbits/sec
13年4月23日火曜日
Large Receive Offload
• LSOの逆
• 受信パケットをNIC上で結合
1つの大きなパケットとしてOSへ渡す
• プロトコルスタックの呼び出し回数が
少なくて済む
13年4月23日火曜日
FreeBSDでの
Large Receive Offload
• ifconfig -m ix0|grep capabilities
LROが表示されていれば対応
• ifconfig ix0 lro
Large Receive Offloadの有効化
• カーネルからはMTUサイズがとても大き
なNICからパケットが送られてきているよ
うに見える
13年4月23日火曜日
Large Receive Offloadは
どれくらい性能に影響するのか
• Linux, ixgbeで実験
• ethtool -K ix0 lro off
• iperf -s / iperf -c <IP>
• 有効:8.03 Gbits/sec
• 無効:7.84 Gbits/sec
13年4月23日火曜日
LSO・LROのSW実装
• LinuxではLSO・LROをソフトウェアで実装
している
• オフロードではなくソフトウェア処理で
も、結果的にプロトコルスタックの実行回
数が減るならば性能が上がる余地がある
• FreeBSDはHWのみの対応
13年4月23日火曜日
3. データ移動に伴う
オーバヘッド
13年4月23日火曜日
TOEがネットワークIOパフ
ォーマンスの解決策か?
• 大きなパケット(>8KB)を用いるデータベースサーバなど
のユースケースならTOEは有効
→より小さなパケットの多い他のサーバにはあまり有効で
ない
• iWARPやiSCSI HBAなどのオフローディング方式では既存の
アプリを載せられない
• ローエンドなNICのTOEエンジンは新しいXeonよりずっと
遅い→オフロードする事でかえってパフォーマンスが落ち
る事もありえる
13年4月23日火曜日
どの処理が重いのか
• プロトコル処理よりもむしろNIC・メモ
リ・CPUキャッシュの間でのデータ移
動に伴うオーバヘッドの方が重いケース
がある
• 特にメモリアクセスが低速
13年4月23日火曜日
• NICのバッファ→アプリケーションのバ
ッファへパケットをDMA転送
• CPU負荷を削減
• チップセットに実装
• (Intel I/O ATとも呼ばれる)
Intel QuickData Technology
13年4月23日火曜日
Intel QuickData Technology
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
13年4月23日火曜日
Intel QuickData Technology
• FreeBSDでは非対応
13年4月23日火曜日
Intel Data Direct I/O
Technology
• 従来、NICはメモリにパケットを書き込み、CPUはメ
モリからキャッシュにパケットを読み込んでからアク
セスしていた
• DDIOではNICがCPUのキャッシュへDMAを行えるよ
うにする
→メモリアクセス分のレイテンシを削減
• 新しいXeonと10GbEでサポート
• OS側での対応は不要な模様
13年4月23日火曜日
4. プロトコル処理の
並列化
13年4月23日火曜日
旧型のプロトコルスタックでは
マルチスレッドで処理できない
Process(User)
Process(Kernel)
HW Intr Handler
SW Intr Handler
パケット受信
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
input
queue
socket
queue
パケット
システムコール
プロセス起床
ソフトウェア割り込みスケジュール
ハードウェア割り込み
ユーザ空間へコピー
• システムに1つしか
ない受信キュー
• 並列化されていない
ソフトウェア割り込
みハンドラ
13年4月23日火曜日
FreeBSD network stackのマ
ルチスレッド対応
• 3つの処理方式を実装
• マルチスレッド化されたランキューに
積んでスケジュールする方式
• direct dispatch
(その場でプロトコル処理)
• ハイブリッド
13年4月23日火曜日
マルチスレッド化されたランキュ
ーに積んでスケジュールする方式
• net.isr.dispatch = deferred
net.isr.maxthreads
net.isr.bindthreads
• プロトコル処理用のワーカースレッドを任意の数起
動できる
• スレッドごとに受信キューを持つ
• スレッドはCPUに固定する事も、通常のプロセス同
様にマイグレートされるように設定する事も可能
13年4月23日火曜日
送り先スレッドの選択方法
は?
• プロトコル毎にポリシー
(NETISR_POLICY_*)とハンドラ関数
で設定されている
• イーサーネットなら
NETISR_POLICY_SOURCE
→NICによってスレッドを決定
13年4月23日火曜日
direct dispatch
• net.isr.dispatch = direct
• 常に割り込みコンテキストでプロトコ
ル処理
13年4月23日火曜日
ハイブリッド
• net.isr.dispatch = hybrid
• deferredと基本的に同じように動作しよ
うとするが、宛先スレッドが自CPUの
ものだったらdirect dispatchする
13年4月23日火曜日
それでも1つのNICからのパケ
ットは1つのCPUで処理される
• 1つのNICは1つの割り込みしか持たない
• 受信処理の途中でパケットを複数のコアに
割り振る仕組みがない
→ NICが複数あって割り込み先CPUが分散さ
れていれば並列に処理されるが、1つのNIC
からのパケットは1つのCPUで処理される
13年4月23日火曜日
でも…
• ネットワークIO負荷が高いと1コアでは捌き切
れなくなってくるケースがある
• その場合、アイドルなコアがあるのに1コアだ
けカーネルが8∼9割のCPU時間を食ってしま
い、アプリの性能が落ちるという現象が発生
• 1つのNICに届いたパケットを複数のコアに分
散して処理したい
13年4月23日火曜日
MSI-X割り込み
• PCI Expressでサポート
• デバイスあたり2048個のIRQを持てる
• それぞれのIRQの割り込み先CPUを選べ
る
→1つのNICがCPUコア数分のIRQを持
てる
13年4月23日火曜日
ランダムにパケットを分散
すれば良いのか?
• 複数コアで1つのNICに届いたパケットを並列に受信処理を
行うと到着順と異なる順序でプロセスに渡される可能性が
ある(CPU間で待ち合わせを行わない限りどんな順で処理
が終わるかは保証できない)
• UDPには順序保証が無いので問題ない
• TCPには順序保証が有るので並列に処理されるとパケットの
並べ直し(リオーダ)が発生してパフォーマンスが落ちる
• 1つのフローのパケットがバラバラのコアで処理されると、
キャッシュ競合が増えて性能が落ちる可能性がある
13年4月23日火曜日
Receive Side Scaling
• (Multi Queue NICとも呼ばれる)
• パケットヘッダのハッシュ値を元にパケットを複数
の受信キューへ振り分け
→同一フローは同じキューへ
• 振り分け先キューはハッシュテーブルの値に基づく
• 受信キューはそれぞれIRQを持ち、別々のCPUへ割
り込む(キュー数がコア数より少ない事もある)
13年4月23日火曜日
Receive Side Scaling
NIC
パケットパケットパケット
ハッシュ計算
パケット着信
hash queue
ディスパッチ
参照
RX
Queue
#0
RX
Queue
#1
RX
Queue
#2
RX
Queue
#3
cpu0 cpu1 cpu2 cpu3
受信処理
割り込み
受信処理
■
■
0
1
13年4月23日火曜日
MultiQueue NIC on
FreeBSD (dmesg)
igb5: <Intel(R) PRO/1000 Network Connection version - 2.0.7> port
0x1000-0x101f mem 0xb2400000-0xb241ffff,0xb1c00000-0xb1ffffff,0xb2440000-
igb5: Using MSIX interrupts with 9 vectors
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: [ITHREAD]
igb5: Ethernet address: 00:1b:21:81:e9:57
MSI-Xによって複数の割り込みベクタが確保されて
いる
13年4月23日火曜日
MultiQueue NIC on
FreeBSD (vmstat -i)
# vmstat -i | grep ix0
irq256: ix0:que 0 3555342 10305
irq257: ix0:que 1 3120223 9044
irq258: ix0:que 2 3408333 9879
irq259: ix0:que 3 3279717 9506
irq260: ix0:link 4 0
キュー毎にIRQが割り当てられている
13年4月23日火曜日
受信キューの割り当て
• フローに割り当てら
れたキューが宛先プ
ロセスのCPUと異な
るとオーバヘッドが
発生する
CPU0 CPU1 CPU2 CPU3
割り込みハンドラ
ネットワーク
スタック
プロセス起床
プロセスA
キュー2
ネットワーク
スタック
プロセス起床
プロセスB
割り込みハンドラ
キュー3
13年4月23日火曜日
受信キューの割り当て
• ハッシュテーブルの
設定値を変更する事
でCPUを一致させる
事ができる
CPU0 CPU1 CPU2 CPU3
割り込みハンドラ
ネットワーク
スタック
プロセス起床
プロセスA
バッファ
ネットワーク
スタック
プロセス起床
プロセスB
割り込みハンドラ
バッファ
13年4月23日火曜日
Receive Side Scalingの制限
• 例えばIntel 82599 10GbE Controllerだと:
• Redirection Tableは128エントリ
• ハッシュ値は下位4bitのみ使用
• フローが多いとハッシュ衝突する為、特
定フローを特定CPUへキューするのには
あまり向いていない
13年4月23日火曜日
Intel Ethernet Flow
Director(ixgbe)
• フローとキューの対応情報を完全に記録
• 32kのハッシュテーブルの先にリンクドリスト
• 2つのFilter mode
• Signature Mode:ハッシュ値→最大32k個
• Perfect Match Mode:ヘッダの完全マッチ(dst-
ip, dst-port, src-ip, src-port, protocol)→最大8k個
13年4月23日火曜日
Intel Ethernet Flow Director
のフィルタ更新方法
proce
ss
送信処理
システムコール
ソケット
プロトコル
スタック
ドライバ
Txq
NIC
フィルタ
更新
Flow
Director
Filters
プロセスコンテキストからのパケット送出時に送信
元CPUとパケットヘッダを用いてフィルタを更新
13年4月23日火曜日
Intel Ethernet Flow
Director on FreeBSD
• ixgbeのドライバはデフォルトでFlow
Directorを有効にしている
13年4月23日火曜日
RPS(Linux)
• RSS非対応のオンボードNICをうまくつかってサー
バの性能を向上させたい
• ソフトでRSSを実装してしまおう
• ソフト割り込みの段階でパケットを各CPUへばら
まく
• CPU間割り込みを使って他のCPUを稼動させる
• RSSのソフトウエアによるエミュレーション
13年4月23日火曜日
cpu3cpu2cpu1cpu0
割り込み無効化
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
パケット
システム
コール
プロセス起床
ハードウェア割り込み
ユーザ空間へコピー
パケットパケット
ソフトウェア割り込み
パケット受信
ハッシュ計算
ディスパッチ
プロトコル処理
ソケット
受信処理
ユーザ
プログラム
user
buffer
socket
queue
backlog
#1
hash queue
参照
■
■
0
1
CPU間
割り込み
backlog
#2
backlog
#3
13年4月23日火曜日
RFS(Linux)
• 受信待ちプロセスがいるCPUへパケッ
トをディスパッチ出来る仕組みをRPSに
追加
• データローカリティの向上、レイテン
シの削減
13年4月23日火曜日
RPS/RFS for FreeBSD
• GSoC’11 by Kazuya GODA
• マージされていないが実装済
ベンチマークで性能が向上する事を確
認
13年4月23日火曜日
まとめ
• 高速なネットワークIOを捌くために様々な改善が行わ
れている事を紹介
• ハードウェア・ソフトウェアの両面で実装の見直しが
繰り返し要求されており、その範囲はネットワークに
直接関係ないような所にまで及ぶ
• 取り敢えず明日から出来ること:
まずはサーバに取り付けるNICを選ぶときに「マルチキ
ューNIC」「RSS対応」などとされているものを選ぼう
13年4月23日火曜日

More Related Content

マルチコアとネットワークスタックの高速化技法