Date: Mon, 12 Jul 1999 11:12:08 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Poul-Henning Kamp <phk@critter.freebsd.dk>, Luoqi Chen <luoqi@watermarkgroup.com>, dfr@nlsystems.com, jeremyp@gsmx07.alcatel.com.au, freebsd-current@FreeBSD.ORG, mike@ducky.net Subject: Ack! Wrong results. Message-ID: <199907121812.LAA70732@apollo.backplane.com>
next in thread | raw e-mail | index | archive | help
How did that happen?!!! Argg.. I didn't save the email. Here are better results: Empty loop: mode 0 9.21 ns/loop nproc=1 lcks=EMPTY With and without lock prefix, one and two processes mode 1 16.48 ns/loop nproc=1 lcks=no mode 2 23.65 ns/loop nproc=2 lcks=no mode 3 93.02 ns/loop nproc=1 lcks=yes mode 4 160.82 ns/loop nproc=2 lcks=yes With and without lock prefix, one and two processes, with other global memory operations (note that the lock prefix instructions have absorbed the other memory ops) mode 5 37.64 ns/loop nproc=1 lcks=no mode 6 89.28 ns/loop nproc=2 lcks=no mode 7 88.32 ns/loop nproc=1 lcks=yes mode 8 161.08 ns/loop nproc=2 lcks=yes My conclusion from this is that the lock protocols have a general case overhead of 50 to 80 nS on a duel P-III/450 system. I don't think it would be noticeable. -Matt /* * Compile -O2 */ #include <sys/types.h> #include <sys/mman.h> #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <stdarg.h> #include <unistd.h> #define LOOPS 10000000 #define ATOMIC_ASM(type,op) \ __asm __volatile ("lock; " op : "=m" (*(type *)p) : "ir" (v), "0" (*(type *)p)) #define ATOMIC_ASM_NOLOCK(type,op) \ __asm __volatile (op : "=m" (*(type *)p) : "ir" (v), "0" (*(type *)p)) static __inline void atomic_add_int(void *p, u_int v) { ATOMIC_ASM(int, "addl %1,%0"); } static __inline void atomic_add_int_nolock(void *p, u_int v) { ATOMIC_ASM_NOLOCK(int, "addl %1,%0"); } volatile int GX[8]; /* note: not shared between processes */ int main(int ac, char **av) { int fd; int *ptr; char *wlocks; int pgsize = getpagesize(); volatile int i; int m; int usec; struct timeval tv1; struct timeval tv2; fd = open("test.dat", O_RDWR|O_CREAT|O_TRUNC, 0666); ftruncate(fd, pgsize); ptr = mmap(NULL, pgsize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); for (m = 0; m <= 8; ++m) { pid_t pid = -1; int nproc = 1; const char *lcks = "EMPTY"; gettimeofday(&tv1, NULL); switch(m) { case 8: pid = fork(); nproc = 2; /* fall through */ case 7: for (i = 0; i < LOOPS; ++i) { atomic_add_int(ptr, 1); GX[0] = 1; GX[1] = 1; GX[2] = 1; GX[3] = 1; GX[4] = 1; GX[5] = 1; GX[6] = 1; GX[7] = 1; } lcks = "yes"; break; case 6: pid = fork(); nproc = 2; /* fall through */ case 5: for (i = 0; i < LOOPS; ++i) { atomic_add_int_nolock(ptr, 1); GX[0] = 1; GX[1] = 1; GX[2] = 1; GX[3] = 1; GX[4] = 1; GX[5] = 1; GX[6] = 1; GX[7] = 1; } lcks = "no"; break; case 4: pid = fork(); nproc = 2; /* fall through */ case 3: for (i = 0; i < LOOPS; ++i) { atomic_add_int(ptr, 1); } lcks = "yes"; break; case 2: pid = fork(); nproc = 2; /* fall through */ case 1: for (i = 0; i < LOOPS; ++i) { atomic_add_int_nolock(ptr, 1); } lcks = "no"; break; case 0: for (i = 0; i < LOOPS; ++i) { ; } break; default: printf("huh?\n"); exit(1); } if (pid == 0) _exit(0); while (wait(NULL) > 0) ; gettimeofday(&tv2, NULL); usec = tv2.tv_usec + 1000000 - tv1.tv_usec + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000; printf("mode %d\t%6.2f ns/loop nproc=%d lcks=%s\n", m, (double)usec * 1000.0 / (double)LOOPS / (double)nproc, nproc, lcks); } return(0); } 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?199907121812.LAA70732>