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: bounds check elimination for `if len(x) > 32 { ...; x = x[8:]; ... }` #24876

Open
dgryski opened this Issue Apr 15, 2018 · 4 comments

Comments

Projects
None yet
6 participants
@dgryski
Contributor

dgryski commented Apr 15, 2018

( From #23354 (comment) )

In dgryski/go-metro@1308eab I got a major performance boost by changing the loop to remove the reassignments to ptr which, even though they were still within range, invalidated the bounds checks for that were valid for ptr before the assignment.

The bounds-check elimination prover should handle this common case.

@rasky

This comment has been minimized.

Member

rasky commented Apr 15, 2018

This is already fixed on master by my prove CLs. I will add a specific testcase.

@gopherbot

This comment has been minimized.

gopherbot commented Apr 15, 2018

Change https://golang.org/cl/107355 mentions this issue: cmd/compile: add testcase for #24876

@dgryski

This comment has been minimized.

Contributor

dgryski commented Apr 15, 2018

Sweet! Sorry I didn't check against tip. I forgot about filing this issue and Austin's comments made it sound like it was unlikely to be done anytime soon.

@mvdan mvdan added the Performance label Apr 16, 2018

@bradfitz bradfitz added the NeedsFix label Apr 16, 2018

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Apr 18, 2018

@rasky

This comment has been minimized.

Member

rasky commented Sep 2, 2018

Sorry, forgot to update this issue. The specific case in dgryski/go-metro@1308eab is unfortunately not fixed yet.

IOW, this still has bound checks:

        for len(data) >= 32 {
		x += binary.BigEndian.Uint64(data)
		data = data[8:]
		x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
		data = data[8:]
		x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
		data = data[8:]
		x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
		data = data[8:]
	}

while this doesn't:

        for len(data) >= 32 {
		x += binary.BigEndian.Uint64(data[:8])
		x += binary.BigEndian.Uint64(data[8:16])
		x += binary.BigEndian.Uint64(data[16:24])
		x += binary.BigEndian.Uint64(data[24:32])
		data = data[32:]
	}

I'll notice that, even if you remove bound checks from the first snippet, you still get a lot of overhead compared to the second one because the additional 3 slice updates that require a writebarrier and computation of len/cap which are not optimized away.

gopherbot pushed a commit that referenced this issue Sep 2, 2018

cmd/compile: add testcase for #24876
This is still not fixed, the testcase reflects that there are still
a few boundchecks. Let's fix the good alternative with an explicit
test though.

Updates #24876

Change-Id: I4da35eb353e19052bd7b69ea6190a69ced8b9b3d
Reviewed-on: https://go-review.googlesource.com/107355
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment