优秀的 tcp vegas 拥塞控制大揭秘

看到题目就觉得我在扯,因为 delay-based 算法总被抢,没一个表现好的…可你们知道原因吗?因为 loss-based 算法不是分布式的啊,它们是被集中管理的,以 aimd 为例,其效率决定于 buffer 而不决定于自己(参见 bw = alpha/RTT * sqrt(1/f(buffer_size)))。

你要总觉得 vegas 抢不过 cubic,cubic 抢不过 bbr,就别看本文了,都是你对。

今天周五,我坐的长途公交车上都是在宝山,杨浦上学回家过周末的中学生和大学生,一个个戴着耳机刷视频或聊天。。。只有我在算什么一元二次方程,用手机画图[撇嘴]不过 geogebra 是真的好用,免费的,个人感觉比几何画板好,推荐一把。

aimd 公平收敛在于它本质上是集中式控制的(虽然看起来好像是分布式的)。收敛动作统一由 buffer (丢包)触发,端侧被动响应的过程中完成公平收敛。要点是,aimd 竟然是集中控制的。

而 vegas 是一种完全的,真正的分布式拥塞控制,它可能是少有的 “正确” 行为方式,且非常简单。
vegas 跟踪时延变化,将其控制在一定的比例范围而不是绝对时间内,从而获得了公平伸缩性。简单看一下 why。

按照 vegas 的公式,cwnd 在满足以下条件时保持稳定,出其右 cwnd —,缺其左 cwnd ++,式子 1:

α < = W ∗ r r t − r t t p r o p r t t p r o p = W ∗ r t t q u e u i n g r t t p r o p < = β \alpha <= W*\dfrac{rrt-rtt_{prop}}{rtt_{prop}}=W*\dfrac{rtt_{queuing}}{rtt_{prop}}<=\beta α<=Wrttproprrtrttprop=Wrttproprttqueuing<=β

假设 2 条流共享 bltbw,式子 2:

b w 1 + b w 2 = W 1 r t t q u e u i n g + r t t p r o p + W 2 r t t q u e u i n g + r t t p r o p = W 1 + W 2 r t t q u e u i n g + r t t p r o p = 1 bw_{1}+bw_{2} = \dfrac{W_1}{rtt_{queuing}+rtt_{prop}}+\dfrac{W_2} {rtt_{queuing}+rtt_{prop}}=\dfrac{W_1+W_2}{rtt_{queuing}+rtt_{prop}}=1 bw1+bw2=rttqueuing+rttpropW1+rttqueuing+rttpropW2=rttqueuing+rttpropW1+W2=1

从式子 2 解出 rtt_{queuing} 代入式子 1(取阿尔法为 2,贝塔为 4):

α < W 1 ∗ W 1 + W 2 − r t t p r o p r t t p r o p < = β \alpha<W_1*\dfrac{W_1+W_2-rtt_{prop}}{rtt_{prop}}<=\beta α<W1rttpropW1+W2rttprop<=β

同理,对于 W2,有:

α < W 2 ∗ W 2 + W 1 − r t t p r o p r t t p r o p < = β \alpha<W_2*\dfrac{W_2+W_1-rtt_{prop}}{rtt_{prop}}<=\beta α<W2rttpropW2+W1rttprop<=β

来吧,画图,W1 为红色,W2 位紫色,W1 = x,W2= y:
在这里插入图片描述

菱形区域就是收敛结果,简直太公平。使用 geogebra,滑动 a,b,r 滑块,你将清晰看到这些值的变化如何影响收敛区域。更一般的,如果 proprt 不一致是否还能公平,数学说了算。设 D 为共享排队时延,r1,r2 分别为两条流的 propagation 时延(proprt),看算式:

b w 1 + b w 2 = W 1 D + r 1 + W 2 D + r 2 = . . . ( D + r 1 ) ( D + r 2 ) = 1 bw_1+bw_2=\dfrac{W_1}{D+r_1}+\dfrac{W_2}{D+r_2}=\dfrac{...}{(D+r_1)(D+r_2)}=1 bw1+bw2=D+r1W1+D+r2W2=(D+r1)(D+r2)...=1

可解关于 D 的一元二次方程。

今天周五,回嘉定过周末的,在杨浦,宝山上学的中学生,大学生跟我一起挤上了去嘉定的长途公交车,学生们都在刷视频聊天,而我在折腾一元二次方程(有笔没纸,恰好包里有本书,随便画了)…
在这里插入图片描述
终于回到家,画出收敛菱形区域如下:
在这里插入图片描述
在这里插入图片描述

可见 rtt 越大,分配的 cwnd 越大,这就是 rtt 公平伸缩性!以至于我将 vegas 视为标杆。

我们的日常生活基本就是按照这个方案进行的,一切按照耐受性规定一个 “度”,大家收敛到这个度,就保证了全局公平。别的不必挂齿,我说过拥塞控制做不到微观控制,它只能确定趋势。

vegas 是分布式公平的(但基本被遗忘),bbr 呢?

很多人说 bbr 是 delay-based 算法,其实不然。在我看来 bbr 只是一个拍脑袋的实验室验证(连 poc 都算不上),作者本人可能也慌。

