[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: statistics of TX mbuf size and chains



<080811203137.M0100647@mirage.ceres.dti.ne.jp>の記事において
私は書きました。

> なんとなく sgimips の O2 の内蔵イーサネットのドライバの
> 送信部分をいろいろといじっているのですが、各ドライバの
> (*ifp->if_start)() に渡される送信パケットについて、
> 以下のような統計的データってどこかにないでしょうか?
> 
> ・送信パケットのサイズ
> ・ヘッダ部分のサイズ、フラグメント数、alignment状態
> ・データ部分のサイズ、フラグメント数、alignment状態

ほとんどがクライアント的動作(一部 NFS サーバー動作)ですが、
いろいろと動かしながら evcnt(9) の数字を vmstat(8)で見ると
以下のようになりました。

---

1. パケットサイズの分布

全 20,000,009 送信パケット中、

(a)   ~60bytes        986/20000009   0.005%
(b)  ~120bytes    1233978/20000009   6.17%
(c)  ~160bytes     537230/20000009   2.67%
(d)  ~256bytes   12580722/20000009  62.90%
(e)  ~512bytes    1032608/20000009   5.16%
(f) ~1024bytes     251417/20000009   1.26%
(g) >1024bytes    4363068/20000009  21.82%

という具合いでした。

(d)の 256バイト付近(ack?)と (g)の 1024バイト以上(data?)が多い
というのは前述の FreeBSD の論文と似たような感じです。

60バイト以下のパケット(ETHER_MIN_LEN の padding が必要なもの)は
ほとんどが name server 問い合わせの UDP パケットのようです。


2. データ部分のフラグメント

さらに、 mec(4) のドライバの送信部において、前回書いた

> (1) もともと 120バイトより小さいパケットはすべて (a)にコピーする
>     120バイトより大きいパケットについては、
> (2) 先頭から約90バイトまでに含まれるフラグメントは (a)にコピーする
> (3) 残り部分の先頭が 8byte 境界になければ端数を (a)にさらにコピーする
> (4) 残りの部分が (b)の 3つの領域に収まればそれをそのまま指定する
> (5) 収まっていなければあきらめて新しい mbuf を確保してコピー

の方法で送信バッファを割り当てた場合の

(a) (1)の 120bytes領域に収まるパケット (← 1の(a)(b)の合計)
(b) (4)の 連続領域 1つで収まるパケット
(c) (4)の 連続領域 2つで収まるパケット
(d) (4)の 連続領域 3つで収まるパケット
(e) (5)の 新規の mbuf が必要なパケット

のそれぞれのパケット数を見ると、

(a)  1234964/20000009   6.17%
(b) 16417689/20000009  82.09%
(c)  2247801/20000009  11.24%
(d)    54427/20000009   0.27%
(e)    45128/20000009   0.23%

90%以上が 1つ or 2つの 8バイト align の連続領域に収まり、
120バイト以下の極小パケットを除けばパケット全体の
コピーが必要になる状況はほとんどないという、
結構意外(?)な結果になりました。

# ただ、 (e)の新規 mbuf が必要になるようなパケットは
# 特定のアプリケーション操作をするとボロボロ出るようなので、
# 1% 以下の部分の比率はあまり当てにならないと思います。

(c)の連続領域 2つの場合のほとんどはページ境界をまたいでいる場合
と思われるので、実際のデータとしては単一連続領域のものがほとんど
のようです。


3. ヘッダ部分のフラグメント

前項の方法のうち (b),(c),(d) についてはパケット先頭部分の88バイト
に収まるヘッダ部分(実際にヘッダかどうかまでは見ていないので
正確には単に先頭部分)の fragment 部分および unaligned の部分を
別途コピーしているわけですが、その部分のフラグメント数を見ると、

(a)フラグメント無し  10130135/18719917  54.11%
(b)フラグメント1つ    8586208/18719917  45.87%
(c)フラグメント2つ       3574/18719917   0.02%

となり、ヘッダ部のフラグメントが3つ以上のものはなく、
半数以上がヘッダとデータとが連続している、
もしくはヘッダ長が88バイトを超えている
(== unaligned 部分のみがコピーされている)
という結果でした。


4. ヘッダ長

同様に先頭部分からコピーされたバイト数を見ると、

(a)  ~8bytes  10130135/18719917 54.11%
(b) ~16bytes     26186/18719917  0.14%
(c) ~32bytes         0/18719917  0.00%
(d) ~64bytes   2236999/18719917 11.95%
(e) ~80bytes   6324800/18719917 33.79%
(f) ~96bytes      1797/18719917  0.01%

となりました。

(a)は 3の(a)と全く同じなので、パケット先頭が unalinged で
それ以降が 88バイト以上連続していた場合の unaligned 部分のみが
コピーされた場合です。

(d)は UDP パケットでヘッダ部分が独立している場合、
(e)は TCP パケットでヘッダ部分が独立している場合のようです。
それ以外はいつ出てきたのかよくわかりません。

前項で少し書いていますが、実ヘッダ長が 88バイトを超える場合は
ヘッダもデータ扱いで、各ヘッダのフラグメントが 8byte 境界にあれば
2項の(b),(c),(d)で処理されてコピー無しで転送され、
8byte 境界にない、あるいは連続領域が 3つを超える場合は
2項の(e)で処理されている、ということになると思います。


なお、上記の計測環境において IPv6 は使用していません。
---

というわけで、最初に mec(4) のドライバを書いた時は
他の NIC と比べてずいぶん DMA まわりが貧弱だなあ、
などと思っていたのですが、今回のこの結果を見ると、実は
SGI はこの辺りも検討した上でコストパフォーマンス最適設計をした
ということなのかなぁ、などと思ったのでした。

# もっとも、今回修正したドライバでもベンチマークの数字以外に
# 体感できる差はあまりないのですが。


書いたソースはまた別途 port-sgimips にでも投げます。

# 実はドライバがバグってて変な数字でした、というオチがあるかも……
---
Izumi Tsutsui