曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6874|回复: 0
打印 上一主题 下一主题

SH_DIV,ACTHZ,TICK_NSEC

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
跳转到指定楼层
楼主
发表于 2011-4-2 21:30:39 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
内核:2.6.24
平台:x86 32位
在 linux 中有一个脉搏,它就是 HZ,在现代的 X86 上,改值被定义为 1000 ,也就是说每 1ms 会产生一次时钟中断,这个时钟间隔叫做一个节拍 (tick) 。

TICK_NSEC 就是以纳秒为单位来表示这个节拍的长度。TICK_NSEC 被定义为:

[C++] 纯文本查看 复制代码
/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */
#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))


上面, ACTHZ 表示实际的 HZ,这个值在这里并不是 1000,而是经过扩展为 256 倍后的一个中间值。之所以扩展,正是为了提高其精度,它的定义为:

[C++] 纯文本查看 复制代码
/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))


上面的两个宏都用到共同的一个宏 SH_DIV 。该宏目的是提高整数除法的精度,它定义为:

[C++] 纯文本查看 复制代码
/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can
 * improve accuracy by shifting LSH bits, hence calculating:
 *     (NOM << LSH) / DEN
 * This however means trouble for large NOM, because (NOM << LSH) may no
 * longer fit in 32 bits. The following way of calculating this gives us
 * some slack, under the following conditions:
 *   - (NOM / DEN) fits in (32 - LSH) bits.
 *   - (NOM % DEN) fits in (32 - LSH) bits.
 */
#define SH_DIV(NOM,DEN,LSH) (   (((NOM) / (DEN)) << (LSH))              \
                             + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))


关于 SH_DIV 的探讨可参考:http://www.groad.net/bbs/read.php?tid-3328.html


最后算得 TICK_NSEC 的值为 999848ns (产生的时钟信号频率大约为 1000.15Hz)。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-11-1 08:01 , Processed in 0.061403 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表