Reading Notes about mult and shift Pairs
Author:YangHonggang (Joseph) <eagle.rtlinux@gmail.com>
Kernel version: Linux 3.0.4
========================================================== ========================================================== ==========================================
The mult and shift values exist in X in the kernel code.
Clocksource, clock_event_device, timekeeper, cyclecounter, clock_data
Next, let's take a look at its application in clocksource.
The clocks_calc_mult_shift () function is used to calculate the mult and shift values based on specific application parameters. Let's start with the analysis here.
/* Clocks_calc_mult_shift-calculatemult/shift factors for scaled math of clocks
* @ Mult: pointer to mult variable
* @ Shift: pointer to shift variable
* @ From: frequency to convert from
* @ To: frequency to convert
* @ Maxsec: guaranteed runtimeconversion range in seconds
* The function evaluates theshift/mult pair for the scaled math
* Operations of clocksources andclockevents.
* @ To and @ from are frequency valuesin Hz. For clock sources @ to is
* Nsec_per_sec = 1 GHz and @ from isthe counter frequency. For clock
* Event @ to is the counter frequencyand @ from is nsec_per_sec.
* The @ maxsec conversion rangeargument controls the time frame in
* Seconds which must be covered by theruntime conversion with
* Calculated mult and shift factors. This guarantees that no 64bit
* Overflow happens when the inputvalue of the conversion is
* Multiplied with the calculated multfactor. Larger ranges may
* Reduce the conversion accuracy bychosing smaller mult and shift factors.
*/
Void
Clocks_calc_mult_shift (u32 * mult, u32 * shift, u32 from, u32 to, u32 maxsec)
{
U64 TMP;
U32 SFT, sftacc = 32;
/*
* Calculate the shift factor whichis limiting the conversion
* Range:
*/
TMP = (u64) maxsec * From)> 32; [1]
While (TMP ){...... [*]
TMP> = 1;
Sftacc --;
} [-1]
/*
* Find the conversion shift/multpair which has the best
* Accuracy and fits the maxsecconversion range:
*/
For (SFT = 32; SFT> 0; SFT --) {[2]
TMP = (u64) to <SFT;
TMP + = from/2;
Do_div (TMP, from );
If (TMP> sftacc) = 0) [3]
Break;
}
* Mult = TMP;
* Shift = SFT;
}
Before analyzing the principles of this Code, first look at the following relationship.
If the clock frequency is freq, the clock cycle is 1/freq second, that is
1/freq * nsec_per_sec nanoseconds.
The number of ns in the Cyc clock is,
NS = Cyc * (nsec_per_sec/freq )...... [A]
In actual computation, because the kernel does not support floating-point computation and only supports integer division computation, it will cause a great loss of precision. Therefore, we need to transform the sub-statements above, as shown below:
NS = (CYC * (nsec_per_sec <N)/freq)> N ...... [B]
Ling
Mult = (nsec_per_sec <N)/freq
N = Shift
So,
NS = (CYC * mult)> shift ...... [C]
The above code is analyzed as follows:
The following analysis is based on
Clocks_calc_mult_shift (& CS-> mult, & CS-> shift, freq,
Nsec_per_sec, Sec );
Call an instance.
First,[1]Possible UseMult, shiftTo process the largestCycValue
The explanation is as follows,
By formula [a],
Because maxsec is the maximum time range (in seconds) that can be used to use mult, shift conversion is known.
Yes,
Maxsec = Cyc/freq
Available,
Cyc = maxsec * freq
Therefore, our conclusion is that the function of the Code in [1] is to obtain the maximum Cyc value that can be converted using mult and shift.
[*]AtWhileLoop To obtainCycThe maximum number of places that can be moved to the left to ensure that no result is displayed.64Bit overflow.
The result is saved in sftacc. // NS = (CYC <n) * nsec_per_sec/freq)> N
Then,[2]Find the best conversion AccuracyMult, shiftValue Pair.
Shift value. The larger the value, the better.
The explanation is as follows,
TMP = (to <SFT)/from
= (Nsec_per_sec <SFT)/freq
In fact, TMP is Mult
However, there can be multiple mult and shift pairs, but only one is the best.
From formula [c], we can find the criteria with good conversion accuracy,
If, mult> (sftacc + x) and X are integers greater than 1, the maximum limit of Cyc is obviously reduced,
If, mult> (sftacc-x), X
Is an integer greater than 1, so it is clear that when the number of Cyc is small
[C] The Conversion Result is 0, which affects the conversion accuracy.
Therefore, a good standard is,
The maximum mult that can satisfy (mult> sftacc = 0) can locate the final mult, and the corresponding shift can also be obtained.