4. 拥塞控制机制:端到端与逐跳、信用与令牌

各位,咱们今天聊点实在的。网络拥塞控制,说白了就是防止数据把网络“撑死”。你想想看,如果所有设备都拼命往外扔数据包,交换机来不及处理,那结果就是丢包、重传、性能雪崩。我在做第一代智能网卡芯片时,就吃过这个亏——流量一上来,整个系统直接卡死。

拥塞控制的核心思路其实就两种:端到端(E2E)逐跳(Hop-by-Hop)。另外还有两种辅助机制:信用机制令牌机制。咱们一个一个拆开讲。

4.1 端到端拥塞控制(E2E)

端到端,顾名思义,就是发送端和接收端之间的事。中间的网络设备(比如交换机)不参与决策,只负责转发。发送端通过观察丢包率、延迟变化来判断网络是否拥塞,然后调整发送速率。

TCP 的拥塞控制就是典型的 E2E 方案。慢启动、拥塞避免、快速重传、快速恢复——这些算法大家应该都熟悉。但我要说的是,在芯片层面实现这些逻辑,和软件实现完全是两码事。

芯片实现要点:

  • 需要硬件维护每个流的拥塞窗口(cwnd)和慢启动阈值(ssthresh)
  • 丢包检测通常依赖 ACK 超时或重复 ACK,硬件需要精确计时器
  • 速率调整(加法增、乘法减)需要可配置的步长参数

我个人习惯在芯片里用滑动窗口 + 定时器阵列来实现。每个流分配一个定时器,超时未收到 ACK 就认为丢包。嗯,这里要注意:定时器的精度不能太高,否则硬件开销会爆炸。我曾经试过 1us 精度的定时器,结果芯片面积直接翻倍,得不偿失。

4.2 逐跳拥塞控制(Hop-by-Hop)

逐跳控制就不一样了。每个中间节点(交换机、路由器)都会参与拥塞判断。如果某个端口快撑不住了,它会直接给上游发信号:“兄弟,慢点!” 上游收到信号后立刻降速。

这种机制的好处是响应快。端到端要等一个 RTT 才能感知到拥塞,逐跳可以在一个跳步内完成反馈。对于数据中心这种低延迟场景,逐跳控制几乎是标配。

我记得在某个 400G 交换机项目中,我们用了逐跳的 PFC(优先级流控制)机制。每个端口维护一个信用计数器,当缓冲区水位超过阈值时,就发送暂停帧给上游。效果立竿见影,丢包率从 0.1% 降到了接近零。

避坑指南: 我曾经遇到过 PFC 死锁的问题。A 端口等 B 端口释放缓冲区,B 端口又在等 A 端口释放,两边互相等待,整个网络卡死。解决方案是引入超时机制——如果某个端口暂停超过一定时间,强制丢弃部分数据包打破死锁。

4.3 信用机制(Credit-based)

信用机制,说白了就是先买票后上车。发送端在发送数据之前,先向接收端申请信用。接收端根据自己可用的缓冲区大小,分配一定数量的信用给发送端。发送端只有拿到信用才能发数据,发完就扣减信用。

这种机制的好处是绝对不会丢包——因为接收端保证有足够的空间来接收。但代价是增加了延迟,因为每次发送前都要先做一次信用申请。

在芯片实现中,信用机制通常用于片上网络(NoC)高速 SerDes 通道。我做过一个 16x16 的 NoC 路由器,每个输入端口都配了一个信用计数器。初始信用值等于接收端缓冲区的深度,每发一个 flit(流量单元)就减 1,收到接收端的释放信号就加 1。

// 信用管理伪代码(硬件描述风格)
always @(posedge clk) begin
  if (credit_grant) begin
    credit_count <= credit_count + grant_amount;
  end
  if (flit_sent) begin
    credit_count <= credit_count - 1;
  end
  // 只有 credit_count > 0 时才能发送
  can_send <= (credit_count > 0);
end

小技巧: 信用值可以用格雷码编码,减少跨时钟域同步时的毛刺风险。我在一个 28nm 的项目里用过,效果不错。

4.4 令牌机制(Token-based)

令牌机制和信用机制有点像,但思路不同。信用机制是接收端驱动的,令牌机制是发送端驱动的。发送端维护一个令牌桶,令牌以固定速率生成。每发一个数据包,就消耗一个令牌。如果令牌桶空了,就不能再发数据了。

令牌机制的核心参数有两个:令牌生成速率(决定了平均发送速率)和桶深度(决定了突发能力)。你想想看,桶越深,能容忍的突发流量就越大。

在芯片里实现令牌桶,我建议用累加器 + 比较器的结构。累加器每隔固定时间加一个令牌值,比较器判断当前令牌数是否足够发送下一个包。注意,累加器的位宽要足够大,防止溢出。我曾经因为位宽不够,导致令牌数绕回,结果流量失控——嗯,那是一次惨痛的教训。

机制 控制主体 响应速度 丢包风险 典型应用
端到端(E2E) 发送端/接收端 慢(1 RTT) TCP/IP 网络
逐跳(Hop-by-Hop) 中间节点 快(1 跳步) 数据中心、InfiniBand
信用机制 接收端 中等 NoC、PCIe
令牌机制 发送端 中等 流量整形、QoS

4.5 四种机制的对比与选择

说实话,没有哪种机制是万能的。实际项目中往往是混合使用。比如,数据中心交换机里,端口级用逐跳 PFC,流级用端到端 ECN(显式拥塞通知),再配合令牌桶做流量整形。

我个人建议这样选型:

  • 如果对零丢包有硬性要求(比如存储网络),优先考虑信用机制
  • 如果对延迟极度敏感(比如 HPC),逐跳控制更合适
  • 如果兼容性是首要考虑(比如互联网),端到端是唯一选择
  • 如果要做流量整形带宽限制,令牌桶是标配

核心观点: 拥塞控制的本质是供需平衡。发送端是“供”,网络和接收端是“需”。信用机制和令牌机制都是在“供”和“需”之间加了一个缓冲层,让流量更平滑。而端到端和逐跳则是通过反馈信号来动态调整“供”的速率。

好了,这一章的内容就到这里。四种机制各有千秋,关键是要理解它们的适用场景和硬件代价。下一章咱们聊聊更具体的——如何在芯片里实现这些机制的硬件模块。


专注资料整理