Google 实时流拥塞控制算法GCC

2024-05-04 02:48

本文主要是介绍Google 实时流拥塞控制算法GCC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、简介

参考:https://tools.ietf.org/html/draft-ietf-rmcat-gcc-02#section-4.4

gcc是google实时流拥塞控制算法的简称,已经在webrtc中实现,应用于chrome,后面将应用到Hangouts(视频聊天产品)中,主要用于视频流的拥塞控制。

网络瓶颈主要发生在中间的传输设备上,比如路由器,所以如果有中间设备的帮助(ECN),网络瓶颈应该会更早并且更准确的被检测到,gcc属于端到端的拥塞控制算法,端到端的算法将中间路径想象成一个黑盒子,它不借助中间设备的帮助,这就增加了网络拥塞预测的难度。端到端的实时流拥塞算法主要有以下难点:

(1)网络拥塞一般与链路容量,当前链路中的流量以及即将发送的流量有关,由于路由的不确定性以及链路是由多个流共享并且瞬息万变等原因,对于一个流而言这三个因素都是随机变量。

(2)拥塞控制算法要求同一种流(都使用gcc)能够公平分享带宽,同时能够与TCP流公平相处,不会被TCP流抢占带宽,也尽量不要抢占TCP流的带宽。

(3)视频解码器对丢包敏感,但实时性又不能使用重传机制,因为需要尽量减少丢包,另一方面解码器并不能快速的调整码率,因而估计出的带宽尽量平滑,减少毛刺。

2、实现

gcc由基于延迟的控制器和基于丢包的控制器组成,信令基于RTP扩展头和RTCP传输。

(1)反馈和扩展

gcc可以有两种实现,第一种是两种控制器都在发送端实现,接收端周期性的反馈到达的每一个包的序列号和到达时间,发送端记录每一个包的发送时间和到达时间,同时计算出丢包率。第二种是延迟控制器在接收端实现,接收端计算出组间延迟,根据组间延迟计算出发送比特率通过REMB消息反馈给发送端,接收端通过RTCP消息将丢包率反馈给发送端,丢包控制器在发送端实现,发送端通过接收端反馈的信息计算出最终的发送比特率。

(2)发送引擎

定速器用于实现发送固定比特率的视频包,编码器产生的数据先会放到定时队列中,定时器会在每个burst_time发送一组包,burst_time建议为5ms,这一组包的大小是由发送比特率和burst_time计算出来的。

(3)延迟控制器

(3.1)到达时间模型

d(i) = t(i) - t(i-1) - (T(i) - T(i-1)) 

d(i)表示第i组包的延迟和第i-1组包的延迟之差,t(i)表示第i组包的到达时间,取最后一个包的到达时间,T(i)表示第i组包的发送时间,取最后一个包的发送时间,忽略乱序的包。

d(i) > 0说明组间的延迟增大了,d(i) < 0说明组间的延迟减少了,d(i) = 0说明组间的延迟没变化。

我们将组间延迟建模成 d(i) = w(i),w(i)是一个随机过程W的采样,这个随机过程是链路容量,当前链路的流量以及当前发送的比特率的函数。将W建模成白高斯过程。如果我们过度使用链路则我们期望w(i)增大,如果链路中的队列正在排空,则意味着w(i)将会减小,其它情况w(i)将是0。

d(i) = w(i) = m(i) + v(i)

m(i)是从w(i)中提取出来的使w(i)的均值为0的部分。v(i)是噪声项代表网络抖动以及其它模型捕捉不到的影响延迟的因素,v(i)是均值为0的高斯白噪声,方差var_v = E{v(i)^2}。

(3.2)滤波之前

链路中断会使延迟瞬间变化很大,影响模型的准确计算,所以滤波之前会把一些包合并成一组,如果满足下面的条件将会合并,(1)一些包的发送时间在一个burst_time内(2)一个包的组间到达时间小于burst_time并且组间延迟d(i)小于0。

(3.3)到达时间滤波

我们将要估计m(i)然后用这个估计值检测链路过载。gcc使用kalman滤波器来估计m(i)。

m(i+1) = m(i) + u(i)

上面的是m(i)的状态转移方程。u(i)是状态噪声,将它建模成均值为0,方差为q(i)的符合高斯统计的稳态过程,其中q(i) = E{u(i)^2},q(i)建议值为10^-3。

kalman滤波器递归地更新m(i)的估计值m_hat(i)

z(i) = d(i) - m_hat(i-1)

m_hat(i) = m_hat(i-1) + z(i) * k(i)

 k(i) = (e(i-1) + q(i)) / var_v_hat(i) + (e(i-1) + q(i))

e(i) = (1 - k(i)) * (e(i-1) + q(i))

其中;

var_v_hat(i) = max(alpha * var_v_hat(i-1) + (1-alpha) * z(i)^2, 1)

alpha = (1-chi)^(30/(1000 * f_max))

f_max = max {1/(T(j) - T(j-1))} for j in i-K+1,...,i 代表最近K组包的最大发送频率。

(3.4)过载探测

用到达时间滤波模块估计出的组间延迟m(i)与阈值del_var_th(i)进行比较,如果m(i) > del_var_th(i)则意味着过载,这一个条件还不能给速率控制系统发送过载信号,检测的过载时间最少维持overuse_time_th毫秒,并且不能出现m(i) < m(i-1)的情况。相反的情况,如果m(i) < -del_var_th(i)则意味着网络使用不足,最后一种情况是正常状态。

del_var_th对算法的整体仿真和性能有很大的影响,另外如果del_var_th取一个固定的值,将会被当前的TCP流占用带宽导致饥饿的产生。这个饥饿可以通过将del_var_th设置成足够大的值而避免。因而有必要动态调整del_var_th去获取更好的性能,例如与基于丢包的流的竞争中。

