Re: [RFC - 0/9] Generic timekeeping subsystem (v. B5)

From: Ulrich Windl
Date: Wed Aug 17 2005 - 01:11:52 EST


On 16 Aug 2005 at 11:25, Christoph Lameter wrote:

> You mentioned that the NTP code has some issues with time interpolation
> at the KS. This is due to the NTP layer not being aware of actual time
> differences between timer interrupts that the interpolator knows about. If
> the NTP layer would be aware of the actual intervals measured by the
> timesource (or interpolator) then presumably time could be adjusted in a
> more accurate way.

Hi,

whatever the implementation is, at some point there must exist an interface go get
and set "normal time", free of any jumps and jitter. That "frontend time" will be
used a a base of correction. Basically that means time should be as monotonic and
jitter free as possible for any measurement interval you like.

Otherwise when extrapolating the time-error, it (NTP) will try to overcompensate
(or undercompensate), making the whole thing instable.

Here's a sample from some ancient NTP distribution (pre-nanosecond), but you'll
get the idea what to check:

more util/jitter.c
/*
* This program can be used to calibrate the clock reading jitter of a
* particular CPU and operating system. It first tickles every element
* of an array, in order to force pages into memory, then repeatedly calls
* gettimeofday() and, finally, writes out the time values for later
* analysis. From this you can determine the jitter and if the clock ever
* runs backwards.
*/
#include <sys/time.h>
#include <stdio.h>

#define NBUF 20002

void
main()
{
struct timeval ts, tr;
struct timezone tzp;
long temp, j, i, gtod[NBUF];

gettimeofday(&ts, &tzp);

/*
* Force pages into memory
*/
for (i = 0; i < NBUF; i ++)
gtod[i] = 0;

/*
* Construct gtod array
*/
for (i = 0; i < NBUF; i ++) {
gettimeofday(&tr, &tzp);
gtod[i] = (tr.tv_sec - ts.tv_sec) * 1000000 + tr.tv_usec;
}

/*
* Write out gtod array for later processing with S
*/
for (i = 0; i < NBUF - 2; i++) {
/*
printf("%lu\n", gtod[i]);
*/
gtod[i] = gtod[i + 1] - gtod[i];
printf("%lu\n", gtod[i]);
}

/*
* Sort the gtod array and display deciles
*/
for (i = 0; i < NBUF - 2; i++) {
for (j = 0; j <= i; j++) {
if (gtod[j] > gtod[i]) {
temp = gtod[j];
gtod[j] = gtod[i];
gtod[i] = temp;
}
}
}
fprintf(stderr, "First rank\n");
for (i = 0; i < 10; i++)
fprintf(stderr, "%10ld%10ld\n", i, gtod[i]);
fprintf(stderr, "Last rank\n");
for (i = NBUF - 12; i < NBUF - 2; i++)
fprintf(stderr, "%10ld%10ld\n", i, gtod[i]);
}

Regards,
Ulrich

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/