TCPのRTO計算で使われる各数値の数学的定義
TCPの再送タイムアウト(RTO)を算出するプロセスは、複数の指標を漸化式(ぜんかしき)を用いて逐次更新していくことで実現されます。以下に、各数値の厳密な定義と、その更新に使われる数式を示します。
ある時刻$n$における測定値を$SampleRTT_n$、その時点での推定値を$EstimatedRTT_n$、ばらつきを$DevRTT_n$と表記します。
SampleRTT (標本RTT)
- 定義: TCPセグメントを送信後、その確認応答(ACK)を受信するまでに要した実測時間。
-
数式: $SampleRTT_n$
- これは計算によって導出される値ではなく、ネットワークから直接観測されるn番目の入力値そのものです。
EstimatedRTT (RTT推定値) と係数 α
- 定義: 時刻$n$までの観測に基づいた、ラウンドトリップタイム(RTT)の指数平滑移動平均 (Exponentially Smoothed Moving Average)。
-
係数
α: 平滑化係数(smoothing factor)。最新の$SampleRTT_n$が$EstimatedRTT_n$の更新に与える影響の度合いを決定します。一般的に$0 < \alpha < 1$であり、今回は$\alpha = 0.125$です。 -
更新式:
$$EstimatedRTT_n = (1 - \alpha) \cdot EstimatedRTT_{n-1} + \alpha \cdot SampleRTT_n$$ - 式の意味: 新しい推定値($EstimatedRTT_n$)は、直前の推定値($EstimatedRTT_{n-1}$)を$(1-\alpha)$の比率で維持しつつ、最新の観測値($SampleRTT_n$)を$\alpha$の比率で取り込んで合成されます。これは、急激な変動を抑え、RTTの傾向を捉えるための数式です。
DevRTT (RTTばらつき推定値) と係数 β
- 定義: $SampleRTT$と$EstimatedRTT$の差分の絶対値について、指数平滑移動平均を計算した推定値。
-
係数
β: 平滑化係数。最新の差分が$DevRTT_n$の更新に与える影響の度合いを決定します。今回は$\beta = 0.25$です。 -
更新式:
$$DevRTT_n = (1 - \beta) \cdot DevRTT_{n-1} + \beta \cdot |SampleRTT_n - EstimatedRTT_{n-1}|$$ -
式の意味: 新しいばらつき($DevRTT_n$)は、直前のばらつき($DevRTT_{n-1}$)を$(1-\beta)$の比率で維持しつつ、最新の観測から生じたばらつき($|SampleRTT_n - EstimatedRTT_{n-1}|$)を$\beta$の比率で取り込みます。
EstimatedRTTの更新とは異なり、比較対象は更新前の$EstimatedRTT_{n-1}$である点に注意が必要です。
RTO (再送タイムアウト)
- 定義: TCPセグメントの再送を実行するまでの待機時間。
-
算出式:
$$RTO_n = EstimatedRTT_n + 4 \cdot DevRTT_n$$ -
式の意味: RTOは、RTTの推定値($EstimatedRTT_n$)を基準とし、そこに安全マージンとしてばらつきの推定値($DevRTT_n$)の4倍を加算して算出されます。
4という係数は、ネットワーク遅延の一時的な増加によって不必要な再送が起きることを防ぐための規約値です。
# --- 条件設定 ---
# 実際の計測データ (SampleRTT) のリスト
sample_rtts = [10, 12, 7, 8, 15, 20, 17, 24]
# EstimatedRTTを更新する際の重み係数
alpha = 0.125
# DevRTTを更新する際の重み係数
beta = 0.25
# --- 初期値の設定 (n=1) ---
# 最初の予測値(EstimatedRTT)は、最初の実測値を使うのが一般的
estimated_rtt = sample_rtts[0]
# 最初のばらつき(DevRTT)は、課題のルール通り実測値の半分
dev_rtt = sample_rtts[0] / 2
# --- n=2からn=8までをループで計算 ---
# 2番目以降の実測値を使って、予測値とばらつきを逐次更新していく
for i in range(1, len(sample_rtts)):
sample_rtt = sample_rtts[i]
# DevRTTの計算には「更新前」のEstimatedRTTが必要なため、先に差分を計算しておく
diff = sample_rtt - estimated_rtt
# DevRTTを更新
# 新しいDevRTT = (古いDevRTTに重みをかけたもの) + (実際のズレに重みをかけたもの)
dev_rtt = (1 - beta) * dev_rtt + beta * abs(diff)
# EstimatedRTTを更新
# 新しいEstimatedRTT = (古いEstimatedRTTに重みをかけたもの) + (今回の実測値に重みをかけたもの)
estimated_rtt = (1 - alpha) * estimated_rtt + alpha * sample_rtt
# --- 最終的なRTOの計算 (n=8) ---
# 全ての実測値を反映し終わった最終的なEstimatedRTTとDevRTTを使ってRTOを算出
rto = estimated_rtt + 4 * dev_rtt
# --- 結果の表示 ---
print(f"RTO(t8) = {rto:.2f} ms")