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>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199911231819.KAA10294>