RateLimiter的 SmoothBursty(非warmup预热)及SmoothWarmingUp(预热,冷启动)

SmoothBursty

主要思想

记录 1秒内的微秒数/permitsPerSencond = 时间间隔interval,每一个interval可获得一个令牌
根据允许使用多少秒内的令牌参数,计算出maxPermits
setRate时初始化下次interval时间,及storedPermits

acquire时,计算当前nowMicros,如果大于下次interval时间时间,则更新storedPermits和下次interval时间,计算storedPermits能否满足此次acquire,如果能,则需要等待的时间为0,如果不能,则计算还需要多少微秒等待,并在非同步块外执行sleep操作

如果其他线程已经刷新了nextFreeTicketMicros,会如下情况acquire是无timeout的

Thread 1: acquire 11 -> storedPermits不能满足要求 -> waitTime = (acquire - stored) * stableIntervalMicros -> nextFreeTicketMicros += waitMicros ----->  out lock sleep
Thread 2: acquire 2 -> nowMicros < nextFreeTicketMicros , stored = 0,被线程1消耗完了 -> freshPermits = requiredPermits - storedPermitsToSpend 即 = requiredPermits -> waitTime = freshPermits * stableIntervalMicros
-> nextFreeTicketMicros += waitTime,此时的nextFreeTicketMicros包含了Thread1需要等待的时间 -------> out lock sleep a longer time

tryAquire(num,timeout)逻辑

timeoutMicros = timeout.toMicros
lock()
nowMicros = ...
canAcquire = nextFreeTicketMicros <= nowMicros + timeoutMicros
if(!canAcquire){return false;
}
else{microsToWait = ...
} 
unlock()
sleep(microsToWait)
return true;

SmoothWarmingUp

主要思想和SmoothBursty相似,由于带预热过程,刚开始由于availablePermitsAboveThreshold>0.0,速率会较慢,如果持续获取令牌,则会使availablePermitsAboveThreshold=0,速率变快

  • 从0->thresholdPermits,生成一个令牌的时间:stableIntervalMicros
  • 从thresholdPermits-> maxPermits ,生成一个令牌的时间:stableIntervalMicros + permits * slope;

    @Override
    final long reserveEarliestAvailable(int requiredPermits, long nowMicros) {
    resync(nowMicros);
    long returnValue = nextFreeTicketMicros;
    //当前需要且尽最大可能消费的
    double storedPermitsToSpend = min(requiredPermits, this.storedPermits);
    //新鲜permits个数,这些个数是一定会产生等待的,除了0
    double freshPermits = requiredPermits - storedPermitsToSpend;
    //计算需要wait的总时间
    long waitMicros =
    //非busty类型的storedPermitsToWaitTime直接返回0
    storedPermitsToWaitTime(this.storedPermits, storedPermitsToSpend)
    + (long) (freshPermits * stableIntervalMicros);
    //下次有票时间
    this.nextFreeTicketMicros = LongMath.saturatedAdd(nextFreeTicketMicros, waitMicros);
    this.storedPermits -= storedPermitsToSpend;
    return returnValue;
    }

     //已知permitsToTake <= storedPermits@Overridelong storedPermitsToWaitTime(double storedPermits, double permitsToTake) {//减去预热需要保留的permits,剩下的可消耗的数量double availablePermitsAboveThreshold = storedPermits - thresholdPermits;long micros = 0;// measuring the integral on the right part of the function (the climbing line)//如果有剩余可用的令牌if (availablePermitsAboveThreshold > 0.0) {//剩余可用的和需要获取的个数取小值double permitsAboveThresholdToTake = min(availablePermitsAboveThreshold, permitsToTake);// TODO(cpovirk): Figure out a good name for this variable.//用可消耗的数量 + (可消耗的数量 - 实际消耗的数量)permitsToTime//在预热阶段从thresholdPermits到maxPermits的耗时并非是stableIntervalMicros * n//会耗费更多的时间,其计算规则不同,所以才需要把permitsAboveThresholdToTake从permitsToTake减去//length 可能作为一个经验值,相当于补充permitsAboveThresholdToTake个令牌需要的平均时间值*2//剩余可用的-实际需要且最大能消耗的令牌,得到最终剩余的令牌个数,可能是0double length = permitsToTime(availablePermitsAboveThreshold)+ permitsToTime(availablePermitsAboveThreshold - permitsAboveThresholdToTake);//这里确实不好理解,从语义环境来说,它是从 thresholdPermits 到 maxPertmis 过程中//生成 permitsAboveThresholdToTake 个令牌需要耗费的时间//并且带coldFactor的构造函数不是public,SmoothWarmingUp也是private-package的micros = (long) (permitsAboveThresholdToTake * length / 2.0);//从permitsToTake中减去保留预热需留下个数后最终消耗的个数,这部分个数由于是提前存在的、富余的//因此不需要计算到wait时间permitsToTake -= permitsAboveThresholdToTake;}// measuring the integral on the left part of the function (the horizontal line)//如果没有剩余可用令牌,走的是stableIntervalMicros * nmicros += (stableIntervalMicros * permitsToTake);return micros;}   