del_var_th(i) = del_var_th(i-1) + (t(i)-t(i-1)) * K(i) * (|m(i)|-del_var_th(i-1))

另外,如果|m(i)| - del_var_th(i) > 15时不更新del_var_th(i),并且del_var_th(i) 在[6, 600]区间内。

(3.5)速率控制器

当检测到过载,延迟控制器估计的有效带宽将会减少,通过这种方式获得一个递归的自适应的有效带宽估计。

速率控制子系统有3个状态,Increase, Decrease 和Hold状态。当没有检测出拥塞时是Increase状态,检测出拥塞时是Decrease状态,Hold状态表示等待队列清空的过程。

 

状态转移

增大当前有效带宽将使用乘法或加法,取决于当前的状态,如果当前估计的带宽离拥塞较远,则使用乘法,如果接近拥塞,则使用加法。如果当前的比特率R_hat(i)接近之前Decrease状态的平均比特率则认为接近拥塞。

R_hat(i)是延迟控制器在T秒钟的窗口中计算出来的接收比特率:

R_hat(i) = 1/T * sum(L(j)) for j from 1 to N(i)

其中N(i)是T秒钟接收的包数,L(j)是第j个包的负载长度。窗口建议设置成0.5秒到1秒之间。

eta = 1.08^min(time_since_last_update_ms / 1000, 1.0)

A_hat(i) = eta * A_hat(i-1)

在加法增长阶段,估计值在response_time最多增长半个包的长度。

response_time_ms = 100 + rtt_ms

alpha = 0.5 * min(time_since_last_update_ms / response_time_ms, 1.0)

A_hat(i) = A_hat(i-1) + max(1000, alpha * expected_packet_size_bits)

expected_packet_size_bits用于在低码率时获得一个缓慢的增长。它可以根据当前的码率估算出来。

bits_per_frame = A_hat(i-1) / 30

packets_per_frame = ceil(bits_per_frame / (1200 * 8))

avg_packet_size_bits = bits_per_frame / packets_per_frame

之前的讨论都是假设链路会出现拥塞,如果发送端产生不了足够的比特流,估计的有效带宽需要保持在一个给定的范围内。

A_hat(i) < 1.5 * R_hat(i)

如果检测到过载,则进入Decrease状态,延迟控制器估计的有效带宽会减少。

A_hat(i) = beta * R_hat(i)

beta一般选择属于[0.8, 0.95],一般建议是0.85。

(4)丢包控制器

定义丢包控制器估计有效带宽为As_hat。

延迟控制器估计的有效带宽只在队列足够大时有效,如果队列较小,就需要使用丢包率检测过载。

As_hat(i) = As_hat(i - 1)      (2 < p < 10%)

As_hat(i) = As_hat(i-1)(1-0.5p) (p > 10%)

As_hat(i) = 1.05(As_hat(i-1))      (p < 2%)

真实的发送速率设置成丢包控制器估计值和延迟控制器估计值的较小的。

我们观察到由于过载出现少量的丢包,如果不调整发送的比特率,丢包率会快速增长到达10%门限值然后调整发送比特率。然而,如果丢包率不增加,拥塞很可能不是自己造成的,因而不需要进行调整。

(5)互操作

如果发送端实现了这个算法,但是接收端没有实现RTCP消息和RTP头扩展,建议发送端检测RTCP的接收端报告,然后使用丢包率和rtt做为丢包控制器的输入,关闭延迟控制器。

 

注:服务中的自适应流控也可以参考GCC,后面这个是BRPC的流控:BRPC自适应流控



作者:x1wan
链接:https://www.jianshu.com/p/9be68af1f611
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这篇关于Google 实时流拥塞控制算法GCC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958195

相关文章

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

【linux学习指南】Linux编译器 gcc和g++使用

文章目录 📝前言🌠 gcc如何完成🌉预处理(进行宏替换) 🌠编译(生成汇编)🌉汇编(生成机器可识别代码) 🌠链接(生成可执行文件或库文件)🌉函数库 🌠gcc选项🚩总结 📝前言 预处理(进行宏替换)编译(生成汇编)汇编(生成机器可识别代码)连接(生成可执行文件或库文件) 🌠 gcc如何完成 格式 :gcc [选项] 要编译的文件 [选项] [目标文

三.海量数据实时分析-FlinkCDC实现Mysql数据同步到Doris

FlinkCDC 同步Mysql到Doris 参考:https://nightlies.apache.org/flink/flink-cdc-docs-release-3.0/zh/docs/get-started/quickstart/mysql-to-doris/ 1.安装Flink 下载 Flink 1.18.0,下载后把压缩包上传到服务器,使用tar -zxvf flink-xxx-

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException异常

用Gson解析json数据的时候,遇到一个异常,如下图: 这个异常很简单,就是你的封装json数据的javabean没有写对,你仔细查看一下javabean就可以了 比如:我的解析的代码是             Gson gson = new Gson();             ForgetJson rb = gson.fromJson(agResult.mstrJson, For

gcc编译常见问题

inux C gcc -lm     使用 math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项 ,因为数学函数位于 libm.so 库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找。本书用到的大部分库函数(例如printf)位于 libc.so 库文件中,使用libc.so中的库函数在编译时不需要加-l

Google Earth Engine——高程数据入门和山体阴影和坡度的使用

目录 山体阴影和坡度 对图像应用计算 应用空间减速器 高程数据 通过从“重置”按钮下拉菜单中选择“清除脚本”来清除脚本。搜索“elevation”并单击 SRTM Digital Elevation Data 30m 结果以显示数据集描述。单击导入,将变量移动到脚本顶部的导入部分。将默认变量名称“image”重命名为“srtm”。使用脚本将图像对象添加到地图: Map