[comp.sys.sun] SPARC Context switching times

gja@mullian.ee.mu.OZ.AU (03/01/90)

The subject almost says it all. Does anyone know where I can find info. on
this. The issue is that we are interested in how fast an interrupt routine
will be activated after the actuall interrupt line is activated. Advice on
which FM to read would be appreciated.

lm@sun.com (Larry McVoy) (03/09/90)

In article <5539@brazos.Rice.edu> gja@mullian.ee.mu.OZ.AU writes:
>X-Sun-Spots-Digest: Volume 9, Issue 72, message 7
>
>The subject almost says it all. Does anyone know where I can find info. on
>this. The issue is that we are interested in how fast an interrupt routine
>will be activated after the actuall interrupt line is activated. Advice on
>which FM to read would be appreciated.

Well, I'm not sure how you want to count this: each process goes down into
the kernel to send the sig, back out of the kernel, and then back until
the signal is sent back from the other process.  I think you can believe
that you went back and forth 10000 times.  Both processes read a wall
clock time duration so how you want to compute the "context switch time"
is beyond me.  Anyway, this may help you get a rough idea.  On a SS1 I get
something like 710 usec each in the printout which I think means 350usec /
switch.  Furthermore, running the program under rusage shows mean 10011
voluntary switches but another 2400 involuntary switches.  That cuts it
down to 564usec / switch which gives 282 usec each.  It's on the order of
300 usecs is my best guess.

Remember - Sun's have "contexts" so rapidly switching between two
processes is faster than switching between 100.  It doesn't scale
linearly.  Furthermore, measuring ctx switch time this way isn't very
meaningful - the processes are tiny, the pages are always there in memory,
the cache is probably full and hitting like crazy etc, etc.

#include <sys/types.h>
#include <signal.h>

pid_t other;
int caught;

void handler() { caught++; }

main()
{
	struct sigvec sv;
	int parent;

	sv.sv_handler = handler;
	sv.sv_mask = 0;
	sv.sv_flags = 0;
	sigvec(SIGUSR1, &sv, 0);
	sigblock(sigmask(SIGUSR1));

	if (!(other = fork())) {
		other = getppid();
		parent = 0;
	} else {
		parent = 1;
	}
	start();
	while (caught < 10000 && (kill(other, SIGUSR1) != -1))
		sigpause(0);
	kill(other, SIGUSR1);
	stop();
	printf("This time is real time, divide by two for ctx sw time\n");
	ptime(caught);
	if (parent)
		wait(0);
}

/* 
 * statistics code
 */
#include "stdio.h"
#include "sys/types.h"
#include "sys/time.h"

static struct timeval t1, t2;

error(s)
    char* s;
{
    perror(s);
    exit(1);
}

start() { gettimeofday(&t1, 0); }
stop() { gettimeofday(&t2, 0); }
ptime(bytes) { ptransfer(bytes, &t1, &t2); }

ptransfer(bytes, t0, t1)
	long bytes;
	struct timeval *t0, *t1;
{
	struct timeval td;
	double s, bs;

	tvsub(&td, t1, t0);
	s = td.tv_sec + (td.tv_usec / 1000000.);
#define	nz(x)	((x) == 0 ? 1 : (x))
	bs = bytes / nz(s);
	printf("%d in %.4g secs, %.6g / sec, %.6g millisec each\n",
		bytes, s, bs, s / (bytes / 1000.0));
}

tvsub(tdiff, t1, t0)
	struct timeval *tdiff, *t1, *t0;
{

	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
	if (tdiff->tv_usec < 0)
		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
}

What I say is my opinion.  I am not paid to speak for Sun, I'm paid to hack.
    Besides, I frequently read news when I'm drjhgunghc, err, um, drunk.
Larry McVoy, Sun Microsystems     (415) 336-7627       ...!sun!lm or lm@sun.com