Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

15,734 views

Published on

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

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

×