当前位置: 首页 > news >正文

RFC6937 PRR 的兑换细节

分析 RFC6937 和 tcp_cwnd_reduction 函数,再看我的 数据包守恒和拥塞控制,做对一道中学几何题就理解 PRR 算法了。

按照兑换比分析,用几何描述下面的算法:

 DeliveredData = change_in(snd.una) + change_in(SACKd)  
 prr_delivered += DeliveredData  
 pipe = (RFC 6675 pipe algorithm)  
 if (pipe > ssthresh) {  
     // Proportional Rate Reduction  
     sndcnt = CEIL(prr_delivered * ssthresh / RecoverFS) - prr_out  // 公式 1
 } else {  
     // Two versions of the Reduction Bound  
     if (conservative) { 
         // PRR-CRB  
         limit = prr_delivered - prr_out  
     } else { 
         // PRR-SSRB  
         limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS  
     }  
     // Attempt to catch up, as permitted by limit  
     sndcnt = MIN(ssthresh - pipe, limit)  
 }

公式 1 变换为:

sndcnt + prr_out = CEIL(prr_delivered * ssthresh / RecoverFS)

意味着兑换比就是 β = ssthresh / RecoverFS,收到 1 个单位数据,发送 β 单位数据。trace 几何图示如下:
在这里插入图片描述

最终直到 cwnd = β·cwnd_prior 停止。但魔鬼在细节,最重要的并不是这个兑换比,而是 inflight 的变化:

static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
{
    return tp->sacked_out + tp->lost_out;
}
/* This determines how many packets are "in the network" to the best
 * of our knowledge.  In many cases it is conservative, but where
 * detailed information is available from the receiver (via SACK
 * blocks etc.) we can make more aggressive calculations.
 *
 * Use this for decisions involving congestion control, use just
 * tp->packets_out to determine if the send queue is empty or not.
 *
 * Read this equation as:
 *
 *      "Packets sent once on transmission queue" MINUS
 *      "Packets left network, but not honestly ACKed yet" PLUS
 *      "Packets fast retransmitted"
 */
static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
{
    return tp->packets_out - tcp_left_out(tp) + tp->retrans_out;
}

inflight 本就抛除了 lost_out,如果 lost_out 太多,比如无线场景,或 DCN 大象流遭遇 incast 场景, tcp_packets_in_flight 会一下子降到 ssthresh 以下。显然在这个时候,硬要把 cwnd 提到 ssthresh 会继续丢包。这种场景下,算法重要的是后半部:

else {  
     // Two versions of the Reduction Bound  
     if (conservative) { 
         // PRR-CRB  
         limit = prr_delivered - prr_out  
     } else { 
         // PRR-SSRB  
         limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS  
     }  
     // Attempt to catch up, as permitted by limit  
     sndcnt = MIN(ssthresh - pipe, limit)  
 }

这里可以看到一个强版本的数据包守恒,这是一个一比一的兑换,DeliveredData 作为可以新发送的数据量,它表示如此多的数据量在本轮被确认而离开网络了。

这就是我在昨天提到的那个问题 PRR 的 Linux 实现问题。RFC6937 并没有规定 PRR 结束之后如何做,Linux 直接将 cwnd = ssthresh 显然是不合适的。

如果管道收缩 1000 倍,cwnd 本是 5000,正常应该收缩到 cwnd = 5,然而按照 AIMD 标准算法,经历一次丢包后,cwnd 收缩到 β·cwnd,以 Reno 为例,即 cwnd = 2500,这显然还会继续丢包,幸运的是,PRR 可以一次性将 cwnd 收缩到 5,遗憾的是,Linux 将 cwnd = 5 又拉回了 cwnd = 2500。

AIMD 应对丢包无条件执行相同逻辑,它无法区分拥塞丢包还是链路随机丢包,对于拥塞丢包,固定比例降窗无疑是合适的,但对于链路随机丢包,特别是丢包率波动变化很大的情况,固定比例降窗显然不合适,drain to target 才合适,而 PRR 可以做到,with PRR,sending rate is bounded to be near delivery rate。

浙江温州皮鞋湿,下雨进水不会胖。


文章转载自:
http://cephaloid.elldm.cn
http://carambola.elldm.cn
http://carniferous.elldm.cn
http://arkansan.elldm.cn
http://caducous.elldm.cn
http://agnomen.elldm.cn
http://atmospherically.elldm.cn
http://alkanet.elldm.cn
http://aryl.elldm.cn
http://applicant.elldm.cn
http://allnighter.elldm.cn
http://anaclinal.elldm.cn
http://borneol.elldm.cn
http://bisayan.elldm.cn
http://celestialize.elldm.cn
http://abstractively.elldm.cn
http://apoprotein.elldm.cn
http://centinewton.elldm.cn
http://aapss.elldm.cn
http://catlap.elldm.cn
http://belgique.elldm.cn
http://acrimoniously.elldm.cn
http://basaltic.elldm.cn
http://averseness.elldm.cn
http://aurorean.elldm.cn
http://antehuman.elldm.cn
http://absurdist.elldm.cn
http://catharine.elldm.cn
http://cacique.elldm.cn
http://braaivleis.elldm.cn
http://www.dtcms.com/a/111395.html

相关文章:

  • [2017][note]基于空间交叉相位调制的两个连续波在few layer铋Bi中的全光switch——
  • AWS数据分析全栈实战(Redshift+SageMaker)
  • MYOJ_4576:(洛谷P1032)[NOIP 2002 提高组]字串变换(BFS提高)
  • 低成本训练垂直领域文娱大模型的技术路径
  • SCADE 6: 面向高安全软件开发的基于模型的解决方案
  • 【每日一个知识点】隐私计算:概念、技术、应用及发展趋势
  • GORM 中 CURD 操作用法详解
  • 7.训练篇5-毕设
  • 数字内容体验的未来方向是什么?
  • 图形渲染中的定点数和浮点数
  • 智慧放羊如何实现?
  • Python设计模式:克隆模式
  • 音视频入门基础:RTP专题(21)——使用Wireshark分析海康网络摄像机RTSP的RTP流
  • LeetCode 1123.最深叶节点的最近公共祖先 题解
  • Runnable组件动态添加默认调用参数
  • 基于SpringBoot框架发生验证码
  • 【Docker项目实战】使用Docker部署MediaCMS内容管理系统
  • 脑影像分析软件推荐 | BCT(Brain Connectivity Toolbox)
  • c语言修炼秘籍 - - 禁(进)忌(阶)秘(技)术(巧)【第四式】自定义类型详解(结构体、枚举、联合)
  • Windows 11 听的见人声,但是听不见背景音乐或者听不见轻音乐等,可以这样设置
  • 【橘子大模型】Runnable和Chain以及串行和并行
  • STM32 HAL库 CANFD配置工具
  • 小程序API —— 58 自定义组件 - 创建 - 注册 - 使用组件
  • CExercise_04_1运算符_6 (扩展) 找出数组中只出现一次的唯二元素
  • 社会视频汇聚:构筑城市安全防线的智慧之眼
  • VirtualBox 配置双网卡(NAT + 桥接)详细步骤
  • 《微服务概念进阶》精简版
  • 新浪财经股票每天10点自动爬取
  • 免费送源码:Java+SSM+Android Studio 基于Android Studio游戏搜索app的设计与实现 计算机毕业设计原创定制
  • Springboot + Vue + WebSocket + Notification实现消息推送功能