Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: don't emit writebarrier for stores to newly allocated objects #9755

Closed
dvyukov opened this issue Feb 2, 2015 · 5 comments
Closed

Comments

@dvyukov
Copy link
Member

dvyukov commented Feb 2, 2015

Consider the following code:

x := &X{&obj, make([]int, n)}
...

Compiler transforms it to roughly the following code:

tmp0 := runtime.makeslice(int, n)
tmp1 := runtime.newobject(X)
runtime.writebarrierptr(&tmp1.f0, &obj)
runtime.writebarrierslice(&tmp1.f2, tmp0)

I suspect that barriers are unnecessary in this case because tmp1 is accessible only through the stack of the current goroutine. So &obj and tmp0 will be found and marked during stack scanning.

It seems that a simple approximation of the "is accessible only through the stack of the current goroutine" condition is "we have not yet encountered any calls since allocation of the object". That is:

tmp1 := runtime.newobject(X)
tmp1.f0 = ... // no write barrier
tmp1.f1 = ... // no write barrier
any function call
tmp1.f0 = ... // write barrier
tmp1.f2 = ... // write barrier

@dvyukov
Copy link
Member Author

dvyukov commented Feb 2, 2015

@rsc @RLH @randall77

@dvyukov
Copy link
Member Author

dvyukov commented Feb 2, 2015

I've calculated an optimistic approximation of the potential win by counting runtime.writebarrier calls right after runtime.newobject calls w/o any intervening calls in godoc binary.
Total number of writebarrier calls = 9732
writebarrier calls right after newobject = 2495
= ~25%

@RLH
Copy link
Contributor

RLH commented Feb 2, 2015

I'm not sure the gain is as large as you imply with your 25% number. If the
write barrier is off then the compiler will eventually emit a normal path
of a load of gcphase, a compare, and a branch. Since the branch is
predictable any reasonable OOO machine will do a pretty good job hiding the
sequence. It will be great when we get to a point where these types of
performance optimizations are at the top of our list for increasing
performance.

On Mon, Feb 2, 2015 at 12:23 PM, Dmitry Vyukov notifications@github.com
wrote:

I've calculated an optimistic approximation of the potential win by
counting runtime.writebarrier calls right after runtime.newobject calls w/o
any intervening calls in godoc binary.
Total number of writebarrier calls = 9732
writebarrier calls right after newobject = 2495
= ~25%


Reply to this email directly or view it on GitHub
#9755 (comment).

@rsc rsc removed the repo-main label Apr 14, 2015
@rsc
Copy link
Contributor

rsc commented May 19, 2015

The compiler now emits the needWriteBarrier check. I think that's enough for Go 1.5. We can revisit this if and when profiles show that we're spending too much time on things like this.

@rsc rsc modified the milestones: Unplanned, Go1.5Maybe May 19, 2015
@rsc rsc changed the title cmd/gc: don't emit writebarrier for stores to newly allocated objects cmd/compile: don't emit writebarrier for stores to newly allocated objects Jun 8, 2015
@randall77
Copy link
Contributor

This is fixed now; the following code has no write barriers:

package main

type X struct {
	p *int
	q []int
}

var obj int

func f(n int) {
	x := &X{&obj, make([]int, n)}
	g(x)
}

//go:noescape
func g(x *X)

@golang golang locked and limited conversation to collaborators Apr 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants