-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: SSA recalculating loop termination condition every time #16457
Comments
Looks as though the 1.7 compiler has decided to leave the sqrt() call inside the inner loop for some reason (in spite of it being loop-invariant). Assembly for 1.7 for the inner loop looks like
For 1.6 the inner loop looks like:
Also appears that the 1.7 compiler is not able to eliminate divide-by-zero check if I am reading that correctly, but I don't think that's the real performance issue. |
This is tighten's fault; it is moving the sqrt calculation closer to use. Simpler code: package main
import "math"
var x uint32
func main() {
end := uint32(math.Sqrt(float64(x)))
for j := uint32(3); j <= end; j += 2 {
}
} With
With regular SSA:
With SSA with the tighten pass disabled:
Observe that with tighten disabled, we do have to generate an extra CMPL, so in some sense, tighten is doing its job...it just has no idea that the value calculation it moved is so expensive that it's worth keeping out of the loop. Not sure what the right approach is here. |
We have a (reducible) "loop detector" hanging around that we might be able to use for this; tag some operations as "expensive" and don't tighten them any closer than just before the entry to the next loop. We also have a strongly-connected-components detector in a pending 1.8 CL that will find all (outermost) loops, including the irreducible ones. |
There's also a simple, minimal fix for this particular problem: CL 25111. |
CL https://golang.org/cl/25111 mentions this issue. |
I believe this is now fixed since https://go-review.googlesource.com/c/28712/ @s-l-teichmann Can you confirm? |
Looks fine now. I'v re-run the orignal test with todays |
Please answer these questions before submitting your issue. Thanks!
go version
)?go env
)?Arch Linux / Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.
I run a prime number generator
https://play.golang.org/p/7asXrSGepM
(which dumps out as much primes as possible)
for 10 seconds.
Current git:
Go 1.6.3:
The numbers should be in the same order/range.
The 1.6 number is twice as high as the 1.7 one.
If I remove the math.Sqrt function before the inner loop in
favour to the out commented line above the numbers are nearly
equal.
The text was updated successfully, but these errors were encountered: