一覧NW-01-2 · 通信の基本モデル

帯域幅・遅延・スループット

回線速度だけでは決まらない転送時間を、記録と計算で調べます。

説明

帯域は単位時間に送り出せる量、遅延は届くまでや応答までの時間です。有効なデータがどれだけ速く届いたかを調べるには、転送量と経過時間、待ち時間、ヘッダー等の追加分を合わせて考えます。

同じ1MiBを送った三つの記録から速度を計算します。送り出す時間と距離による時間を分け、RTTと未確認データ量の制約、最後にフレームの追加分を含む効率を確認します。

1同じ量を送った三つの記録

measurements.csvは、1MiBの有効データを送った比較用の記録です。転送量、経過秒、リンク速度、RTTを同じ表で読みます。

cat measurements.csv転送量と時間の対応

転送量はすべて1048576バイトです。リンク速度は100または1000Mbit/秒、RTTは4または80msです。ここでの経過時間は比較用に固定した値で、特定製品の性能値ではありません。

2有効データの転送速度

バイト数を8倍してビットへ換算し、経過時間で割ります。Mbitは100万ビットとして計算します。

awk -F, 'NR>1 {printf "%s goodput=%.2f Mbit/s link=%s Mbit/s\n",$1,$2*8/$3/1000000,$4}'有効データ量を時間で割る measurements.csv同量の三条件

nearとfast-farは約93.21Mbit/秒、farは約49.34Mbit/秒です。リンク速度が10倍でも、短い転送の有効速度が10倍になるとは限りません。経過時間には送信以外の待ちも含まれます。

3リンクへ送り出すだけの時間

ヘッダー等の追加分を除き、1MiBを回線へ送り出す時間を各速度で計算します。

awk -F, 'NR>1 {printf "%s serialization=%.3f ms\n",$1,1000*$2*8/($4*1000000)}'ビット数をリンク速度で割る measurements.csv転送量と速度

100Mbit/秒では約83.886ms、1000Mbit/秒では約8.389msです。これは直列化遅延であり、最後のビットが相手まで伝わる時間、処理、待ち行列、応答待ち等は含めていません。

4距離による伝搬時間

links.csvのモデルでは伝搬速度を両媒体とも2億m/秒としています。距離を伝搬速度で割り、片道時間を求めます。

awk -F, 'NR>1 {printf "%s %s propagation=%.3f us\n",$1,$2,1000000*$4/$5}'距離から片道時間 links.csv媒体と距離の条件

20mで0.1µs、2000mで10µsです。伝搬時間は送り出すデータ量に依存せず、直列化時間はデータ量と伝送速度で変わります。光ファイバーという媒体名だけで、経路全体のRTTが小さいとは決まりません。

5送信と応答待ちを一回ずつ行う場合

単純化のため、有効データ全体を送信した後に1RTT分待つモデルで、合計時間を比べます。

awk -F, 'NR>1 {send=1000*$2*8/($4*1000000); printf "%s send_plus_rtt=%.3f ms\n",$1,send+$5}'送信時間と一往復の和 measurements.csv同じ三条件

nearは87.886ms、farは163.886ms、fast-farは88.389msです。回線の高速化で短縮できるのは主に送信部分で、80msの待ちが残ります。この式は比較用の一往復モデルで、TCPの全転送時間を常にこの式で求められるわけではありません。

6ACKを待たずに送れる量の影響

RTT80msで未確認データを64KiBまでしか保持できない場合、ACKで窓が進む速度を上限として計算します。

python3 -c窓とRTTの関係を計算 'window=65536; rtt=0.080; print(window*8/rtt/1000000,"Mbit/s"); print(100000000*rtt/8,"bytes for 100 Mbit/s")'窓による上限と帯域遅延積

64KiBでは約6.55Mbit/秒が窓による上限です。100Mbit/秒×80msに相当する量は1000000バイトです。回線を使い切るには十分な飛行中データ量が必要ですが、受信窓のほか輻輳窓や損失等も制約になります。

7ヘッダーを含む回線上のデータ量

この例ではEthernetヘッダー14、IPv4ヘッダー20、TCPヘッダー20、有効データ1460、FCS4、プリアンブルとSFD8、フレーム間隔12バイト相当とし、効率を計算します。VLANやTCPオプションはありません。

python3 -c占有量と有効データの比率 'payload=1460; wire=14+20+20+payload+4+8+12; print(wire, round(100*payload/wire,2), round(100*payload/wire,2),"Mbit/s at 100 Mbit/s")'ヘッダー・FCS・間隔を含める

線上の占有は1538バイト相当で、有効データの割合は約94.93%です。100Mbit/秒で連続送信できても、この条件の有効データは約94.93Mbit/秒です。フレーム間隔は実際のペイロードバイトではなく時間の換算量です。ACKや再送等を含めれば条件はさらに変わります。

まとめ

バイトとビット、MbitとMiBの単位をそろえて、量と時間から有効速度を求めます。

直列化、伝搬、応答待ちなど、時間を構成する部分を分けます。

RTT・窓・ヘッダー等が影響するため、リンク速度だけでは転送完了時間を決められません。

操作履歴と解説を振り返れます。

シェル / PCAPと通信の記録

1
cat measurements.csv
CASE,PAYLOAD_BYTES,ELAPSED_SEC,LINK_MBIT_S,RTT_MS
near,1048576,0.090,100,4
far,1048576,0.170,100,80
fast-far,1048576,0.090,1000,80
2
awk -F, 'NR>1 {printf "%s goodput=%.2f Mbit/s link=%s Mbit/s\n",$1,$2*8/$3/1000000,$4}' measurements.csv
near goodput=93.21 Mbit/s link=100 Mbit/s
far goodput=49.34 Mbit/s link=100 Mbit/s
fast-far goodput=93.21 Mbit/s link=1000 Mbit/s
3
awk -F, 'NR>1 {printf "%s serialization=%.3f ms\n",$1,1000*$2*8/($4*1000000)}' measurements.csv
near serialization=83.886 ms
far serialization=83.886 ms
fast-far serialization=8.389 ms
4
awk -F, 'NR>1 {printf "%s %s propagation=%.3f us\n",$1,$2,1000000*$4/$5}' links.csv
LAN-A copper propagation=0.100 us
LAN-B fiber propagation=10.000 us
5
awk -F, 'NR>1 {send=1000*$2*8/($4*1000000); printf "%s send_plus_rtt=%.3f ms\n",$1,send+$5}' measurements.csv
near send_plus_rtt=87.886 ms
far send_plus_rtt=163.886 ms
fast-far send_plus_rtt=88.389 ms
6
python3 -c 'window=65536; rtt=0.080; print(window*8/rtt/1000000,"Mbit/s"); print(100000000*rtt/8,"bytes for 100 Mbit/s")'
6.5536 Mbit/s
1000000.0 bytes for 100 Mbit/s
7
python3 -c 'payload=1460; wire=14+20+20+payload+4+8+12; print(wire, round(100*payload/wire,2), round(100*payload/wire,2),"Mbit/s at 100 Mbit/s")'
1538 94.93 94.93 Mbit/s at 100 Mbit/s

演習完了