Skip site navigation (1)Skip section navigation (2)
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>