
Go Escape Analysis Flaws - diakritikal
https://docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/preview?sle=true
======
xdissent
Russ Cox commented on a couple of the proposed fixes:

> Maybe after the compiler is converted to Go.

> I'm not willing to make major changes to escape analysis right now. I intend
> to ask someone to take a look at the whole thing and see whether it should
> be changed/rewritten/fixed/etc in a few weeks.

It sounds to me like there are some significant changes coming down the pipe
anyway, which may or may not effect the current escape analysis behavior.

~~~
twotwotwo
Vyukov and others have made some allocation-related changes that went by today
in [https://twitter.com/golang_cls](https://twitter.com/golang_cls) (small
maps and string-related buffers can now sometimes be stack-allocated,
variables captured by closures less often need to be moved to the heap, and
some other language constructs that used to allocate now don't). It figures
that some stuff wouldn't be approved for 1.5; other changes are going on, and
some compromise mostly seems like the cost of the regular release schedule
they maintain.

------
pbiggar
[tl;dr: I suspect the Go GC isn't very good]

I'm interested and surprised to see people putting much effort into escape
analysis for stack allocation. The research that came out in the 90s and 00s
pretty much said that if you have a good GC you won't see much benefit to
using EA for stack allocation.

[Disclaimer: All of the below written with the expectation of being wrong
because my knowledge is out of date, my memory is bad, and/or there are
specifics to Go or the implementation which invalidates my points. Still wrote
it cause it might be interesting to others or lead to interesting
conversation]

OK, why do I say that. Well:

\- It's very expensive to do EA well (O(n^3) or O(n^6) where n is the depth of
the call graph). You can do it cheaper in a JIT that has on-stack-replacement
(basically where you make optimistic assumptions and reoptimize if your
assumptions are invalidated)

\- You do get good payoff from stack allocation, in terms of time spent
allocating and deallocating memory.

\- The real payoff from EA is to allow synchronization removal in Java (which
shouldnt matter for Go).

\- Stack allocation provides cheap allocation (don't need a malloc, you can
just do an alloca, which is a cheap add operation), but a good copying GC
provides bump allocation which is better.

\- Stack allocation provides cheap deallocation, but not as cheap as a
generational GC which can clear the young generation for very very cheap.

\- Stack allocation also extends object lifetimes, which is bad.

\- Stack allocation also allows you to move object fields into variables which
can get values out of memory and into registers, which is good.

\- Stack allocation also has worse locality than a good GC (a copying
collector has amazing locality, putting things on the stack doesn't
necessarily).

So all this, plus the details in the doc, imply that the Go GC isn't very
good. If it were good, it would have better allocation performance than you
would get from stack allocation, and the only thing left would be that the
benefit from moving values into fields outweighs the costs.

I don't know anything about Go, so this may not be possible, but as a total
bystander with no info at all, I'd say don't work on optimizing EA and instead
focus on improving the GC.

[disclaimer: please reread disclaimer above]

~~~
voidlogic
>I'm interested and surprised to see people putting much effort into escape
analysis for stack allocation. The research that came out in the 90s and 00s
pretty much said that if you have a good GC you won't see much benefit to
using EA for stack allocation.

Garbage never generated is garbage never collected. Large enterprise Java apps
often still have GC issues despite very advanced GCs to choose from. Also Go's
GC is maturing slower than its escape analysis and its object pool
(sync.Pool). Go is younger so its GC is weak compared to Java- but it does a
good job using the stack and offers a state of the art object pool with thread
local caching.

>It's very expensive to do EA well (O(n^3) or O(n^6) where n is the depth of
the call graph). You can do it cheaper in a JIT that has on-stack-replacement

Isn't this apples to oranges since one of these is a compile time expense and
the other is a run time expense?

~~~
coldtea
> _Go is younger so its GC is weak compared to Java_

I see this often repeated, and it's false.

Go's GC is indeed younger compared to Java, but Go being younger doesn't have
anything to do with it.

It's not like GC's "mature" and get better with time organically. They mature
and get better with the effort put into them, which is different than time.

You can have a GC besting an older language's GC in a language that has 1/10
the years the old one has.

~~~
enneff
Yes, it's not true that software magically gets better with age, but we now
have a small team of experts working on the Go runtime, so we expect the GC to
improve dramatically this year.

We didn't have those people before, and one reason for that is that the
project was smaller then.

------
voidlogic
The author, Dmitry, had a recent escape analysis fix related to maps with
impressive results:

[https://go.googlesource.com/go/+/b3be360f16c44d21b2594d06e8d...](https://go.googlesource.com/go/+/b3be360f16c44d21b2594d06e8d0e609e8fe3c0c)

------
twotwotwo
Fixing the "dot-dot-dot arguments always escape" issue could in particular
mean that logging code no longer risks making things escape even when it
doesn't run:

[http://stackoverflow.com/questions/27788813/variadic-
functio...](http://stackoverflow.com/questions/27788813/variadic-functions-
causing-unnecessary-heap-allocations-in-go)

...which would be cool.

------
tunesmith
I keep on clicking on these Go headlines thinking they are about the board
game. :-( I thought this was about flaws in a computer-go algorithm.

~~~
chc
Given the relative frequency of topics on HN, that seems like a strange
assumption.

~~~
protopete
Still, s/Go/Golang/ would help clear up any confusion.

~~~
chc
So would /s/Go/Gogame/, but I think you'd agree that's a pretty silly
suggestion.

