-
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: a constant expression is moved into a loop #71443
Comments
That's not a load, it is just an address calculation. The compiler doesn't try to keep those outside the loop currently. We could, I guess, but there's a tension there between computing the address just once, and using an additional register to hold it. The worries about raciness don't apply here, as |
Do you have a benchmark that demonstrates that the |
Here is the C + asm version of the same loop.
This is a 10.4% more time because of a The code for the benchmark:
There is one difference. |
There is another interesting thing. Consider the following code. It has the same loop as
The loop compiles to the following code:
The C + asm code for this version of the loop (
The difference of the run time between the two is
For this version of the loop, the difference between |
I couldn't believe that a random Source code: https://go.dev/play/p/dwi-EzN2oTo You also need to patch the assembler to use diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index 638f4e2fc4..0bc8d1e3ce 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -68,7 +68,7 @@ func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
labels: make(map[string]*obj.Prog),
dataAddr: make(map[string]int64),
errorWriter: os.Stderr,
- allowABI: ctxt != nil && objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI,
+ allowABI: true,
pkgPrefix: pkgPrefix,
}
} This test a 2×4 configuration space:
Here are results for 10 interleaved runs:
If anything my conclusion is that for this exact function, having the |
Go version
go version go1.24rc2 linux/amd64
Output of
go env
in your module/workspace:What did you do?
Compile the following code:
What did you see happen?
The second function loads the global var
table
into a local var before the loop, and never changes it. I'd expect that load to happen once in the generated code, yetSum0()
andSum1()
compile to the same code and loadtable
in every loop iteration:What did you expect to see?
Do not move constant expressions into a loop, evaluate them only once.
Even in the case of
Sum0()
repeated reloads oftable
look dubious to me. Another goroutine may changetable
concurrently, but in the absence of locking inSum0()
I'd argue that hoisting the load out of the loop is as racy as reloading it every time. Moreover,table
is private to the package so the compiler can know that no code in the package writes to it, nor takes its address, sotable
is a constant.The text was updated successfully, but these errors were encountered: