首页 › programming › 加一砍半:AIMD凭什么让TCP均分带宽

加一砍半:AIMD凭什么让TCP均分带宽

你有没有想过一个有点诡异的问题:全球几十亿台设备、无数条数据流,同时在同一条光纤、同一个路由器里挤来挤去,可为什么没有一条流能把整条管道独占?又为什么不会所有人一起挤爆、然后集体瘫痪?答案藏在一个看起来极其朴素、甚至有点"笨"的策略里——每往返时间多发一个包,一旦丢包就砍掉一半。这就是 Computerphile 这期 TCP b: Additive Increase Multiplicative Decrease & 'Slow Start' 要拆的核心。

这期视频值得看,是因为它把计算机网络里最容易被一笔带过、却真正撑起整个互联网的一层逻辑,讲得清清楚楚:拥塞控制不是某个聪明的中央调度器在分配带宽,而是一个没有指挥、纯靠每台机器各自退让就涌现出"公平"的分布式奇迹。看完你会理解,为什么 1986 年的互联网差点自我噎死、Van Jacobson 怎么靠一篇论文把它救活,以及为什么"慢启动"这个名字是计算机史上最大的谎言之一。下面我把视频的核心论点拆开,再补上它没展开、但你必须知道的底层脉络。

视频背景卡片

项目 内容
视频标题 TCP b: Additive Increase Multiplicative Decrease & 'Slow Start'
频道 Computerphile
发布日期 2026-06-15
时长 约 12–15 分钟(深度技术讲解)
频道订阅 230万+
配套视频 TCP a: Ensuring Your Data Gets There & in the Right Order(2026-06-13)
核心主题 TCP 拥塞控制:慢启动 + 加性增长 + 乘性下降(AIMD)

核心内容拆解

一、TCP 先解决了"到不到",才暴露出"发多快"

要看懂这期视频,得先补一个它默认你已经懂的前提。Computerphile 把 TCP 拆成了两集:a 集讲可靠性,b 集讲拥塞控制。在 a 集里,TCP 用序列号、确认号(ACK)、重传来保证数据按序、完整地到达——丢了我重传,乱序我重排。这套机制漂亮地回答了"数据能不能到"的问题。

但 b 集要讲的是另一层问题,它只有在可靠性问题被解决之后才会冒出来:既然重传能兜底,那我能不能使劲发? 答案是不能。因为互联网里的路由器是"哑的"——它没有信号告诉你"我快满了",它的处理方式只有一种:队列塞满了,就把新来的包直接扔掉。于是问题被颠倒了:网络永远不会主动告诉你它满了,你只能从"我的包被丢了"这件事反推它满了。 这就像你在一条漆黑的隧道里开车,唯一能判断前方堵没堵的方法,就是撞上前面那辆车。TCP 拥塞控制,本质上就是一套"撞了怎么办"的策略。

历史上这事真出过大事。1986 年 10 月,互联网经历了一次著名的 congestion collapse(拥塞崩溃):吞吐量从正常的 32 kbit/s 跌到 40 bit/s,降到了千分之一。原因就是早期 TCP 没有拥塞控制,大家都在重传、重传再重传,宝贵的带宽全被无意义的重复包吃光。Van Jacobson 1988 年那篇论文《Congestion Avoidance and Control》提出的算法,就是今天视频的主角,它从根上把互联网从这种"自我噎死"里救了出来。

二、慢启动:计算机史上名字最大的谎言

视频标题里的 'Slow Start',是整套机制里最反直觉、也最容易把人带偏的一个名字。慢启动一点都不慢——它反而是整个 TCP 里增速最快的阶段,是指数增长。

它的机制是这样的:发送端维护一个叫 拥塞窗口(congestion window, cwnd) 的变量,表示"我现在敢往网络里同时塞多少个未经确认的包"。连接刚建立时,cwnd 从很小(通常是 1 到 10 个 MSS,即最大报文段)开始。慢启动阶段,每收到一个 ACK,cwnd 就加 1——但注意,一个 RTT(往返时间)内你会收到一整个窗口数量的 ACK,所以效果是 每个 RTT cwnd 翻一倍:1、2、4、8、16……纯指数爆炸。

那为什么叫"慢"?视频会告诉你:这个"慢"是相对发送端一上来就用最大窗口把管道灌满而言的。在 Jacobson 之前,TCP 的默认行为是连接建立就倾泻而出,瞬间把沿途路由器的队列冲爆。慢启动的作用恰恰相反——它让发送端试探着进入网络,先小口喝,确认没事再大口灌。名字是站在"防止启动冲击"的角度起的,可一旦它跑起来,它是全场最激进的加速器。

这里有个关键的开关叫 ssthresh(slow-start threshold,慢启动阈值)。当 cwnd 涨到 ssthresh 之上,慢启动就戛然而止,切换到下一个、温柔得多的阶段。这个阈值本身就是一次"丢包"留下的记忆——每次丢包后,ssthresh 就被设成当前 cwnd 的一半,意思是"上次我在这个速度撞墙了,下次别这么猛"。

三、拥塞避免:线性爬坡,一格一格试探边界

一旦越过 ssthresh,TCP 就从指数增长切换到线性增长,这个阶段叫 congestion avoidance(拥塞避免)。机制简单到朴素:不再是"每个 RTT 翻倍",而是"每个 RTT 只加 1"。

这个加性增长(Additive Increase)的物理含义非常深刻。它在做一件事:一边走一边用脚探路,每一步都小心翼翼地多踩出去一点点,看看地面会不会塌。 网络的可用容量对发送端是完全未知的黑箱,TCP 唯一的探测手段就是"再多发一点,看会不会丢"。所以拥塞避免的本质,是一个主动的、持续的边界探测过程——它注定要一直加、一直加,加到撞墙为止。撞墙不是 bug,是 feature:你不撞,就永远不知道墙在哪。

这就引出了一个很多人没意识到的真相:TCP 在稳态下是"故意周期性丢包"的。 它把 cwnd 线性推上去,直到某次丢包,然后下降,再线性推上去……形成一条经典的"锯齿"(sawtooth)曲线。这条锯齿不是缺陷,而是一个自激振荡的反馈系统:它在故意地、周期性地越过网络容量边界,用丢包作为信号来定位那个边界。换句话说,丢包对于 TCP 不是事故,是它赖以工作的传感器。

四、乘性下降:丢包即信号,一刀砍半

当丢包真的发生(不管是超时 timeout,还是收到 3 个重复 ACK 触发的快重传),TCP 进入 Multiplicative Decrease(乘性下降):cwnd 不是减 1、减一个固定值,而是直接砍掉一半(×0.5,CUBIC 等变种参数不同,但思路一致)。同时 ssthresh 被设成这个砍半后的值,意味着"重新进入慢启动时,到这个点就要切换到线性"。

为什么要砍得这么狠?这是视频里最值得琢磨的设计决策。第一,激烈反应才能让出带宽。网络已经拥塞到开始丢包了,如果你只减一点点,队列还是满的,你会继续丢、继续重传,陷入 1986 年那种崩溃。砍一半是一种"立刻让管道喘口气"的休克疗法。第二,砍一半不会归零,避免吞吐量雪崩式下跌,保留了一定的发送能力。第三(这点尤其重要),这种"乘性下降"和前面的"加性增长"组合在一起,会产生一个意想不到的数学结果——下一节就是这个视频真正的灵魂。

五、AIMD 的数学之美:公平性是"涌现"出来的

这是整期视频、也是整个 TCP 拥塞控制思想里最漂亮的一笔,我重点展开。单看一条 AIMD 流,你会觉得它很笨:傻乎乎地线性加、撞墙砍半、再线性加。但当你把多条 AIMD 流放进同一条瓶颈链路时,奇迹发生了——它们会自动、必然地收敛到几乎均分带宽的状态。

Chiu 和 Jain 在 1989 年那篇经典论文《Analysis of the Increase and Decrease Algorithms for Congestion Avoidance in Computer Networks》里给出了证明,直观上可以这样理解:想象两条流在二维平面上,横轴是流1的 cwnd,纵轴是流2的 cwnd。加性增长意味着两个轴同时+1,向量指向 (1,1) 方向——也就是朝着 45 度对角线(公平线,cwnd1=cwnd2)平移。乘性下降意味着两个轴同时×0.5,向量指向原点方向——也就是沿着过原点的射线收缩,但收缩不改变两条流的比例。一来一回,所有流都会被"挤"向那条对角线,也就是均分。

