■LANのデータ転送速度が,ギガビット・イーサネット(GbE)や10GbEの登場で高速化している。これに伴い,サーバーのCPUにおけるTCP/IPネットワーク処理の負荷が問題になっている。
■そこで注目されるのがTCP/IP処理をNIC上の専用プロセッサに任せるオフロード機能である。Windowsのネットワーク・タスクのオフロード機能を説明するとともに,その有効性を検証した。
(2005年3月号「Windowsテクノロジ徹底解説」より)
昨今,サーバー機が使用するLAN(ローカル・エリア・ネットワーク)は,データ転送速度100Mビット/秒のファースト・イーサネットから1Gビット/秒のギガビット・イーサネット(以後GbEと表記)へとシフトしている。近い将来,10Gビット/秒の10GbEが普及するのも確実である。 従来は,ネットワークが高速化しても,サーバー機で帯域幅を最大限に利用しにくかった。TCP/IPの通信では,すべてのプロトコルがOS上のソフトウエアで実装される。CPUはデータ転送をはじめ,割り込み処理やパケットのチェックサム計算などネットワークの処理を担う必要がある。ネットワークが高速化すればするほど,サーバー機のCPU使用率はTCP/IPネットワーク処理に割かれてしまう。 現在では,この問題に対処するため,GbEのような高速ネットワークを使う場合,サーバーに搭載された複数のCPUのうち1つ分をTCP/IP処理用に用意するのが常とう手段の1つとされる。CPUの高速化により,この方法でもGbEの理論値に近い性能が得られる。 だが,ネットワーク・パフォーマンスの大幅な向上と引き換えに,本来はアプリケーションを処理するためのCPU能力を,TCP/IP処理で消費してしまっている状況は無視できない。近い将来,普及が見込まれている10GbEを考慮すれば,さらに大量のTCP/IPネットワーク処理が必要で,すべてをCPUに任せるのは現実的ではない。この問題を解消するのが,ネットワーク・タスクのオフロード,またはNICオフロードと呼ばれる機能だ。
Windows 2000から備わる Windowsでは,Windows 2000で採用されたネットワーク・ドライバのインターフェース仕様「NDIS 5」から,このオフロード機能の実装が始まった。 具体的には,
(1) TCP/IPチェックサムのオフロード ——の3つが利用可能である。 このうち,TCPセグメント化オフロードは,Windows 2000が出荷された当時開発者向けとして位置付けられ,デフォルトでは[disable]だった。 一方,ハードウエアであるNIC側では,Windows 2000の出荷以降,サーバー機用のNICからTCP/IPチェックサムのオフロード機能が実装され始めた。当初,サーバー機用の普及価格帯のNICでは,オフロード機能による性能向上は期待されたほどではなかった。また,当時TCP/IPネットワーク処理のCPU負荷を軽減したい場合は,TOE(TCP/IPオフロード・エンジン)対応といわれる,OSのTCP/IPプロトコル・スタックに独自に手を加えたドライバなどを使う高価な専用のNIC(10数万円程度)が必要だった。 最近,その状況が変わっている。Windows Server 2003が出荷されて以降,NIC上の専用プロセッサ,ミニポート・ドライバ,TCP/IPドライバ,NDISドライバ,それぞれの効率が徐々に改善された。 現在では約1万~2万円と普及価格帯のNICであっても,OS標準のオフロード機能によるCPU負荷軽減の効果が得られる。Windows Server 2003で実装されたNDIS 5.1からはTCPセグメント化オフロード機能がデフォルトで[enable](利用可能)になっている効果も大きい。
チェックサムとセグメント化の 前述した通り,Windows ServerではWindows 2000から,TCP/IPチェックサムのオフロード,TCPセグメント化オフロード,IPSecオフロードの実装が始まった。 このうち,IPSecのオフロードに関しては,NICによる実装があまり進んでいない。理由は,(1)IPSec自体がLAN上で標準的に広く利用される状況にない,(2)IPSec用のロジックを普及価格帯のNICに搭載できるほど安価に生産する技術が確立していない——ことだと推測される。この状況は今後,市場に合わせて変化していくだろう。 まず,具体的にどのような処理がオフロードの対象になっているのかを知るため,Windows Server 2003でオフロードの対象とされているTCP/IPチェックサム,TCPセグメント化の処理内容をそれぞれ解説しよう。
単純な演算ではあるが
送信側では,ヘッダー・チェックサム以外のフィールドを,メモリーからの単純な値のコピーもしくは数回の簡単な加減算によって埋める。しかし,ヘッダー・チェックサムは,ヘッダー全体を16ビット単位で「『1の補数の和』の1の補数」を計算して求められる。単純ではあるが演算回数は多い。
まず,送信側では,ヘッダー・チェックサムのフィールドを0x0として,IPヘッダーの16ビット単位の「1の補数の和」を求める。計算式は次の通りである。
次に「『1の補数の和』の1の補数」を計算する。「『1の補数の和として算出された0xDC61』の1の補数」は,けたあふれがないことから,単純に「0xDC61」のビット反転により求められ「0x239E」となる。この0x239Eがヘッダー・チェックサムの値である。
TCPヘッダーとUDPヘッダーの構成を,それぞれ図4,図5に示す。TCP/UDPのチェックサムは,TCP/UDPヘッダーおよびデータが壊れていないかどうかをチェックするための16ビットのフィールドである。TCP/UDPチェックサム以外のフィールドは,メモリーからの単純な値のコピーもしくは数回の単調な増減演算によって埋められる。 しかし,TCP/UDPチェックサムは,「疑似ヘッダー+ヘッダー+データ」を16ビット単位で「『1の補数の和』の1の補数」を計算することにより求められる。やはり単純な演算ではあるが,データ部が含まれることもあり,パケットの長さによっては演算数がとても多くなる。
まず,送信側では,チェックサム・フィールドを0x0として,16ビット単位で「1の補数の和」を求める。計算方法はIPヘッダーのときと同様に以下のようになる。
さらに,「『1の補数の和』の1の補数」を計算する。「『1の補数の和として算出された0x3581D』の1の補数」は,16ビット単位で見たときに,けたあふれがあるので,1の補数の性質通り,けたあふれ補正の処理が必要になる。具体的には,あふれた部分の0x3を残り部分の0x581Dの下位ビットに加える。計算すると,
となる。求めた0x5820のビットを反転させると0xA7DFになり,この値をチェックサム・フィールドに代入して,データを送信する。
受信側では,チェックサム・フィールドを含むUDPのすべてのフィールドで,16ビット単位の「1の補数の和」を計算し,結果が0xFFFFとなれば整合したと見なす。
|