diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2011-07-21 13:57:13 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2011-07-21 13:57:13 -0400 |
| commit | 6b2ec065871019d07dcbe6ca527fbd4c600e1c19 (patch) | |
| tree | ec8664ae376c9fab705f6dfd359fd6af8100070a /src/cmd | |
| parent | 17d9093bf214f3461815410c298006bac8427c0e (diff) | |
| download | go-6b2ec065871019d07dcbe6ca527fbd4c600e1c19.tar.xz | |
runtime: faster select
Make selectsend() accept pointer to the element,
it makes it possible to make Scase fixed-size
and allocate/free Select, all Scase's and all SudoG at once.
As a consequence SudoG freelist die out.
benchmark old,ns/op new,ns/op
BenchmarkSelectUncontended 1080 558
BenchmarkSelectUncontended-2 675 264
BenchmarkSelectUncontended-4 459 205
BenchmarkSelectContended 1086 560
BenchmarkSelectContended-2 1775 1672
BenchmarkSelectContended-4 2668 2149
(on Intel Q6600, 4 cores, 2.4GHz)
benchmark old ns/op new ns/op delta
BenchmarkSelectUncontended 517.00 326.00 -36.94%
BenchmarkSelectUncontended-2 281.00 166.00 -40.93%
BenchmarkSelectUncontended-4 250.00 83.10 -66.76%
BenchmarkSelectUncontended-8 107.00 47.40 -55.70%
BenchmarkSelectUncontended-16 67.80 41.30 -39.09%
BenchmarkSelectContended 513.00 325.00 -36.65%
BenchmarkSelectContended-2 699.00 628.00 -10.16%
BenchmarkSelectContended-4 1085.00 1092.00 +0.65%
BenchmarkSelectContended-8 3253.00 2477.00 -23.85%
BenchmarkSelectContended-16 5313.00 5116.00 -3.71%
(on Intel E5620, 8 HT cores, 2.4 GHz)
R=rsc, ken
CC=golang-dev
https://golang.org/cl/4811041
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/gc/builtin.c.boot | 2 | ||||
| -rw-r--r-- | src/cmd/gc/go.h | 1 | ||||
| -rw-r--r-- | src/cmd/gc/runtime.go | 2 | ||||
| -rw-r--r-- | src/cmd/gc/select.c | 7 | ||||
| -rw-r--r-- | src/cmd/gc/subr.c | 37 | ||||
| -rw-r--r-- | src/cmd/ld/dwarf.c | 1 |
6 files changed, 37 insertions, 13 deletions
diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot index 95098c8afa..6419873a28 100644 --- a/src/cmd/gc/builtin.c.boot +++ b/src/cmd/gc/builtin.c.boot @@ -76,7 +76,7 @@ char *runtimeimport = "func \"\".selectnbrecv (elem *any, hchan <-chan any) bool\n" "func \"\".selectnbrecv2 (elem *any, received *bool, hchan <-chan any) bool\n" "func \"\".newselect (size int) *uint8\n" - "func \"\".selectsend (sel *uint8, hchan chan<- any, elem any) bool\n" + "func \"\".selectsend (sel *uint8, hchan chan<- any, elem *any) bool\n" "func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) bool\n" "func \"\".selectrecv2 (sel *uint8, hchan <-chan any, elem *any, received *bool) bool\n" "func \"\".selectdefault (sel *uint8) bool\n" diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 8ca086ee04..ff71e80a94 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -1137,6 +1137,7 @@ Sym* restrictlookup(char *name, Pkg *pkg); Node* safeexpr(Node *n, NodeList **init); void saveerrors(void); Node* cheapexpr(Node *n, NodeList **init); +Node* localexpr(Node *n, NodeList **init); int32 setlineno(Node *n); void setmaxarg(Type *t); Type* shallow(Type *t); diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index e13c95db93..7254f874e8 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -103,7 +103,7 @@ func selectnbrecv(elem *any, hchan <-chan any) bool func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool func newselect(size int) (sel *byte) -func selectsend(sel *byte, hchan chan<- any, elem any) (selected bool) +func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool) func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool) func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool) func selectdefault(sel *byte) (selected bool) diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c index 91d4ebfd50..14ec015f2d 100644 --- a/src/cmd/gc/select.c +++ b/src/cmd/gc/select.c @@ -309,7 +309,12 @@ walkselect(Node *sel) fatal("select %O", n->op); case OSEND: - // selectsend(sel *byte, hchan *chan any, elem any) (selected bool); + // selectsend(sel *byte, hchan *chan any, elem *any) (selected bool); + n->left = safeexpr(n->left, &r->ninit); + n->right = localexpr(n->right, &r->ninit); + n->right = nod(OADDR, n->right, N); + n->right->etype = 1; // pointer does not escape + typecheck(&n->right, Erv); r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL], &init, var, n->left, n->right); break; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 4253deabb2..96727b10bd 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2750,6 +2750,20 @@ safeexpr(Node *n, NodeList **init) return cheapexpr(n, init); } +static Node* +copyexpr(Node *n, NodeList **init) +{ + Node *a, *l; + + l = nod(OXXX, N, N); + tempname(l, n->type); + a = nod(OAS, l, n); + typecheck(&a, Etop); + walkexpr(&a, init); + *init = list(*init, a); + return l; +} + /* * return side-effect free and cheap n, appending side effects to init. * result may not be assignable. @@ -2757,21 +2771,26 @@ safeexpr(Node *n, NodeList **init) Node* cheapexpr(Node *n, NodeList **init) { - Node *a, *l; - switch(n->op) { case ONAME: case OLITERAL: return n; } - l = nod(OXXX, N, N); - tempname(l, n->type); - a = nod(OAS, l, n); - typecheck(&a, Etop); - walkexpr(&a, init); - *init = list(*init, a); - return l; + return copyexpr(n, init); +} + +/* + * return n in a local variable if it is not already. + */ +Node* +localexpr(Node *n, NodeList **init) +{ + if(n->op == ONAME && + (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT)) + return n; + + return copyexpr(n, init); } void diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index d02fff3c26..d8ca27acea 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -1422,7 +1422,6 @@ synthesizechantypes(DWDie *die) copychildren(dwh, hchan); substitutetype(dwh, "recvq", dww); substitutetype(dwh, "sendq", dww); - substitutetype(dwh, "free", defptrto(dws)); newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size)->value, nil); |
