math is hard, lets go shopping!
1 用法
/**
* cyc2ns - converts clocksource cycles to nanoseconds
* @cs: Pointer to clocksource
* @cycles: Cycles
*
* Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
*
* XXX - This could use some mult_lxl_ll() asm optimization
*/
static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
{
u64 ret = (u64)cycles;
ret = (ret * cs->mult) >> cs->shift;
return ret;
}
2 动机
为什么不 cycles *NSEC_PER_SEC / freq?
1. convert the clock cycles to ns
ns = cyc *
NSEC_PER_SEC / freq (freq is clock freq of the counter)
= use the
scaling math. (please refer to arch/x86/kernel/tsc.c)
= (cyc * mult)
>> shift (refer to clocksource_calc_mult_shift() )
另2.6.34
arch/x86/kernel/tsc.c
/*
Accelerators for sched_clock()
* convert from cycles(64bits) =>
nanoseconds (64bits)
* basic equation:
* ns =
cycles / (freq / ns_per_sec)
* ns = cycles *
(ns_per_sec / freq)
* ns = cycles * (10^9 / (cpu_khz *
10^3))
* ns = cycles * (10^6 / cpu_khz)
*
*
Then we use scaling math (suggested by george@mvista.com) to get:
*
ns = cycles * (10^6 * SC / cpu_khz) / SC
* ns = cycles
* cyc2ns_scale / SC
*
* And since SC is a constant power
of two, we can convert the div
* into a shift.
*
* We can
use khz divisor instead of mhz to keep a better precision, since
*
cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
*
(mathieu.desnoyers@polymtl.ca)
*
*
-johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
3 shift
value和mult的选取
/**
+ * clocksource_hz2shift - calculates shift
from hz and # of bits
+ * @bits: Number of bits this clocksource uses
+
* @hz: Clocksource frequency in Hz
+ *
+ * Helper functions that
calculates the best shift value
+ * based on the hz and # of bits of
any given clock.
+ */
+static inline u32 clocksource_hz2shift(u32
bits, u32 hz)
+{
+ u64 temp;
+
+ for (; bits > 0; bits--)
{
+ temp = (u64) NSEC_PER_SEC << bits;
+ do_div(temp, hz);
+
if ((temp >> 32) == 0)
+ break;
+ }
+ return bits;
+}
结
合下面的解释,可以看到要保证shift足够大, 同时又要保证temp(即以后的mult) 必须
2^32-1 范围内
[patch
0/3] Provide generic function to calc mult/shift factors for clocks
The mult and shift factors of clock events differ in
their data type
from those of clock sources for no reason. u32 is
sufficient for
both. shift is always <= 32 and mult is limited to
2^32-1 to avoid
64bit multiplication overflows in the conversion.
2.6.34
有clocksource_calc_mult_shift函数
阅读(1323) | 评论(0) | 转发(0) |