Re: [PATCH] i386: Selectable Frequency of the Timer Interrupt

George Anzinger
2005-07-12T00:42:03Z

[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]

Martin J. Bligh wrote:
>>>Lots of people have switched from 2.4 to 2.6 (100 Hz to 1000 Hz) with no impact in
>>>stability, AFAIK. (I only remember some weird warning about HZ with debian woody's
>>>ps).
>>>
>>
>>Yes, that's called "progress" so no one complained. Going back is
>>called a "regression". People don't like those as much.
>
>
> That's a very subjective viewpoint. Realize that this is a balancing
> act between latency and overhead ... and you're firmly only looking
> at one side of the argument, instead of taking a compromise in the
> middle ...
>
> If I start arguing for 100HZ on the grounds that it's much more efficient,
> will that make 250/300 look much better to you? ;-)

I would like to interject an addition data point, and I will NOT be subjective.
The nature of the PIT is that it can _hit_ some frequencies better than
others. We have had complaints about repeating timers not keeping good time.
These are not jitter issues, but drift issues. The standard says we may not
return early from a timer so any timer will either be on time or late. The
amount of lateness depends very much on the HZ value. Here is what the values
are for the standard CLOCK_TICK_RATE:

HZ TICK RATE jiffie(ns) second(ns) error (ppbillion)
100 1193180 10000000 1000000000 0
200 1193180 5000098 1000019600 19600
250 1193180 4000250 1000062500 62500
500 1193180 1999703 1001851203 1851203
1000 1193180 999848 1000847848 847848

The jiffie values here are exactly what the kernel uses and are based on the
best one can do with the PIT hardware.

I am not suggesting any given default HZ, but rather an argumentation of the
help text that goes with it. For those who want timers to repeat at one second
(or multiples there of) this is useful info.

For you enjoyment I have attached the program used to print this. It allows you
to try additional values...

--
George Anzinger george@mvista.com
HRT (High-res-timers): http://sourceforge.net/projects/high-res-timers/

[-- Attachment #2: as.c --]
[-- Type: text/x-csrc, Size: 1430 bytes --]

#define NSEC_PER_SEC 1000000000
//#define CLOCK_TICK_RATE /*100000000 */ 1193180
#define LATCH(CLOCK_TICK_RATE,HZ) ((CLOCK_TICK_RATE + HZ/2) / HZ)
#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \
+ (((NOM % DEN) << LSH) + DEN / 2) / DEN)
#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH(CLOCK_TICK_RATE,HZ), 8))
#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))

struct {
int hz;
int clocktickrate;
} vals[] = {{100, 1193180}, {200, 1193180}, {250, 1193180}, {500, 1193180}, {1000, 1193180},{0,0}};

void do_it(int hz,int tickrate)
{
int HZ = hz;
int CLOCK_TICK_RATE = tickrate;
int tick_nsec = TICK_NSEC;
int ticks_per_sec = NSEC_PER_SEC/tick_nsec;
int sec_size = ticks_per_sec * tick_nsec;
int one_sec_p;
int err;

if (sec_size < NSEC_PER_SEC)
sec_size += tick_nsec;
one_sec_p = sec_size;
err = one_sec_p - NSEC_PER_SEC;
printf( "%4d\t%8d\t%8d\t%10d\t%8d\n",hz, tickrate, tick_nsec,
one_sec_p, err);
}

void bail(void)
{
printf("run as: as [hz [clock_tick_rate]]\n");
exit(1);
}

main(int argc, char** argv)
{
int i = 0;
int phz = 0;
int pcr = vals[0].clocktickrate;

if (argc > 1) {
phz = atoi(argv[1]);
if (!phz)
bail();
}
if (argc > 2) {
pcr = atoi(argv[2]);
if (!pcr)
bail();
}

printf("HZ \tTICK RATE\tjiffie(ns)\tsecond(ns)\t error (ppbillion)\n");
while(vals[i].hz) {
do_it(vals[i].hz, vals[i].clocktickrate);
i++;
}
if (phz)
do_it(phz, pcr);
}