Date: Tue, 23 Nov 1999 10:19:03 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: Peter Wemm <peter@netplex.com.au>, Tommy Hallgren <thallgren@yahoo.com>, freebsd-smp@FreeBSD.ORG Subject: Found it ... Re: Matt's new unlock optimiazation Message-ID: <199911231819.KAA10294@apollo.backplane.com> References: <19991123140128.3A7D41C6D@overcee.netplex.com.au> <199911231703.JAA09896@apollo.backplane.com> <199911231751.JAA10135@apollo.backplane.com>
index | next in thread | previous in thread | raw e-mail
I got it.
http://developer.intel.com/drg/pentiumii/appnotes/831.htm
All we need is a serializing instruction. CPUID will do the trick, but
actually doing a locked instruction on private memory (verses shared
memory) is going to be faster.
with cpuid 141 ns
lock/private 47 ns (same with or without segment override)
lock/shared 160 ns (with cpu contention)
I'll commit the change in a little bit. It will look a little ugly, but
it will be very fast.
BTW, if people want to mess with this, my test program is below.
-Matt
cc lock1.c lock2.s -o test
/*
* LOCK1.C
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#define LOOPS 4000000
extern void fubar(void *ptr);
int
main(int ac, char **av)
{
int i;
int dt;
void *ptr;
struct timeval tv1;
struct timeval tv2;
int flags = MAP_ANON;
if (ac == 1) {
printf("%s [shared/private]\n", av[0]);
exit(1);
}
if (strcmp(av[1], "shared") == 0) {
flags |= MAP_SHARED;
} else if (strcmp(av[1], "private") == 0) {
;
} else {
printf("illegal argument\n");
exit(1);
}
ptr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, flags, -1, 0);
gettimeofday(&tv1, NULL);
if (fork() == 0) {
for (i = 0; i < LOOPS; ++i)
fubar(ptr);
_exit(0);
} else {
for (i = 0; i < LOOPS; ++i)
fubar(ptr);
while (wait(NULL) > 0)
;
}
gettimeofday(&tv2, NULL);
dt = tv2.tv_usec + 1000000 - tv1.tv_usec +
(tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
printf("%d nS/loop\n", dt * 1000 / (LOOPS * 2));
return(0);
}
/*
* LOCK2.S
*/
.text
.globl fubar
fubar:
movl 4(%esp),%ecx
/*cpuid*/
/*lock; cmpxchgl %eax,(%ecx)*/
/*lock; xchg %eax,(%ecx)*/
ret
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-smp" in the body of the message
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199911231819.KAA10294>
