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: avoid repeated write barrier checks #48245

Open
CAFxX opened this issue Sep 8, 2021 · 1 comment
Open

cmd/compile: avoid repeated write barrier checks #48245

CAFxX opened this issue Sep 8, 2021 · 1 comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance
Milestone

Comments

@CAFxX
Copy link
Contributor

CAFxX commented Sep 8, 2021

(I quickly went through the open write barrier issues and couldn't find something covering this, so here goes. Sorry if I missed it.)

While investigating something completely unrelated (I'm on 1.17 on darwin/amd64), I noticed that we coalesce writes behind a single write barrier check, but we don't do so consistently:

image

In the loop on the left, we check whether the write barrier is enabled 4 times, even though once would suffice. I could understand redoing the check if there were function calls or otherwise a significant amount of code between two wb checks, but that's not the case in this specific instance.

In this instance, I would have expected instead at most one write barrier check per loop iteration and the whole jump-threaded wb-enabled version pushed away to a cold section of the function. Given the tiny amount of code in the common parts, and the elimination of the compare and jumps due to jump-threading, it is even possible that total code size would decrease.

Just for completeness, the go code goes something like this:

	// var wg1, wg2 sync.WaitGroup
	// var p = runtime.GOMAXPROCS(0)
	for i := 0; i < p; i++ {
		wg1.Add(1)
		wg2.Add(1)
		t := time.NewTicker(d)
		go func() {
            // lots of stuff
        }()
    }

(Another thing that is visible in that graph is that sometimes both predecessors of a basic block end with an unconditional jump: with better ordering one of the two jumps should not be required)

@randall77
Copy link
Contributor

I think the back-and-forth is due the fact that when we write a composite value, we share the scalar-writing parts and then branch for the pointer-writing parts.
You're right, we could duplicate some code to remove some checks. We'd need some sort of cost model for doing that.

@randall77 randall77 added this to the Unplanned milestone Sep 8, 2021
@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 13, 2021
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance
Projects
None yet
Development

No branches or pull requests

4 participants