CUBIC の三次関数ウィンドウ制御
長距離・高速回線でなぜ Reno より速く帯域を埋められるのか。CUBIC が三次関数で窓を伸ばす内部を、数式と曲線の形で腑に落とします。
- 1.CUBIC は cwnd を直前ロスからの経過時間 t の三次関数 W(t)=C·(t−K)^3+W_max で更新し、RTT 回数ではなく実時間を基準にする。
- 2.曲線は W_max 手前で凹(急→緩)、W_max で平坦、その先で凸(緩→急)。安定点を慎重に守りつつ未探索の帯域を素早く探る。
- 3.更新が実時間ベースゆえ RTT 非依存に近く、大 BDP 経路で窓を素早く満たす。短 RTT 経路では TCP フレンドリ域が Reno の下限を保証する。
CUBIC が解いた問題:実時間で窓を伸ばす
Reno 系の輻輳回避は「1 RTT ごとに cwnd を +1」でした。これは増加速度が RTT に縛られることを意味します。RTT が 200ms の長距離経路では、半減した窓を元に戻すだけで膨大な往復回数を要し、太い回線を使い切れません。背景の数理は AIMD と輻輳制御の数理 を、回線容量と窓の関係は 帯域・レイテンシ・スループット を参照してください。
CUBIC(RFC 9438、Linux 既定)の発想は、窓の増加を RTT 回数ではなく実時間 t(直前のロスからの経過秒数)の関数にする ことです。RTT が長かろうと短かろうと、同じ実時間が経てば同じだけ窓が伸びる。これが「RTT 非依存」と呼ばれる性質の核心です。系譜上の位置づけは TCP輻輳制御の系譜 を参照してください。
三次関数の式とパラメータ
CUBIC の窓更新は次の一本の式に集約されます。
W_cubic(t) = C · (t − K)^3 + W_max
W_max : 直前にロスした時点の cwnd(前回の上限)
t : ロス発生からの経過時間(秒)
C : 拡張性パラメータ(Linux 標準で 0.4)
K : W(t) が W_max へ到達するまでの目安時間
ロス直後、cwnd は W_max を β 倍に減らした値(CUBIC の乗法減少係数 β は標準で 0.7。Reno の 0.5 より減らし方が穏やか)から再出発します。K はその出発点から W_max まで戻るのに要する時間で、減少後の窓 W_max·β を用いて次のように決まります。
K = cbrt( W_max · (1 − β) / C ) # cbrt は立方根
この K の式が効きます。W_max(=回線が太いほど大きい)が K の中に入っているため、太い回線ほど K が大きく、ロス直後の凹型区間で一気に窓を伸ばす。一方で K の中に RTT は現れません。ゆえに増加プロファイルは RTT に直接は左右されないのです。
曲線の三段階:凹・平坦・凸
t を 0 から増やしたときの W_cubic(t) の形を、三次関数の幾何として読み解きます。(t−K)^3 は t = K を変曲点(かつ符号の境目)に持つため、区間ごとに性質が変わります。
| 区間 | t の範囲 | 曲線の形 | ねらい |
|---|---|---|---|
| 復帰フェーズ | 0 ≤ t < K | 凹(急増→鈍化) | W_max 手前まで素早く戻す |
| 安定フェーズ | t ≈ K | ほぼ平坦 | 前回の上限近傍を慎重に保つ |
| 探索フェーズ | t > K | 凸(鈍化→急増) | 未知の帯域を再び探る |
ロス直後(t が小さい)は (t−K)^3 が大きな負値で、そこに W_max が足されるので窓は W_max·β 付近から 急な傾きで立ち上がり、K に近づくにつれ傾きが緩みます(凹型)。t ≈ K で窓は W_max に達し、変曲点なので傾きがほぼ 0、すなわち 前回ロスした上限の近くで足踏み します。混雑がそこにある可能性が高い領域を慎重に探るわけです。t が K を超えると (t−K)^3 は正に転じて急増し、窓は W_max を上回って 凸型で加速 し、新しい上限を探索します。
直前のロス点 W_max は「最近まで安全だった上限」です。そこへは速く戻りたい(凹で急増)が、その近傍は混雑の境界なので慎重に進みたい(変曲点で平坦)。さらにその先は未知なので、安全が続くなら徐々に大胆に探りたい(凸で加速)。この「速く戻る・慎重に守る・大胆に探る」の三拍子を、変曲点を W_max に置いた一本の三次曲線が自然に表現します。
RTT 非依存と TCP フレンドリ領域
実時間ベースの増加は、長 RTT 経路を救う一方で 短 RTT 経路では Reno より遅くなりうる という裏返しを持ちます。RTT が極端に短ければ、Reno は 1 RTT ごとに何度も +1 できるため、同じ実時間あたりでは Reno の方が速く増える場面が生じるのです。
これを防ぐため CUBIC は、Reno が同条件で到達したであろう窓 W_est を並行して見積もり、W_cubic(t) と比較して 大きい方を採用 します。W_cubic(t) < W_est の領域を TCP フレンドリ領域(Reno 互換モード) と呼びます。
each ACK:
W_est = W_est + (3·(1−β)/(1+β)) / cwnd # Reno 相当の増加を推定
target = W_cubic(t + RTT) # 1 RTT 先を予測して目標を立てる
cwnd = max(target, W_est) # 下限を Reno が保証する
この比較により、大 BDP では三次関数が支配して窓を素早く満たし、短 RTT・低 BDP では Reno の増加速度を下回らない、という二面性が成立します。CUBIC は決して「常に Reno より積極的」なのではなく、Reno を下限として持つ設計です。
CUBIC は窓の増やし方を刷新しましたが、輻輳のシグナルは依然パケットロスです。大容量バッファを積んだ経路では、ロスが出るまで送り続けてキューを満たし、スループットは出るのに遅延だけが膨らむバッファブロートを起こします。これを避けるには遅延や帯域を実測するモデルベースの制御が要り、その代表が BBR の配送レートモデル です。
まとめ:一本の曲線に込めた設計思想
CUBIC の本質は、cwnd という 1 変数の増やし方を「RTT 回数」から「実時間の三次関数」へ置き換えた点にあります。変曲点を直前のロス上限 W_max に固定することで、復帰は速く・安定点は慎重に・探索は大胆に、という相反する要求を一本の曲線で両立させました。
W(t)=C·(t−K)^3+W_max の変曲点が W_max にあり、その手前が凹(速い復帰)・その先が凸(積極探索)になることを図で言えること。増加が実時間ベースゆえ RTT 非依存に近いこと、そして TCP フレンドリ領域で Reno を下限に保証することの両方を押さえると、CUBIC が「なぜ大 BDP に強く、かつ低 BDP で暴れないか」を一貫して説明できます。
ネットワーク Article
CUBIC の三次関数ウィンドウ制御を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
TCP
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 5
導入後に効く点
曲線は W_max 手前で凹(急→緩)、W_max で平坦、その先で凸(緩→急)。安定点を慎重に守りつつ未探索の帯域を素早く探る。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 5
判断チェックリスト
- 自社の用途が「TCP / 輻輳制御」に近いか確認する。
- 強みである「CUBIC は cwnd を直前ロスからの経過時間 t の三次関数 W(t)=C·(t−K)^3+W_max で更新し、RTT 回数ではなく実時間を基準にする。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。