The Go runtime is really starting to look sexy. 20 ms GC pauses on 200+ GB heaps!
I remember a thread discussing a pauseless GC on the dev mailing-list; where Gil Tene, of Azul C4's fame, commented on having a clear policy on safepoints from the beginning was paramount to having a good GC. It looked like the community is very biased towards doing the fundamental things well, and attracting the right people.
You have to be very careful about these sorts of GC statistics. Things are often not quite what they seem and they depend a lot on the type of app you run.
The first thing to be aware of is that with modern collectors (I have no idea how modern Go's new collector is though), GC pause time depends on how much live data there is in the young generation. So you can easily have enormous heaps with very low pause times if all your objects die young and hardly ever make it into the old generations, because then you never really need to collect the rest of the heap at all.
Of course, outside of synthetic benchmarks, many apps don't show such pleasant behaviour, and often GC algorithms face difficult tradeoffs that are only really knowable by the developers. For instance, do you want low pause times, or less CPU used by the collector (higher throughput)? It turns out that's a fundamental tradeoff and the right answer usually depends whether your app is a user facing server (needs low pause times) or a batch job (better to pause for long periods but complete faster). No runtime can know that, which is why the JVM has tons of tuning knobs. Left to its own devices you can theoretically get away with only tweaking a single knob which is target pause time (in G1). Set it lower and CPU usage of the collector goes up but it'll try and pause for less time. Set it higher and the collector gets more efficient.
Or you can just buy Zing and get rid of GC pauses entirely.
So a stat by itself like "20ms GC pauses on 200GB heaps" doesn't mean much by itself. You can get very low pause times with huge heaps out of the JVM as well:
At work (Lytics) 100% of our backend code has been in Go since the beginning over 3 years ago, so slide #6 highlights one of the most things with nearly every Go release:
We generally get our entire stack upgraded to the latest release within 1-3 months with little effort. It wouldn't be much more work to be ready to upgrade on release day, but we haven't found a reason to worry about it.
Go is such a breath of fresh air compared to past Java and Python jobs where production was usually at least a major release version behind the latest and there was extra effort spent getting everyone using the same implementation (Oracle Java v OpenJDK or Ubuntu's Python v CentOS's -- there are differences!).
Conservative releases aren't a must-have for a language, but I do appreciate having one less operational headache to consider.
> Conservative releases aren't a must-have for a language, but I do appreciate having one less operational headache to consider.
Considering the nature of the work, the programming field seems to be particularly rife with "common wisdom" that's not supported by data. This especially goes towards language design. (In the Chris Granger talk that was recently posted here, he noted that programmers who said they "never" used the mouse, only the keyboard, actually used the mouse 50% of the time.)
The reality of the programming field is that it's "almost a field" [1] -- struggling just as much with empiricism as alchemy was before it evolved into the science of chemistry. Language features definitely suffer from the irrationality of the almost-a-field of programming.
Golang seems to be led by good empiricists who are targeting a specific set of use cases for programming in the large.
Can you speak to why you were behind latest on the JVM? I can think of less than a handful of breaking changes over the last 15 years. I'd say it was more stable than Go.
This is my experience as well. The only thing that somewhat breaks between Go project is vendoring (or lack thereof). But in comparison to the pain of supporting python applications that must run on everything from 2.6.6 to 3.5, Go is a walk in the park.
The concurrent map access checks in Go1.6rc1 have already uncovered one such bug in my code. Love it!
Oh, and I've already made use of the whitespace-stripping in text templates, too! :)
One thing I was worried about from the focus on reducing maximum GC pause times (i.e. latency) was that this might negatively affect GC throughput. For example, maybe the pauses are shorter but there are many more of them. The project I'm working on at the moment exercises the GC heavily but is not concerned with latency (it's bulk data-processing), and I didn't see any significant regression in performance/throughput from 1.5 to 1.6rc1. So, yay.
Aggressive GC latency improvements, like the ones Go is making, virtually always negatively affect throughput. For example, Azul C4 has lower throughput than HotSpot (at least per the numbers cited in the paper). There's no free lunch in GC.
A Golang beginner's question: do these GC improvements make Golang a suitable language/ platform for writing games?
EDIT: I realise this is a vague question. I suppose I was wondering if the order of magnitude GC performance in Go is likely to interfere with game loops you might find in reasonably CPU/ GPU intensive Indie games (i.e. NOT Crysis).
You have to ensure that the GC never makes you drop a frame. For 60Hz, that means staying below 16.7ms.
Given that a Go 1.6 GC will still take about 4ms, you have 12.7ms to generate a frame, which can be too limiting for some CPU-intensive games, but is perfectly acceptable for many games.
(In Go 1.5, a GC was much more likely to make you drop a frame, as it could easily average 40ms.)
On the other hand, there are less high-quality libraries in Go than in C++ or in JS. That may be the most limiting factor.
It all depends on which games people intend to write.
Apparently younger generations are unaware that C was seen as a managed language in the 80's and early 90's, with compilers not generating good enough code for game development.
In the 90's I have seen lots of Turbo Pascal and C code where the functions where plain wrappers for inline Assembly.
So unless you intend to write Crysis in Go, there are lots of games you can write with it.
Lots of neat and profitable games have been made in slower languages, so you should be fine, though in some cases you might have to replicate an entire engine... Not being real familiar with Go, the thing you'll want to look out for if your game gets "big" is unpredictable GC events, more-so even than the absolute max duration of any particular GC event. If Go (or whatever else) doesn't provide enough tuning to support "soft" realtime systems, you'll end up structuring your program to allocate in pools and release all references only at certain points to try and make the GC predictable, which is a common pattern for non-GC languages in games, so you've all but lost the let-me-not-care-about-memory-management justification for the language except for the safety aspects, which don't tend to be high priority for games...
It's a voxel game based on OpenGL. It implements much of vanilla minecraft. Annecdotally, I'd say it performs much better for me than minecraft itself does, at longer view distances, and with essentially no observable GC pauses (of which minecraft suffers quite visibly). Also, a stabler heap size, etc.
The capabilities are definitely there.
I'm spending some of my weekend moments playing around with more GL stuff based on what I've learned from reading this project, and it's quite fun. Build times are right up there where you'd expect, too -- seconds or less! (The first build takes a few moments for running gcc for the c bindings to GL, but after that, those cache nicely.) A 1-second turnaround for recompiling a whole game is an incredible breath of fresh air.
And of course, I shipped my demo game to a friend on a mac the same day I started writing. I'm on a linux. Not bad.
To be honest, for 60fps, and now with VR - 120fps and more - it won't be good enough. But... I could be wrong... Lots of games do have additional scripting languages (.gsc in COD games, lua in others, etc., etc.) - these all have garbage collectors. The key to control that is checking your high watermarks (while playing the level), and doing incremental GC.
Whether you can write the whole game in it - I don't know, but it'll be pretty good for tools/editors/pipeline/etc.
yes and no, while the previous GC pauses wouldn't have really affected anything the size of a hobby game, the improvements are welcome. The bigger problem with Go regarding game development is operator overloading and interfacing with C, the latter being a pain when it comes to memory management.
Found a blog post by Joel Webber, who I have not heard of, but he was working on a minecraft clone and had some advice on avoiding GC and memory layout:
Nim (http://nim-lang.org), is a language in some ways filling a similar niche to Go and they are suitable for games, because you can tune or even change the GC. Not the case with Go, so may be less suitable for soft real-time like games.
It should be suitable - but whether it is depends also on your memory usage. GCs are not black boxes which magically work or not work. They do get bad reputation by people who do heap allocations without thinking about them.
They key to good GC performance is about the allocation profile. GO gives you very good control about heap allocation, so it should be possible to arrange the main game loop such that no fresh heap is allocated, which also would mean that the GC does not run. The GO GC runs when, the allocated heap grow to a set multiple (by default 2x) of the heap size after the last GC run. Adjusting this factor to your memory usage should give you pretty good control when the GC runs and when not.
There are a heck of a lot games written in C#, which is not only interpreted, but probably has a less-tuned GC. Including heavy-processors like Kerbal Space Program.
If KSP works in C#, you can write a game in Go no problem.
Their solution to the template whitespace thing underlines a fundamental difference between what the Go core developers consider to be good language/library design and what I do.
To me adding the - to the template tag {{foo -}} to get rid of whitespace on that side of the tag is totally unintuitive and a really kludgy solution. Sure, it's terse and being terse can be nice, but terseness to me probably doesn't even make it into my top 10 concerns when designing a language or library.
In my mind a lot more thought and consideration should be put into solutions for problems that are going into core libraries. Stuffing cute hacks into the core libraries willy nilly leads you to PHP. The consequences of which I deal with daily.
JVM's gc is most likely significantly better. On the other hand golang's gc needs to collect less objects, in some cases orders of magnitude less.
If you compare a slice of structs with 1000 elements, it'll be one object (and allocation) in golang. Equivalent array in JVM requires the array itself + 1000 Objects, 1001 allocations. In this case, golang has lot less object graph to gc.
Of course slice of 1000 interfaces or pointers faces the same 1001 issue in golang as well.
You could emulate same gc load cost in JVM at cost of runtime performance by storing the objects in a byte array and [de]serialize as needed, but that's neither idiomatic or acceptable solution most of the time.
In terms of what? Latency? I think Go is down to something like 10ms, and from what I understand, pressure on the GC can be relieved by using things such as `sync.Pool`.
I develop a lot of command line tools for Linux using shell scripting. The scripts are getting huge and ugly, so I have been looking at Go and it seems I can do so many things by just using the standard library and in general a big improvement over using scripting.
However, everytime Go is discussed at HN I see many posts criticizing the language for various reasons and this has put me off getting started learning Go.
Programming languages are kind of like religion, or one's favorite beverage/food. Everyone has their own preference/coding style. I wouldn't let negative comments on HN steer you away from learning Go. Of course, I'm biased because I write Go code and enjoy it, but there will always be folks who love something and hate something. You'll never know whether you enjoy coding in Go unless you try it for yourself.
Some of the criticisms of Go are valid and some are just haters doing what haters do--hating. Keep in mind Go is very young for a programming language. It's only about 6 years old, but it's use is becoming more and more widespread as it matures.
Although you are correct in that the standard library is pretty much all you need to write CLI apps, this library is definitely useful if you're willing to pull in a third-party dependency: https://github.com/codegangsta/cli
Definitely take a look at Go. If criticism on HN is what you're concerned about, I can tell you that when I started writing Go ~3 years ago it got a lot more criticism on HN than it does now. I've used it as my primary language since then and it's a fun language.
I'm doing much the same as you. command line tools for linux, windows and os x and really like go for that use case. the incredibly easy distribution of the final tools make life awesomely easy.
I'll never use Go personally myself, but criticisms on a forum are a bad reason for not using a language, if you think it will be a good tool (as you seem to do) for your purposes
[+] [-] BenoitP|10 years ago|reply
I remember a thread discussing a pauseless GC on the dev mailing-list; where Gil Tene, of Azul C4's fame, commented on having a clear policy on safepoints from the beginning was paramount to having a good GC. It looked like the community is very biased towards doing the fundamental things well, and attracting the right people.
And on top of that we're get BLAS and LAPACK bindings from https://github.com/gonum
[+] [-] mike_hearn|10 years ago|reply
The first thing to be aware of is that with modern collectors (I have no idea how modern Go's new collector is though), GC pause time depends on how much live data there is in the young generation. So you can easily have enormous heaps with very low pause times if all your objects die young and hardly ever make it into the old generations, because then you never really need to collect the rest of the heap at all.
Of course, outside of synthetic benchmarks, many apps don't show such pleasant behaviour, and often GC algorithms face difficult tradeoffs that are only really knowable by the developers. For instance, do you want low pause times, or less CPU used by the collector (higher throughput)? It turns out that's a fundamental tradeoff and the right answer usually depends whether your app is a user facing server (needs low pause times) or a batch job (better to pause for long periods but complete faster). No runtime can know that, which is why the JVM has tons of tuning knobs. Left to its own devices you can theoretically get away with only tweaking a single knob which is target pause time (in G1). Set it lower and CPU usage of the collector goes up but it'll try and pause for less time. Set it higher and the collector gets more efficient.
Or you can just buy Zing and get rid of GC pauses entirely.
So a stat by itself like "20ms GC pauses on 200GB heaps" doesn't mean much by itself. You can get very low pause times with huge heaps out of the JVM as well:
but of course, you have to pay the piper somehow ... assuming non-weird heap usage the program will run slower overall.[+] [-] rhodysurf|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] amelius|10 years ago|reply
[+] [-] schmichael|10 years ago|reply
> Changes to the language: None
https://talks.golang.org/2016/state-of-go.slide#6
We generally get our entire stack upgraded to the latest release within 1-3 months with little effort. It wouldn't be much more work to be ready to upgrade on release day, but we haven't found a reason to worry about it.
Go is such a breath of fresh air compared to past Java and Python jobs where production was usually at least a major release version behind the latest and there was extra effort spent getting everyone using the same implementation (Oracle Java v OpenJDK or Ubuntu's Python v CentOS's -- there are differences!).
Conservative releases aren't a must-have for a language, but I do appreciate having one less operational headache to consider.
[+] [-] stcredzero|10 years ago|reply
Considering the nature of the work, the programming field seems to be particularly rife with "common wisdom" that's not supported by data. This especially goes towards language design. (In the Chris Granger talk that was recently posted here, he noted that programmers who said they "never" used the mouse, only the keyboard, actually used the mouse 50% of the time.)
The reality of the programming field is that it's "almost a field" [1] -- struggling just as much with empiricism as alchemy was before it evolved into the science of chemistry. Language features definitely suffer from the irrationality of the almost-a-field of programming.
Golang seems to be led by good empiricists who are targeting a specific set of use cases for programming in the large.
[+] [-] kasey_junk|10 years ago|reply
[+] [-] jvehent|10 years ago|reply
[+] [-] dantillberg|10 years ago|reply
Oh, and I've already made use of the whitespace-stripping in text templates, too! :)
One thing I was worried about from the focus on reducing maximum GC pause times (i.e. latency) was that this might negatively affect GC throughput. For example, maybe the pauses are shorter but there are many more of them. The project I'm working on at the moment exercises the GC heavily but is not concerned with latency (it's bulk data-processing), and I didn't see any significant regression in performance/throughput from 1.5 to 1.6rc1. So, yay.
[+] [-] pcwalton|10 years ago|reply
[+] [-] zellyn|10 years ago|reply
[+] [-] mwsherman|10 years ago|reply
[+] [-] martijn_himself|10 years ago|reply
EDIT: I realise this is a vague question. I suppose I was wondering if the order of magnitude GC performance in Go is likely to interfere with game loops you might find in reasonably CPU/ GPU intensive Indie games (i.e. NOT Crysis).
[+] [-] espadrine|10 years ago|reply
Given that a Go 1.6 GC will still take about 4ms, you have 12.7ms to generate a frame, which can be too limiting for some CPU-intensive games, but is perfectly acceptable for many games.
(In Go 1.5, a GC was much more likely to make you drop a frame, as it could easily average 40ms.)
On the other hand, there are less high-quality libraries in Go than in C++ or in JS. That may be the most limiting factor.
[+] [-] pjmlp|10 years ago|reply
Apparently younger generations are unaware that C was seen as a managed language in the 80's and early 90's, with compilers not generating good enough code for game development.
In the 90's I have seen lots of Turbo Pascal and C code where the functions where plain wrappers for inline Assembly.
So unless you intend to write Crysis in Go, there are lots of games you can write with it.
[+] [-] Jach|10 years ago|reply
[+] [-] heavenlyhash|10 years ago|reply
It's a voxel game based on OpenGL. It implements much of vanilla minecraft. Annecdotally, I'd say it performs much better for me than minecraft itself does, at longer view distances, and with essentially no observable GC pauses (of which minecraft suffers quite visibly). Also, a stabler heap size, etc.
The capabilities are definitely there.
I'm spending some of my weekend moments playing around with more GL stuff based on what I've learned from reading this project, and it's quite fun. Build times are right up there where you'd expect, too -- seconds or less! (The first build takes a few moments for running gcc for the c bindings to GL, but after that, those cache nicely.) A 1-second turnaround for recompiling a whole game is an incredible breath of fresh air.
And of course, I shipped my demo game to a friend on a mac the same day I started writing. I'm on a linux. Not bad.
[+] [-] omginternets|10 years ago|reply
[+] [-] malkia|10 years ago|reply
Whether you can write the whole game in it - I don't know, but it'll be pretty good for tools/editors/pipeline/etc.
[+] [-] panamafrank|10 years ago|reply
[+] [-] tossableacct11|10 years ago|reply
Found a blog post by Joel Webber, who I have not heard of, but he was working on a minecraft clone and had some advice on avoiding GC and memory layout:
http://www.j15r.com/blog/2015/01/25/Game_Development_in_Go
Also found an engine, Azul 3D, and they made this claim:
https://azul3d.org/doc/faq.html#what-about-the-garbage-colle...
Then there is termloop, which is a terminal based engine:
https://github.com/JoelOtter/termloop
Fun for indie game stuff.
So, yeah. There's that.
[+] [-] AsyncAwait|10 years ago|reply
[+] [-] _ph_|10 years ago|reply
[+] [-] benchin|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] blakeyrat|10 years ago|reply
If KSP works in C#, you can write a game in Go no problem.
[+] [-] ebbv|10 years ago|reply
To me adding the - to the template tag {{foo -}} to get rid of whitespace on that side of the tag is totally unintuitive and a really kludgy solution. Sure, it's terse and being terse can be nice, but terseness to me probably doesn't even make it into my top 10 concerns when designing a language or library.
In my mind a lot more thought and consideration should be put into solutions for problems that are going into core libraries. Stuffing cute hacks into the core libraries willy nilly leads you to PHP. The consequences of which I deal with daily.
[+] [-] siscia|10 years ago|reply
[+] [-] vardump|10 years ago|reply
If you compare a slice of structs with 1000 elements, it'll be one object (and allocation) in golang. Equivalent array in JVM requires the array itself + 1000 Objects, 1001 allocations. In this case, golang has lot less object graph to gc.
Of course slice of 1000 interfaces or pointers faces the same 1001 issue in golang as well.
You could emulate same gc load cost in JVM at cost of runtime performance by storing the objects in a byte array and [de]serialize as needed, but that's neither idiomatic or acceptable solution most of the time.
[+] [-] omginternets|10 years ago|reply
[+] [-] mrweasel|10 years ago|reply
This seems like a bit of a hack to be honest. Would anything break if
{{range .}}
{{end}}worked as expected?
[+] [-] woofiefa|10 years ago|reply
However, everytime Go is discussed at HN I see many posts criticizing the language for various reasons and this has put me off getting started learning Go.
[+] [-] tshannon|10 years ago|reply
A lot of the criticisms turned me off as well, but I dove in anyway.
I stopped paying attention to the criticisms when I found out how incredibly productive I was able to be in Go.
Give it a try and make your own call on it. The cognitive overhead of jumping into Go is so small compared to many other languages.
[+] [-] travjones|10 years ago|reply
Some of the criticisms of Go are valid and some are just haters doing what haters do--hating. Keep in mind Go is very young for a programming language. It's only about 6 years old, but it's use is becoming more and more widespread as it matures.
Although you are correct in that the standard library is pretty much all you need to write CLI apps, this library is definitely useful if you're willing to pull in a third-party dependency: https://github.com/codegangsta/cli
[+] [-] shawnps|10 years ago|reply
[+] [-] tacticus|10 years ago|reply
[+] [-] plinkplonk|10 years ago|reply
[+] [-] kasey_junk|10 years ago|reply
I'm wondering how it holds up without compaction and in the face of fragmented heaps.
[+] [-] BuckRogers|10 years ago|reply
Best part of Golang, more languages need to borrow this feature. Second best is how relatively easy it is to get going with it.
[+] [-] oliv__|10 years ago|reply
[+] [-] ilya1|10 years ago|reply
Noticed couple e-commerce companies and Google itself in Singapore. Few Russian companies are doing small infra project.
Anyone else seriously investing in Golang?
[+] [-] GreaterFool|10 years ago|reply
I refuse to touch Go until that happens. Go is the asshole of programming languages. It forces you to put code in deeply nested annoying directories
But that I could live with. But constantly commenting the code out (which of course leads to commenting out even more code!) is the real PITA.All said and done it looks like a useful, if uninspired, language. Can avoid it so may as well use it. But this nonsense has to stop!
[+] [-] bshanks|10 years ago|reply
[+] [-] trungonnews|10 years ago|reply
[+] [-] Eric_WVGG|10 years ago|reply
[+] [-] armitron|10 years ago|reply
[deleted]
[+] [-] FenugreekAcerb|10 years ago|reply
[deleted]
[+] [-] jibalt|10 years ago|reply
[+] [-] deskamess|10 years ago|reply
- The header is cut off
- Slide 20 gives an error when running [c: template: redefinition of template "list"]
- Stable sort example does not seem to work. Gives same output as regular sort