在 buffer 中才能有完成收敛,无 buffer 不行,buffer 太大不行,不用 ns-3 仿真,数学上就能看出来。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我不是一个可以运行代码的程序,无法为您提供完整的源代码和报告。但我可以简要介绍如何在NS3中编写纺锤型网络,并使用不同的拥塞控制算法进行性能测试。 1. 编写纺锤型网络 在NS3中,我们可以使用TopologyHelper类来构建网络拓扑。对于八个节点的纺锤型网络,可以按照以下方式实现: ``` Ptr<Node> n0 = CreateObject<Node>(); Ptr<Node> n1 = CreateObject<Node>(); Ptr<Node> n2 = CreateObject<Node>(); Ptr<Node> n3 = CreateObject<Node>(); Ptr<Node> n4 = CreateObject<Node>(); Ptr<Node> n5 = CreateObject<Node>(); Ptr<Node> n6 = CreateObject<Node>(); Ptr<Node> n7 = CreateObject<Node>(); // 创建点对节点 PointToPointHelper pointToPoint; pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); // 设置节点之间的连接 NetDeviceContainer devices; devices.Add(pointToPoint.Install(n0, n1)); devices.Add(pointToPoint.Install(n1, n2)); devices.Add(pointToPoint.Install(n2, n3)); devices.Add(pointToPoint.Install(n3, n4)); devices.Add(pointToPoint.Install(n4, n5)); devices.Add(pointToPoint.Install(n5, n6)); devices.Add(pointToPoint.Install(n6, n7)); devices.Add(pointToPoint.Install(n7, n0)); // 安装网络协议栈 InternetStackHelper stack; stack.InstallAll(); ``` 上述代码中,我们创建了八个节点,并使用PointToPointHelper类创建点对点的连接。接下来,我们将八个节点两两相连,构成一个纺锤型网络。最后,我们使用InternetStackHelper类安装网络协议栈。 2. 使用不同的拥塞控制算法 NS3提供了多种拥塞控制算法,例如TCP NewReno、TCP VegasTCP Cubic等。我们可以在仿真程序中选择不同的算法来测试其性能。 ``` // 创建Socket和Application uint16_t port = 50000; Address sinkAddress(InetSocketAddress(Ipv4Address::GetAny(), port)); PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", sinkAddress); ApplicationContainer sinkApps = packetSinkHelper.Install(nodes.Get(0)); sinkApps.Start(Seconds(0.0)); sinkApps.Stop(Seconds(simulationTime + 0.1)); OnOffHelper onoff("ns3::TcpSocketFactory", sinkAddress); onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]")); onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]")); onoff.SetAttribute("DataRate", DataRateValue(DataRate("5Mbps"))); onoff.SetAttribute("PacketSize", UintegerValue(1000)); // 安装TCP协议 Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1000)); Config::SetDefault("ns3::TcpSocketBase::MaxWindowSize", UintegerValue(50000)); Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno")); ApplicationContainer clientApps = onoff.Install(nodes.Get(1)); clientApps.Start(Seconds(0.0)); clientApps.Stop(Seconds(simulationTime + 0.1)); ``` 上述代码中,我们创建了一个TCP Socket和一个TCP Application,并使用不同的拥塞控制算法来测试网络性能。在这里,我们选择了TCP NewReno算法。使用Config::SetDefault()函数可以设置TCP Socket的一些参数,例如最大窗口大小等。 3. 性能测试和报告 在仿真程序中,我们可以使用Simulator::Run()函数来运行仿真。在仿真结束后,我们可以获取一些性能指标,例如吞吐量、延迟、丢包率等,并根据这些指标来评估不同的拥塞控制算法。 ``` Simulator::Stop(Seconds(simulationTime + 0.1)); Simulator::Run(); // 获取性能指标 uint64_t totalPacketsThrough = DynamicCast<PacketSink>(sinkApps.Get(0))->GetTotalRx(); double throughput = totalPacketsThrough * 8 / (simulationTime * 1000000.0); // Mbps double avgDelay = 0; for (uint32_t i = 0; i < clientApps.GetN(); ++i) { Ptr<OnOffApplication> onoffApp = DynamicCast<OnOffApplication>(clientApps.Get(i)); Time startTime = onoffApp->GetStartTime(); Time stopTime = onoffApp->GetStopTime(); double thisDelay = (stopTime.GetSeconds() - startTime.GetSeconds()) * 1000.0; avgDelay += thisDelay; } avgDelay /= clientApps.GetN(); // ms uint64_t totalPacketsDropped = DynamicCast<PacketSink>(sinkApps.Get(0))->GetLost(); double packetLossRate = totalPacketsDropped * 1.0 / totalPacketsThrough; // 输出性能指标 std::cout << "Throughput: " << throughput << " Mbps" << std::endl; std::cout << "Average Delay: " << avgDelay << " ms" << std::endl; std::cout << "Packet Loss Rate: " << packetLossRate * 100 << "%" << std::endl; ``` 上述代码中,我们获取了网络的吞吐量、平均延迟和丢包率等性能指标,并输出到控制台。 根据上述代码,我们可以编写出完整的仿真程序,并根据不同的拥塞控制算法进行测试。在测试中,我们可以使用如下代码切换不同的拥塞控制算法: ``` Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno")); // 使用TCP NewReno算法 Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpVegas")); // 使用TCP Vegas算法 Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpCubic")); // 使用TCP Cubic算法 ``` 最终,我们可以根据实验结果,撰写不同拥塞控制算法对网络性能的影响的详细报告。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值