Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Aug 2002 13:44:10 -0700
From:      Luigi Rizzo <rizzo@icir.org>
To:        current@freebsd.org
Subject:   how to compute the skew between TSC in SMP systems ?
Message-ID:  <20020823134410.A81962@iguana.icir.org>

next in thread | raw e-mail | index | archive | help
Hi,
does anyone have an idea on how to determine the skew between
TSC content in the various processors on an SMP box ?
 
I was thinking of having one CPU sending an interrupt to
all other processors, a-la forward_roundrobin(), and have
the handler of this interrupt on each processor spin until
acked and then so something like the code below -- basically
the master triggers the process and starts incrementing a
shared variable and saving TSC values around the increment,
the slaves monitor the advancement of the variable and save
samples, and then process() will try to find the average skew
between samples saved by different processors.

I don't know is 1) how to send an interrupt to all other
processors, and 2) how to trigger the execution of a specific
function in response to this interrupt.
Any ideas ?

(the purpose of the above would be to have a cheap way to
timestamp events on an SMP systems by using the TSC -- the
result of the procedure, assuming we can get it with a
significantly small variance, would let us give bounds
on the accuracy of the timestampsA. This would only
need to be done at boot time, so even if the
calibration phase is time consuming we do not care too much.

	cheers
	luigi

---------------
#define SAMPLES 1000
#define CYCLES 100

u_int64_t	*samples[MAXCPU]

volatile u_int64_t	sync_cycle;
volatile int foo;

master_function()
{
	int i,j;
	u_int64_t *s;
	
	sync_cycle = 0;

	for (i=0; i < MAXCPU; i++)
		samples[i] = malloc(sizeof(u_int64_t)*SAMPLES,
			M_TEMP, M_ZERO|M_DONTWAIT);
	
	s = samples[cpuid];
	<send interrupt to all processors>
	<wait until all respond>
	<wait some time so that the slave function can be started>
	for (i=0; i < SAMPLES; i++) {
		sync_cycle = i;
		s[i] = rdtsc();
		for (j=0; j < CYCLES; j++)
			foo = i * s[i]; /* just waste some time */
	}
	
	process(samples)
}

slave_function() /* <start after interrupt is received> */
{
	int i;
	u_int64_t *s;

	s = samples[cpuid];
	while ( (i = sync_cycle) < SAMPLES)
		s[i] = rdtsc();
}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020823134410.A81962>