length/2可以理解为下图
50145-20190627124610807-599597721.png

    //permits值越小,需要的时间就越少,值越大,需要的时间就越大private double permitsToTime(double permits) {//double coldIntervalMicros = stableIntervalMicros * coldFactor;// thresholdPermits = 0.5 * warmupPeriodMicros / stableIntervalMicros;//maxPermits =thresholdPermits + 2.0 * warmupPeriodMicros / (stableIntervalMicros + coldIntervalMicros);//slope带比率的时间,可以理解为增长因子//slope =  (coldIntervalMicros - stableIntervalMicros) / (maxPermits - thresholdPermits)//return表示成这样更易于理解 stableIntervalMicros + (coldIntervalMicros - stableIntervalMicros) * (permits/(maxPermits - thresholdPermits))return stableIntervalMicros + permits * slope;}

转载于:https://www.cnblogs.com/windliu/p/11088320.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/483097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++学习——引用和指针

文章目录1. 引用和指针的区别&#xff1f;2. C中的指针参数传递和引用参数传递1. 引用和指针的区别&#xff1f; 指针是一个实体&#xff0c;需要分配内存空间。引用只是变量的别名&#xff0c;不需要分配内存空间。 #include<iostream> using namespace std;class sol…

未来已来:全球XR产业洞察

来源&#xff1a;德勤Deloitte编辑&#xff1a;蒲蒲近日&#xff0c;德勤中国科技、传媒和电信行业推出元宇宙系列报告《元宇宙系列白皮书—未来已来&#xff1a;全球XR产业洞察》&#xff0c;聚焦XR产业发展趋势。报告指出&#xff0c;多元融合是元宇宙的演变趋势。在元宇宙发…

C++学习——static

文章目录1. static的用法和作用&#xff1f;2.静态变量什么时候初始化1. static的用法和作用&#xff1f; 1.先来介绍它的第一条也是最重要的一条&#xff1a;隐藏。&#xff08;static函数&#xff0c;static变量均可&#xff09; 当同时编译多个文件时&#xff0c;所有未加…

谷歌、哈佛联手绘出「百万分之一」人脑神经3D连接图!天量数据竟可塞满14亿块1T硬盘...

来源&#xff1a;神经科技编辑&#xff1a;Yezi审阅&#xff1a;mingzlee7前不久&#xff0c;谷歌和哈佛大学联手发布人脑神经3D连接图&#xff0c;涵盖人脑一百万分之一的信息&#xff0c;但数据已经塞满了1400块1T硬盘&#xff01;现在&#xff0c;这个研究团队表示&#xff…

python replace()

转载于:https://www.cnblogs.com/JackFang-X/p/11090449.html

C++学习——const

文章目录1.const的作用2.const成员函数的理解和应用&#xff1f;1.const的作用 1. 阻止一个变量被改变&#xff0c;可以使用const关键字。在定义该const变量时&#xff0c;通常需要对它进行初始化&#xff0c;因为以后就没有机会再去改变它了&#xff1b; #include<iostre…

解决表单提交的数据丢失问题

解决表单提交的数据丢失问题&#xff1a; 一、问题描述&#xff1a; 当我们在给前台页面设置修改功能的时候&#xff0c;因为有些信息是不允许进行修改的&#xff0c;所以在修改表单中没有相应的修改输入框&#xff0c;但是在修改表单的数据提交的时候&#xff0c;那些不允许修…

科学家即将揭示人类大脑神经网络结构的奥秘

来源&#xff1a;今日头条人类即将迎来了解大脑神经网络结构神秘世界的曙光&#xff01;哈佛大学神经科学家和谷歌工程师&#xff0c;发布了第一张人类大脑部分的神经网络连接图&#xff0c;大约针头大小的人类大脑组织用重金属染色&#xff0c;切成 5,000&#xff0c;并在电子…

C++学习—— mutable和 extern

