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

Open
dvyukov opened this Issue Feb 2, 2015 · 4 comments

Comments

Projects
None yet
3 participants
@dvyukov
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 dvyukov added this to the Go1.5Maybe milestone Feb 2, 2015

@dvyukov

This comment has been minimized.

Member

dvyukov commented Feb 2, 2015

@dvyukov

This comment has been minimized.

Member

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

This comment has been minimized.

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

This comment has been minimized.

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 from cmd/gc: don't emit writebarrier for stores to newly allocated objects to cmd/compile: don't emit writebarrier for stores to newly allocated objects Jun 8, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment