4 ms·
Note that in addition to the CPU overheads, the paper notes that Go's heap requires a factor of 2 to 3 of headroom to run efficiently: > A potential proble
by haberman 6y ago
Note that in addition to the CPU overheads, the paper notes that Go's heap requires a factor of 2 to 3 of headroom to run efficiently:
> A potential problem with garbage collection is that it
> consumes a fraction of CPU time proportional to the
> “headroom ratio” between the amount of live data and
> the amount of RAM allocated to the heap. This section
> explores the effect of headroom on collection cost.
>
> [...]
>
> In summary, while the benchmarks in §8.4 / Figure 7
> incur modest collection costs, a kernel heap with millions of live
> objects but limited heap RAM might spend
> a significant fraction of its time collecting. We expect
> that decisions about how much RAM to buy for busy
> machines would include a small multiple (2 or 3) of the
> expected peak kernel heap live data size.
>
> [...]
>
> If CPU performance is paramount,
> then C is the right answer, since it is faster (§8.4, §8.5).
> If efficient memory use is vital, then C is also the right
> answer: Go’s garbage collector needs a factor of 2 to 3 of
> heap headroom to run efficiently (see §8.6).
- pjmlp 6y agoMatter of implementation. I also read the paper, but I also have read tons of other papers of systems implemented in other languages. While current implementation is quite good, there is lots of room for improvements, including improving the way Go deals with value types. Also with a small improvements to Go (untraced references), or even a //go: annotation, there would be more room for C like data structures, when required to go down that path. Without trying to diminish the work that went into this thesis, speaking from experience, when it was done it was done, performance improvements were most likely not pursued as the point to write an OS in Go as thesis was already proven.
- throwaway34241 6y agoAbout untraced reference support is there something specific that you’re looking for? Although it doesn’t have a special type I’m pretty sure you can have regular Go object references / interfaces / arrays point to non-GC memory if you want (although you’ll have to cast the result from malloc or something similar). So most library functions should work with unmanaged memory OK by default (if they’re using standard slice/array types) which is not too bad as far as GC languages go.
- pjmlp 6y agoIf you have explicit untraced reference support the GC doesn't have to guess and better algorithms can be taken advantage of. Without it, some guessing games might happen that bring everything down, or the GC has to be more conservative regarding its guesses. An example of this are the latest restrictions on Go 1.15 regarding pointer conversions https://golang.org/doc/go1.15#compiler https://golang.org/doc/go1.15#compiler
- throwaway34241 6y agoWouldn’t the GC be able to just stop scanning memory once it encounters an off GC heap pointer (since it knows what address ranges it manages)? I’ve only allocated non-pointer-containing Go objects manually (that presumably wouldn’t be scanned anyway) and it’s hard to find the specifics of how things work, although it seems like there are some libraries that allow it. [1] Since it’s possible to use C data structures and pointers directly from Go that seems like the safest way to do it, although of course then you need a C toolchain installed. [1] https://github.com/teh-cmc/mmm https://github.com/teh-cmc/mmm
- pjmlp 6y agoIt is a bit more complicated than that, hence why conservative GC are pretty bad reclaiming memory, because they need to play safe. One of the reasons why they are changing the pointer rules in Go, was exactly because there are data races across domains if you happen to nest conversions between GC and non-GC pointers, and the GC happens to run just in the moment that it thinks the reference is no longer in use, while actually it was stored temporarily in an uintptr.
- haberman 6y agoSure, if you use less GC, then the penalties of GC are minimized. But that just reinforces the point that GC has a real cost. When you use less GC, you increase performance, but you also get fewer of the safety and convenience benefits of GC. There is no Holy Grail of GC just around the corner that will make this tradeoff obsolete, despite what GC advocates have been telling me for 20 years.
- pjmlp 6y agoLike anti-GC advocates not getting that a GC in a language like D, is only the replacement for new/delete, with everything else that C++ is capable of still available. Learn to use the tools and enlightenment will be achieved.
- musicale 6y agoThis is fairly damning and another data point that indicates that go (and garbage-collected languages/runtimes in general) may be poor successors to C and C++ for applications where consistent performance and memory efficiency are important. I'm sure there are tricks you can do in go (as in java) to subvert the garbage collector, but I'm not sure I'd want to build a kernel based on them when I could just use another language. Another data point is Apple adopting automatic reference counting for objC and Swift. Another is Discord switching from go to Rust ("go did not meet our performance targets.") Potentially an OS kernel written (for example) in a language like Rust (though not without its own challenges) could have more consistent performance and lower memory overhead. disclaimer: I am aware of OS kernels written in Rust but have no experience developing or using one
- pjmlp 6y agoDon't mistake lack of effort in improving performace, with what could be achieved. Were we having this discussion during the 80's, no one would think C was usable for anything serious, when its compilers couldn't produce better code than junior Assembly developers and all AAA games of the time were 100% Assembly.
- higerordermap 6y ago> Potentially an OS kernel written (for example) in a language like Rust (though not without its own challenges) could have more consistent performance and lower memory overhead. Yeah potentially, but implementing in easier language in less time may be acceptable trade-off. Because Go is not poster child of fast GC'd languages either (conscious choice of a simpler optimzer for fast builds), and the implementation only showed 10%-15% difference with linux, the situation is optimistic. With better escape analysis in GC languages and better compilers, the gap can be reduced further. > Apple adopting ARC That's because of legacy interop concerns mainly. Swift's ARC implementation was once horrible, and ARC still seems to be a significant bottleneck in SwiftUI. The ARC more efficient blanket statement myth is mainly spread by apple fanboys, who might not even have heard the words 'cache' and 'contention'. The efficient ARC methods like deferred RC approach a tracing GC. The benefit of RC is predictability (though not always) & RAII. That's why Rust and many C codebases use explicit refcounting when lifetimes are unknown.