换句话说:这里没有一个中央调度器在分发带宽。每台机器只关心自己,只对丢包做反应,却因为"加增乘减"这种特定的不对称,集体演化出了公平。 这是真正的涌现(emergence)——个体的简单规则,产生出全局的最优分配。这也解释了为什么必须是"加性增、乘性减"这种不对称组合:如果改成"加性增加性减",会震荡不收敛;如果改成"乘性增乘性减",能收敛但不公平。只有加增乘减,既能收敛、又能公平,这是数学上的最优解,不是拍脑袋。 视频把这一点讲透了,也是它最该被记住的内核。

六、从 Tahoe 到 BBR:经典模型的现代遗产

视频讲的是教科书级的 AIMD(对应 TCP Tahoe/Reno),但作为延伸,你必须知道这套机制后来怎么演化的,否则会误以为互联网今天还在用 1988 年的算法。

Tahoe(1988) 只有慢启动和拥塞避免,丢包一律进慢启动。Reno(1990) 加了快重传、快恢复:不靠超时这种"等死"信号,而是靠"收到 3 个重复 ACK"提前判断丢包,cwnd 砍半后不退回慢启动,直接进线性增长,大大提高了效率。之后还有 NewReno、SACK 等改进。今天 Linux 默认的拥塞控制算法是 CUBIC,它把 AIMD 那条线性增长曲线换成了一条三次函数曲线——窗口小时涨得快、接近历史最大值时涨得慢、超过后又再加快,专门为了在高带宽延迟积(BDP)的长肥管道上更高效地利用带宽。

但所有这些(Reno/CUBIC)都共享一个根本假设:丢包=拥塞。2016 年 Google 提出的 BBR 彻底颠覆了这个假设。BBR 不再等丢包,而是主动测量瓶颈带宽(BtlBw)和最小往返时延(RTprop),把 cwnd 设到这俩的乘积(即 BDP)附近。这解决了 AIMD 体系下一个老大难问题——bufferbloat(缓冲膨胀):路由器厂商为了少丢包,把队列缓存做得越来越大,结果 AIMD 一直要"丢包才减速",于是在丢包之前,数据已经在巨大队列里排了几百毫秒,延迟飙升。BBR 因为不再依赖丢包,绕开了这个陷阱。理解了 Computerphile 这期的经典 AIMD,你才能看懂 BBR 到底"颠覆"了什么——它颠覆的,正是"丢包即信号"这个第四节的根基。

七、TCP 的政治哲学:克制换共生

最后我想说一个视频没点明、但贯穿始终的深层洞察。TCP 能撑起整个互联网,不是因为它贪婪,而是因为它克制。 AIMD 那个"丢包就砍半",本质上是一种被编码进协议的礼让(encoded courtesy):当系统告诉我"挤了",我立刻主动让出一半。正是因为所有人都遵守这套礼让,整个系统才稳定、公平、不崩溃。

这就引出了一个对照:那些不遵守 AIMD、不退让的流量——比如某些 UDP 应用、视频会议里的暴力发包、以及最极端的 DDoS 攻击——它们之所以能"抢占"带宽、拖垮服务,恰恰是因为它们背叛了这套集体契约。AIMD 的稳定性是一种社会契约,违约者得利,但如果所有人都违约,系统立刻崩溃。 这也是为什么即便是全新的 QUIC(HTTP/3 的传输层),它彻底重写了 TCP 的可靠性机制、搬到用户态 UDP 之上,却仍然必须内置一套等价的拥塞控制——因为不管传输层怎么换,"无中心、靠退让换公平"这个互联网底层的政治哲学,换不掉。

知识结构图

flowchart TD
    A[TCP连接建立<br/>cwnd=初始小值] --> B{cwnd < ssthresh?}
    B -->|是| C[慢启动 Slow Start<br/>每RTT cwnd×2 指数增长]
    B -->|否| D[拥塞避免 Congestion Avoidance<br/>每RTT cwnd+1 线性增长]
    C -->|cwnd达到ssthresh| D
    D --> E{发生丢包?}
    E -->|否,持续试探边界| D
    E -->|超时timeout| F[慢启动门限下降<br/>ssthresh=cwnd/2<br/>cwnd回到初始值]
    E -->|3个重复ACK快重传| G[乘性下降 Multiplicative Decrease<br/>cwnd砍半×0.5<br/>进入快恢复]
    F --> C
    G --> D

    H[AIMD的数学之美]:::highlight --> I[加性增长: 沿45度方向平移<br/>收敛到公平线]
    H --> J[乘性下降: 沿原点方向收缩<br/>保持比例不变]
    I --> K[多流无中心协调<br/>涌现出公平均分带宽]
    J --> K

    L[现代演进] --> M[CUBIC: 三次曲线替代线性<br/>适配高BDP长肥管道]
    L --> N[BBR: 主动测量带宽与RTT<br/>不再依赖丢包, 解决bufferbloat]

    style C fill:#fff3cd,stroke:#856404
    style D fill:#d1ecf1,stroke:#0c5460
    style G fill:#f8d7da,stroke:#721c24
    style H fill:#d4edda,stroke:#155724
    style K fill:#d4edda,stroke:#155724
    classDef highlight fill:#d4edda,stroke:#155724,stroke-width:2px

