Re: Looking for SMP-capable tester

Colin Plumb (colin@nyx.net)
Fri, 4 Dec 1998 09:37:41 -0700 (MST)


Thanks, folks! I've already got a pile of replies!
I'm getting on towards enough, but if you're curious
about your machine, here's a bug-fixed version that
actually computes the skew properly.

Two things of note:
- If you see a skew greater than 10, I'd be interested in
lots of details about your system, including particularly
the BIOS. (AMI, Phoenix, Award, ...) Running it
repeatedly, does the skew ever reverse?
- If the numbers in columns printed aren't nearly identical,
are you sure your machine is entirely idle? Do you have any
network interfaces running in promiscuous mode competing for
memory bandwidth?

I've got a lot of "good" figures (lots of identical numbers), and
a few "bad" ones (lots of noise). I'm curious what makes the
numbers noisy.

Again, thanks for everyone's help. Run the following harmless
little thing on an SMP system to measure the TSC difference
between two processors.

-- 
	-Colin

#include <stdio.h>

#include <sched.h>

static volatile int receive_ready; static volatile int pad1[15]; static volatile int signal_sent; static volatile int pad2[15];

static char child_stack[100000];

#define NSAMPLES 25

unsigned master_send[NSAMPLES], master_receive[NSAMPLES]; unsigned slave_send[NSAMPLES], slave_receive[NSAMPLES];

#define rdtsc(hi,lo) asm volatile("rdtsc" : "=a" (lo), "=d" (hi))

static int master(void *arg) { unsigned hi, lo; int i;

(void)arg;

for (i = 0; i < NSAMPLES; i++) { /* Send to slave */ signal_sent = 0; while (!receive_ready) ; rdtsc(hi,lo); /* Waste time */ receive_ready = 0; rdtsc(hi,lo); signal_sent = 1; master_send[i] = lo;

/* Receive from slave */ while (signal_sent) ; receive_ready = 1; while (!signal_sent) ; rdtsc(hi,lo); master_receive[i] = lo; }

/* Wait for slave to store last datum */ while (!receive_ready) ;

return 0; }

static int slave(void *arg) { unsigned hi, lo; int i;

(void)arg;

for (i = 0; i < NSAMPLES; i++) { /* Receive from master */ while (signal_sent) ; receive_ready = 1; while (!signal_sent) ; rdtsc(hi,lo); slave_receive[i] = lo;

/* Send to master */ signal_sent = 0; while (!receive_ready) ; rdtsc(hi,lo); /* Waste time */ receive_ready = 0; rdtsc(hi,lo); signal_sent = 1; slave_send[i] = lo; }

/* Tell master we're done */ receive_ready = 1; _exit(); }

int main(void) { int i; int min1, min2, delta; #define CLONE_ALL (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_PID)

/* * We want master and slave running simultaneously, each on a * different processor. Unfortunately, user space offers no * guarantees, but on an idle machine, it should work. */ clone(slave, child_stack + sizeof(child_stack), CLONE_ALL, 0); master(0);

min1 = min2 = 0x7fffffff; for (i = 1; i < NSAMPLES; i++) { delta = slave_receive[i] - master_send[i]; if (min1 > delta) min1 = delta; printf("%9d ", delta); delta = master_receive[i] - slave_send[i]; if (min2 > delta) min2 = delta; printf("%9d\n", delta); } printf("min1 = %d, min2 = %d, skew = %d\n", min1, min2, min1 - min2); return 0; }

- 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.tux.org/lkml/