]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: faster chan creation on Linux/FreeBSD/Plan9
authorDmitriy Vyukov <dvyukov@google.com>
Thu, 4 Aug 2011 12:31:03 +0000 (08:31 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 4 Aug 2011 12:31:03 +0000 (08:31 -0400)
The change removes chan finalizer (Lock destructor)
if it is not required on the platform.

benchmark                    old ns/op    new ns/op    delta
BenchmarkChanCreation          1132.00       381.00  -66.34%
BenchmarkChanCreation-2        1215.00       243.00  -80.00%
BenchmarkChanCreation-4        1084.00       186.00  -82.84%
BenchmarkChanCreation-8        1415.00       154.00  -89.12%
BenchmarkChanCreation-16       1386.00       144.00  -89.61%
(on 2 x Intel Xeon E5620, 8 HT cores, 2.4 GHz, Linux)

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/4841041

src/pkg/runtime/chan.c
src/pkg/runtime/chan_test.go
src/pkg/runtime/darwin/thread.c
src/pkg/runtime/freebsd/thread.c
src/pkg/runtime/linux/thread.c
src/pkg/runtime/plan9/thread.c
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h
src/pkg/runtime/windows/thread.c

index b77e51b60da015bbe74a1c56d978b6b65c8755c7..65feacb78b4858ba36723cc7483e468b8aa3b018 100644 (file)
@@ -85,7 +85,6 @@ runtime·makechan_c(Type *elem, int64 hint)
 {
        Hchan *c;
        int32 n;
-       byte *by;
 
        if(hint < 0 || (int32)hint != hint || (elem->size > 0 && hint > ((uintptr)-1) / elem->size))
                runtime·panicstring("makechan: size out of range");
@@ -101,10 +100,9 @@ runtime·makechan_c(Type *elem, int64 hint)
                n++;
 
        // allocate memory in one call
-       by = runtime·mal(n + hint*elem->size);
-
-       c = (Hchan*)by;
-       runtime·addfinalizer(c, destroychan, 0);
+       c = (Hchan*)runtime·mal(n + hint*elem->size);
+       if(runtime·destroylock)
+               runtime·addfinalizer(c, destroychan, 0);
 
        c->elemsize = elem->size;
        c->elemalg = &runtime·algarray[elem->alg];
index c5ffe93acc29074c4082bbd95220aaff1b85de9e..71c9e2fd785491c07369dddc7821c08908980d25 100644 (file)
@@ -265,3 +265,25 @@ func BenchmarkChanProdConsWork10(b *testing.B) {
 func BenchmarkChanProdConsWork100(b *testing.B) {
        benchmarkChanProdCons(b, 100, 100)
 }
+
+func BenchmarkChanCreation(b *testing.B) {
+       const CallsPerSched = 1000
+       procs := runtime.GOMAXPROCS(-1)
+       N := int32(b.N / CallsPerSched)
+       c := make(chan bool, procs)
+       for p := 0; p < procs; p++ {
+               go func() {
+                       for atomic.AddInt32(&N, -1) >= 0 {
+                               for g := 0; g < CallsPerSched; g++ {
+                                       myc := make(chan int, 1)
+                                       myc <- 0
+                                       <-myc
+                               }
+                       }
+                       c <- true
+               }()
+       }
+       for p := 0; p < procs; p++ {
+               <-c
+       }
+}
index 235d69abfc319193839448b75c128a9d83c11188..6733e815e8163426043fe7773b1c4af28416bfb6 100644 (file)
@@ -82,8 +82,8 @@ runtime·unlock(Lock *l)
        }
 }
 
-void
-runtime·destroylock(Lock *l)
+static void
+destroylock(Lock *l)
 {
        if(l->sema != 0) {
                runtime·mach_semdestroy(l->sema);
@@ -147,6 +147,7 @@ runtime·osinit(void)
        // to let the C pthread libary install its own thread-creation callback.
        if(!runtime·iscgo)
                runtime·bsdthread_register();
+       runtime·destroylock = destroylock;
 }
 
 void
index 569098aa218653e7e83987cda9e6bd71b6c7d68c..f8c550f5780e4871d7f4e450c72c92a11a90c515 100644 (file)
@@ -102,11 +102,6 @@ runtime·unlock(Lock *l)
        umtx_unlock(l);
 }
 
-void
-runtime·destroylock(Lock*)
-{
-}
-
 // Event notifications.
 void
 runtime·noteclear(Note *n)
index 8efba2b98b2164b69b69cb930bd3edfec180d3c2..4878a00f25eb6d35bfa22a86abe828d3066aef18 100644 (file)
@@ -199,11 +199,6 @@ runtime·unlock(Lock *l)
        futexunlock(l);
 }
 
-void
-runtime·destroylock(Lock*)
-{
-}
-
 
 // One-time notifications.
 void
index b091c59788f9e8ee555111de759ecc77701f1d7e..776989242d5c697de9f047a8ce69eb44fed504f9 100644 (file)
@@ -114,12 +114,6 @@ runtime·unlock(Lock *l)
 }
 
 
-void 
-runtime·destroylock(Lock *l)
-{
-       // nothing
-}
-
 // User-level semaphore implementation:
 // try to do the operations in user space on u,
 // but when it's time to block, fall back on the kernel semaphore k.
index c572897d2c3f9dd63233b2d99a2cc6152cf78e9d..57c0873306437acac65158896555070d0b420079 100644 (file)
@@ -10,6 +10,7 @@ enum {
 };
 
 uint32 runtime·panicking;
+void   (*runtime·destroylock)(Lock*);
 
 /*
  * We assume that all architectures turn faults and the like
index 434c82b95dd6e03b17d78a7e76ede99a6f4ed817..d2e4378b59c20c4e9a5af2721ad7f62274c34a47 100644 (file)
@@ -380,6 +380,7 @@ extern      uint32  runtime·panicking;
 extern int32   runtime·gcwaiting;             // gc is waiting to run
 int8*  runtime·goos;
 extern bool    runtime·iscgo;
+extern void    (*runtime·destroylock)(Lock*);
 
 /*
  * common functions and data
@@ -515,7 +516,6 @@ void        runtime·starttheworld(void);
  */
 void   runtime·lock(Lock*);
 void   runtime·unlock(Lock*);
-void   runtime·destroylock(Lock*);
 
 /*
  * sleep and wakeup on one-time events.
index 5644fd5dd79d5cbae8205c96ea164e14f37630b3..4ab043e8874e9958ac1323e8466ad19980a3e36c 100644 (file)
@@ -40,12 +40,14 @@ extern void *runtime·WaitForSingleObject;
 extern void *runtime·WriteFile;
 
 static int64 timerfreq;
+static void destroylock(Lock *l);
 
 void
 runtime·osinit(void)
 {
        runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
        runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
+       runtime·destroylock = destroylock;
 }
 
 void
@@ -154,8 +156,8 @@ runtime·unlock(Lock *l)
        eventunlock(l);
 }
 
-void
-runtime·destroylock(Lock *l)
+static void
+destroylock(Lock *l)
 {
        if(l->event != 0)
                runtime·stdcall(runtime·CloseHandle, 1, l->event);