实战启示

如果你是后端工程师或做网络相关开发,这期视频的内核能直接落到你的日常工作里。第一,理解"吞吐量腰斩"的真相。 当你看到某个 TCP 服务的 QPS 或带宽突然掉一半,第一反应不该是查应用逻辑,而该想是不是网络链路出现了丢包——AIMD 的乘性下降会瞬间把窗口砍半,这完全符合"腰斩"现象。第二,机房内通信偏慢,可能是 initcwnd 和 BDP 的锅。 同机房 RTT 极小,如果初始拥塞窗口太小,慢启动阶段还没爬起来,短连接就结束了,吞吐上不去。Linux 里可以用 ip route change ... initcwnd N 来调大初始窗口。

第三,Bufferbloat 是你该知道的反面教材。 如果你的路由器/网卡队列缓存太大,AIMD 会一直加速直到塞满队列再丢包,结果是延迟从几毫秒飙到几百毫秒——这正是为什么很多家庭网络"带宽测得挺高、但打游戏/视频会议却卡"。对策是启用 fq_codel / CAKE 这类带主动队列管理(AQM)的调度器,或直接上 BBR。第四,QUIC/HTTP3 的拥塞控制设计。 当你评估或排查 HTTP3 时要清楚:它的可靠性机制虽然全新,但拥塞控制层几乎照搬了 TCP 的 CUBIC/BBR,所以"丢包砍半""慢启动"的脾气完全继承了下来。

第五,系统设计面试角度。 "如何设计一个限流/负载均衡/内容分发系统"这类题,本质都在考你对 AIMD 反馈控制思想的理解——用反馈而非中央命令来达成全局最优,是分布式系统设计的一个万能心法。

延伸学习路径

  1. Computerphile 的 TCP a 集(https://www.youtube.com/watch?v=IADOV8UZO34)—— 这期的前传,讲可靠性与有序交付,两集连看才完整。
  2. Van Jacobson, "Congestion Avoidance and Control", SIGCOMM 1988—— 这一切的源头论文,互联网的"大宪章",值得读原文体会那个锯齿曲线是怎么推出来的。
  3. Chiu & Jain, "Analysis of the Increase and Decrease Algorithms...", 1989—— 公平性收敛证明的出处,那张二维平面图就来自这里。
  4. Google BBR 论文(Cardwell et al., 2017, "BBR: Congestion-Based Congestion Control")—— 看完经典 AIMD 再读这篇,能深刻体会到"丢包即信号"范式被颠覆的分量。
  5. RFC 5681(TCP Congestion Control) 与 bufferbloat.net 的科普材料—— 把理论落到协议规范和真实网络运维里。

一句话总结

TCP 公平地撑起整个互联网,靠的不是某个聪明的中央调度器,而是"加一砍半"这种笨拙到极致的退让——它让每台机器各自为政,却用数学必然地涌现出集体公平。

参考来源

  1. TCP b: Additive Increase Multiplicative Decrease & 'Slow Start' - Computerphile — 本次分析的核心视频(2026-06-15)
  2. TCP a: Ensuring Your Data Gets There & in the Right Order! - Computerphile — 配套前传,TCP 可靠性基础
  3. Van Jacobson, "Congestion Avoidance and Control", SIGCOMM 1988 — AIMD/慢启动算法的源头论文
  4. Chiu & Jain, "Analysis of the Increase and Decrease Algorithms", 1989 — AIMD 公平性收敛的数学证明
  5. BBR: Congestion-Based Congestion Control (Google, 2017) — 颠覆"丢包即信号"范式的现代拥塞控制算法

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入