poll/select timout accuracy

Jean-Marie Sulmont (jms@aracnet.com)
Mon, 20 Jul 1998 18:00:26 -0700 (PDT)


Hello.

I'm having problems with timer accuracy of both poll() and select()
system calls on 2.1.xxx on an Intel P6 box where the cpu is clocked at
300Mhz. I'm joining a little program that demonstrates the problem.
In two words, if you do:
t1 = getclock();
poll(0,0,10);
t2 = getclock();
then t2 - t1 is going to be 19.422559ms in avg. So the error is 9.42ms.
The little program is computing the standard deviation and arithmetic mean.
When the timeout given to poll is 100, the error drops to 9.18ms.
When it is 550, it drops to 7.8ms. At 1second, the error is 6.553135ms.

I'm using the real time 64 bits counter of the P6.
I've tried to read the sys_select() code but does not know what a jiffies
is. The program works on Sun OK, showing a constant and consistant error.

This is *very* ennoying. Anyone has an idea? What am I doing wrong?

The behaviour is exactly the same with select().

Thanks, Jean-Marie.

-------------------------- snip ----------------------------------------
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <math.h>
#include <assert.h>

#if defined(linux)
typedef unsigned long long res_t;
res_t
getclock ()
{
res_t now;
asm volatile ("rdtsc":"=A" (now)::"memory");
return now;
}
#define CPUSPEED 300 /* CPU speed in Mhz */
#define F(x) ((double)(x) / (CPUSPEED*1000))
#else
typedef hrtime_t res_t;
#define getclock() gethrtime();
#define F(x) ((double)x/1000000)
#endif

main (int argc, char **argv)
{
int N, i, to, *y;
res_t t1, t2;
double sx, sx2;

to = argc >= 2 ? atoi (argv[1]) : 20;
N = argc == 3 ? atoi (argv[2]) : 100;
y = (int *) malloc (4 * N);
assert (y != 0);

for (i = 0; i < N; i++)
{
t1 = getclock ();
poll (0, 0, to);
t2 = getclock ();
y[i] = t2 - t1;
}
sx = sx2 = 0;
for (i = 0; i < N; i++)
{
sx += y[i];
sx2 += pow (y[i], 2);
}
printf ("%d\t%f\t\t", to, F (sx / N) - to);
printf ("avg=%f\t", F (sx / N));
printf ("std=%f\n", F (sqrt (((double) sx2 - (sx * sx) / N) / N)));
free (y);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html