文章目录1. mutable2.extern用法&#xff1f;1. mutable 1) 如果需要在const成员方法中修改一个成员变量的值&#xff0c;那么需要将这个成员变量修饰为mutable。即用mutable修饰的成员变量不受const成员方法的限制; 常成员函数&#xff0c;不允许修改成员变量的值&#xff0c…

温故而知新,6位顶级CV科学家聚首:计算机视觉中的深度学习方法vs传统方法...

来源&#xff1a;AI科技评论作者&#xff1a;Mr Bear编辑&#xff1a;青暮2021 年 10 月 13 日&#xff0c;来自麻省理工学院、加州大学伯克利分校、伊利诺伊大学香槟分校、华盛顿大学、帝国理工学院的六名顶级人工智能科学家、计算机视觉科学家在 ICCV 2021 大会期间进行了题为…

20190626_二次开发BarTender打印机_C#代码_一边读取TID_一边打印_打印机POSTEK

demo代码如下: private void btnPrint_Click(object sender, EventArgs e){if (this.btnPrint.Text "停止打印"){SetBtnPrintUIEnable();return;}//禁用界面上的相关按钮SetBtnPrintUIDisable();var dt new DataTable(); new Task(() >{///开始的打印//1. 获取…

C++学习——string

文章目录1.int转字符串字符串转int?2.strcat,strcpy,strncpy,memset,memcpy的内部实现&#xff1f;1.int转字符串字符串转int? 例:"123"123#include<iostream> #include<string> using namespace std;string string_head_end(string str) {string s&q…

卷积神经网络(CNN)数学原理解析

来源&#xff1a;图灵人工智能作者&#xff1a;Piotr Skalski编辑&#xff1a;python数据科学原标题&#xff1a;Gentle Dive into Math Behind Convolutional Neural Networks翻 译&#xff1a; 通夜&#xff08;中山大学&#xff09;、had_in&#xff08;电子科技大学&#…

仅模糊背景图像而不是前面的文本

正如标题所说。 如何模糊容器的背景图像而不模糊前面的文本&#xff1f; <div class"card"> <div class"head"> <div class"title"> <span>Card Title</span> </div> </div> <div class"body…

C++学习——模板

文章目录1.C模板2.C模板是什么&#xff0c;底层怎么实现的&#xff1f;1.C模板 模板是泛型编程的基础&#xff0c;泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。 库容器&#xff0c;比如迭代器和算法&#xff0c;都是泛型编程的例…

【数据结构基础】-串-顺序结构的基本操作实现

2019.10.12 数据结构中串的基本操作实现&#xff0c;包括串的定义&#xff0c;串的初始化&#xff0c;赋值&#xff0c;获取串的长度&#xff0c;串的比较&#xff0c;连接串&#xff0c;求子串&#xff0c;清空串。 语言&#xff1a;c语言 运行环境&#xff1a;dev #include &…

大脑研究正在挑战超级计算,“人脑计划”或需提前部署百亿亿级超级计算机...

来源&#xff1a;DeepTech深科技人脑的复杂性正推动着超级计算释放更多的潜力。据了解&#xff0c;人脑包含大约 860 亿个神经元&#xff0c;可形成数万亿个接触点。如果以细胞分辨率对整个大脑进行成像&#xff0c;甚至会产生数 PB 范围内的数据&#xff0c;这样的的计算量令人…

02 算术、字符串与变量(1)

本章内容 1、交互式命令shell 2、整数算术 3、浮点算术 4、其他数学函数 5、字符串 6、字符串拼接 7、获取帮助 8、类型转换 9、变量和值 10、赋值语句 11、变量如何引用值 12、多重赋值 -------------------------------------- 在学习Python前&#xff0c;我们需要了解数据类…

C++学习——c语言和C++语言中的struct

C语言struct和Cstruct区别 C语言中&#xff1a;struct是用户自定义数据类型&#xff08;UDT&#xff09;&#xff1b; C中struct是抽象数据类型&#xff08;ADT&#xff09;&#xff0c;支持成员函数的定义&#xff0c;&#xff08;C中的struct能继承&#xff0c;能实现多态&am…

【数据结构基础】-线性表的顺序实现(数组实现)基本操作

2019.10.10 【数据结构-线性表的顺序结构】 基本操作&#xff1a;初始化&#xff0c;判断是否空表&#xff0c;清空表&#xff0c;获取表中的第i个元素&#xff0c;查找元素&#xff0c;插入元素&#xff0c;删除元素&#xff0c;获取表的元素个数。 抽象数据类型&#xff1a…