初探linux子系统集之timer子系统(二)
想着博客中还没有翻译过一篇文章,虽然英文水平有限,但是借助google翻译慢慢地翻译出一篇文章也是不错的选择。那就来学习下hrtimer的文档吧,翻译的略搓,可以直接跳过这篇,这里仅作为学习的过程!^_^
hrtimers - 高精度内核timers子系统
----------------------------------------------------
这个补丁是介绍一个新的高精度内核timers子系统。
可能有人会问:我们已经有了一个timer子系统(kernel/timers.c),为什么我们需要两个timer子系统呢?在长期的来回试图将高分辨率和高精度的功能集成到现有的timer框架,并在实践中对高精度timers的实现经过各种测试后,我们最终得出了结论是timer的时间轮代码基本上说不适合这样的做法的。我们最初不相信这个(必须有一个解决方案),并发费了相当大的努力试图整合到timer时间轮里,但是我们失败了。事后看来,这种整合很难/不可能是有很多原因的:
1、强制将低分辨率和高分辨率的timers以同样的方式处理导致了很多妥协和很多#ifdef的宏。timers.c代码是非常严格地关于jiffies和采取32位数的,并且已经被磨练和优化到相对狭窄的用例很多年了,因此即使是很小的扩展,也很容易毁掉时间轮的概念,从而导致更加糟糕的妥协。timer时间轮代码是非常好的,紧凑的代码,而且在目前的使用情况下没有出现任何问题,但是它根本就不适合再扩展到高分辨率tmers了。
2、级联的不可预知的O(n)的开销会导致需要更复杂的处理高精度计时器的延迟,从而又降低了鲁棒性。这样的设计还是会引起相当大的时间不准确。级联是timer时间轮概念的基本属性,它不能被设计出在不可接受的方式中带来不必然的降低timer.c部分代码。
3、目前posix的timer子系统上timer时间轮的实现已经推出了相当复杂的处理CLOCK_REALTIME timers的settimeofday或者ntp time-我们的经验,进一步的例子:timer时间轮数据结构对于高精度timers过于严格了。
4、timer时间轮代码是可被确定的最优化的“timeout”用例。这样的超时通常设置为覆盖各种I/O路径的错误,如网络和块的I/O。绝大多数的timers永不过期,很少级联,因为预期正确的事件都及时到来,所以在需要处理它们之前就可以在timer时间轮里面删除了。因而这些超时的用户可以接受timer时间轮的粒度和精度的权衡,并在很大程度上期待timer子系统的开销接近于0。对它们来说准确不是核心目的-事实上大部分使用的超时值都是热点。对它们来说,至多是一个必要以保证超时的完成,因此,这应该是最便宜和不显眼的了。
精密timer的主要用户是用户空间的程序,它们使用nanosleep,posix的timers和itimer的接口。此外,在内核中,用户喜欢驱动程序和子系统也用timer的事件(例如多媒体),可以从一个单独的益高精度timer子系统中受益。
虽然该子系统目前还不提供高精度的时钟源,但是该高精度子系统可以很容易地扩展高精度时钟的功能,并且补丁已经存在并迅速成熟。为实时和多媒体应用的需求日益增加以及用于精确的计时器的其他潜在用户提供了另一个理由分开超时和精准计时器的子系统。
另一个潜在的好处是,这样的分离允许甚至更特殊用户在现有计时器轮低分辨率和低精度的用例的优化-一旦精确敏感API从计时器轮分离,并且被迁移过来hrtimers。例如,我们可以减少在超时子系统的频率从250HZ到100HZ(或者更小)。
hrtimer子系统的实现细节
----------------------------------------------------
基本的设计考虑是:
-简单
-数据结构不绑定jiffies或者任何其他粒度。一切内核逻辑工作在64位纳秒分辨率-不做任何妥协
-简化现有的,时间相关的内核代码
另一个基本的要求是直接入队列然后排列激活timers。看完一些可能的解决方案,比如基数树和哈希,我们选择了红黑树作为基本的数据结构。红黑树可以作为内核库,并且被用在了众多像内存管理和文件系统等的性能要求很严格的领域。这里红黑树仅用于时间排列顺序,一个单独的列表用于给出后可以让代码快速访问排列定时器,而无需遍历红黑树。
(这单独的列表对之后我们要介绍的高精度的时钟非常有用,此外我们需要分离申请中的和过期的队列,同时保持时间顺序完好)
timer排序的入队列不是纯碎用于高精度时钟而言,虽然它也简化了基于低分辨率CLOCK_REALTIME定时器的绝对的处理。现有的实现需要保持所有额外的列表绝对的CLOCK_REALTIME定时器以及复杂的锁。万一settimeofday和NTP,甚至所有的定时器不得不出队列,timer变化的代码不得不解决这些一个接着一个的问题,并且所有这些都必须再次入队列。timer排序的入队和到期时间,在绝对时间的单位存储将产出posix定时器实现的一切复杂的和缩放不好的代码-时钟可以简单地无需触摸红黑树而设置。这也通常情况下使得处理posix定时器变得更加简单。
锁定和hrtiemers的每个CPu的行为大部分是取自现有的定时器轮的代码,因为它十分成熟,非常适合。由于不同的数据结构,代码共享还不能成功。此外,hrtimer函数现在也越来月清晰明了了-比如hrtimer_try_to_cancel()和hrtimer_cancel()[这大致相当于del_timer()和del_timer_sync()]-所以没有将它们直接的1:1映射,因而没有真正潜力来实现代码的共享。
基本数据类型:每时刻time的值,绝对或者相对的,是在一个特殊的纳秒级分辨率的类型:ktime_t。内核内部是通过宏和内联函数来实现表示ktime_t的值和操作的,并且可以在混合联合类型和64位纳秒之间切换。混合联合类型优化了在32位的CPU的一次转换。这个构建时可选择ktime_t存储格式,实现避免在32位CPU上的64位乘法和除法对性能的影响。这样的操作是经常需要由内核和用户空间的接口和内部时刻格式提供的存储格式之间进行转换。(见/include/linux/ktime.h获取更多详细信息)。
hrtimers-四舍五入的计时器值
----------------------------------------------------
该hrtimer代码将以较低分辨率的时钟围绕计时器事件,因为它必须如此,否则它不会做任何人工舍入的。
一个问题是什么分辨率值应该通过返回给用户所述clock_getres()接口。这将返回一个给定时钟任何实际分辨率-无论是低分辨率,高分辨率,或者人工低分辨率。
hrtimers-测试和验证
----------------------------------------------------
我们用在hrtimers顶部的高分辨率时钟子系统验证,在实践中hrtimer实施细则,我们跑了posix计时器测试,以确保符合规范。我们也在低分辨率的时钟下试验。
该hrtimer补丁转换了下面的内核函数使用hrtimers:
- nanosleep
- itimers
- posix-timers
对于nano sleep喝posix定时器的转变启动了统一的nanosleeo和clock_nanosleep
该代码已经成功在以下平台编译成功:
i386, x86_64, ARM, PPC, PPC64, IA64
hrtimers也集成到-rt树,连同一个hrtimers型高分辨率时钟的实现,所以hrtimers代码也得到了海量的测试并在实践中使用。
初探linux子系统集之timer子系统(二)的更多相关文章
- 初探linux子系统集之timer子系统(三)
因为现在的linux虽然还是可以使用低精度的timer,但是趋势是高精度hrtimer,所以上一篇试着翻译一下hrtimer的一些介绍,翻译的不是很好,看来英语还得好好学习啊,下面还是好好学习下lin ...
- 初探linux子系统集之timer子系统(一)
一般来说要让整个linux系统跑起来,那么一个必须的就是linux的时钟,也就是时间子系统了,这里正好工作需要,那么就研究下linux下的时间子系统了. linux内核必须完成两种主要的定时测量.一个 ...
- 转载-lvs官方文档-Linux服务器集群系统(二)
Linux服务器集群系统(二) LVS集群的体系结构 章文嵩 (wensong@linux-vs.org) 2002 年 4 月 本文主要介绍了LVS集群的体系结构.先给出LVS集群的通用体系结构,并 ...
- 初探linux子系统集之led子系统(二)
巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一眼看到7:1还以为点球也能踢成这样,后来想想,点球对多嘛6比1啊,接着就是各种新闻铺天盖地的来了.其实失败并没有什么,人生若是能够成功 ...
- 初探linux子系统集之led子系统(二)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37606487 巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一 ...
- 初探linux子系统集之i2c子系统(二)
大概也是前年了,一直没有把那个i2c的子系统讲解完,这里偷个懒,把以前整理的i2c相关的知识再梳理一下,做个了结,然后再去学习timer子系统. 先看下i2c在内核中的代码分布: obj-$(CONF ...
- 初探linux子系统集之led子系统(一)
就像学编程第一个范例helloworld一样,学嵌入式,单片机.fpga之类的第一个范例就是点亮一盏灯.对于庞大的linux系统,当然可以编写一个字符设备驱动来实现我们需要的led灯,也可以直接利用g ...
- 初探linux子系统集之led子系统(一)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37569789 就像学编程第一个范例helloworld一样,学嵌入式,单片机.f ...
- 初探linux子系统集之i2c子系统(一)
I2c子系统在进公司来的时候就学习过了,可是那是还不是很熟悉linux中的i2c子系统,就没有细看.记得当初很想熟悉linux中的各种总线驱动,想专门写一个关于总线驱动的专集,后来发现好像就没有几个, ...
随机推荐
- 习题9-8 uva1631
题意: 给你一串密码,每次我们可以转动1-3个数字,求转出最终答案的最小步数 思路: 感觉自己好坑,最开始想的是dp[cur][t1][t2][t3]也就是t1的位置以及连续的三个数的状态 但是卡死循 ...
- bzoj3129[Sdoi2013]方程 exlucas+容斥原理
3129: [Sdoi2013]方程 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 582 Solved: 338[Submit][Status][ ...
- JFinal实现伪静态
JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ru ...
- SSM实战
http://www.07net01.com/2016/07/1607717.html https://github.com/Lutils/MyForum
- JSON.parse()在火狐中的BUG
//用sessionStorage解决load页面刷新问题 { //sessionStorage.removeItem("loadInfo"); var loadInfo=de ...
- js变量的一点认识
js中变量包含两种不同数据类型的值,基本类型值(简单的数据段)和引用类型值(可能由多个值组成的对象).那么他们在保存方式和复制变量值是上有什么不同呢? 一.保存 只能给引用类型的值动态添加属性,不能给 ...
- React框架 dva 和 mobx 的使用感受
最近在用react写web项目,领导为了让前端便于维护要求都用react作为开发基础,框架选型不限.在使用 react 的时候或多或少会接触到状态管理,从开始学 react 到现在也挺久了,做一些前端 ...
- 聊聊LightProbe原理实现以及对LightProbe数据的修改
0x00 前言 最近工作比较忙,所以文章已经很久没有更新了.这篇小文的主题也是在出差的高铁上想到,因为最近和一些朋友聊天,发现他们中很多人的项目中都使用了多个实时光源.细问之下主要是某些物体,例如角色 ...
- 当我们在谈论JMM(Java memory model)的时候,我们在谈论些什么
前面几篇中,我们谈论了synchronized.final以及voilate的用法和底层实现,都绕不开一个话题-Java内存模型(java memory model,简称JMM).Java内存模型是保 ...
- Bootstrap3 表格-状态类
通过这些状态类可以为行或单元格设置颜色. .active---鼠标悬停在行或单元格上时所设置的颜色 .success--–标识成功或积极的动作 .info----标识普通的提示信息或动作 .warni ...