Jump to content
  • Advertisement
Sign in to follow this  
Nairou

Go language use in performance-critical code

This topic is 2015 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Coming from a C/C++ perspective, Go looks like a really nice language. I would really like to try it out. I'm curious though if anyone has considered it for game development?

Other than a lack of library support (which will improve over time), my main concern with the language is how it handles memory management. It has a GC, and appears to have a lot of dynamic data types. I can only assume that this means it will be doing memory allocation at runtime. At least, that's what a C/C++ program would be doing. It is possible that Go is structured differently internally to allow seeming-dynamic features within a fixed memory allocation. But I don't know, and so hesitate to try it in performance-critical code, like games.

Does anyone have any insight into how Go handles memory management? Has anyone experimented with Go in performance-critical code and have feedback on how it performed?

Share this post


Link to post
Share on other sites
Advertisement
Ya I am playing with it in my spare time... it's by far my favorite language.
I don't understand what you mean for "dynamic types".. Go has no dynamic types, it's a very simple language statically typed... actually it is very strict about types, requiring explicit casts everywhere. Maybe you are confused by interfaces and duck typing.. but those aren't strictly "dynamic" features... most of them are evaluated at compile time.
Memory management is not very different from C like languages, so, from a performance point of view, the same rules are valid.. avoid creating things on the heap if you can... that's about it... the best way to optimize on a GC is to avoid triggering it.

Performance wise, from my tests on Windows (game oriented stuff like graph traversals and basic math) is in the same ballpark with C# using the standard go compiler. On Linux you can use the gccgo compiler built over the gcc complier and that's pretty damn fast... and runtime performances are only going to get better due the nature of the language.

For gamedev, Go is severely limited in expressing elegant math code.. it doesn't have operator overloading nor function overloading.. thus you're back writing things like:

result := mymath.AddFloat3(&v1 , &v2)

Instead of:

auto result=v1 +v2;

Things get worse with complex formulas:

auto new_pos=pos+vel * dt + (acc * 0.5f * dt *dt);

You'd have to break that down in go operation by operation if pos, vel and acc are vectors.

This gets really annoying when you write math intensive code... but you get lots of good stuff from the language such as goroutines and channels, so it's the goods and the bads are balancing out. Edited by kunos

Share this post


Link to post
Share on other sites

I don't understand what you mean for "dynamic types".. Go has no dynamic types, it's a very simple language statically typed... actually it is very strict about types, requiring explicit casts everywhere. Maybe you are confused by interfaces and duck typing.. but those aren't strictly "dynamic" features... most of them are evaluated at compile time.

What I mean is, things like strings and maps, which are variable in size. They don't have a fixed memory footprint at compile time.


Memory management is not very different from C like languages, so, from a performance point of view, the same rules are valid.. avoid creating things on the heap if you can... that's about it... the best way to optimize on a GC is to avoid triggering it.

I guess part of my question is wondering how you avoid it. I haven't read much on how Go handles it's memory management, and it seems a lot less transparent than it was in C/C++.

In C++, if you avoid malloc() and new, and don't use objects which are known to do runtime allocation, then you're good. With Go, I don't know what that set is. As great as Go looks, I'm curious how much of the language you have to avoid using if you want to keep tight control over what memory allocation occurs. There is probably a document out there somewhere that talks about this, but I haven't seen it.


Performance wise, from my tests on Windows (game oriented stuff like graph traversals and basic math) is in the same ballpark with C# using the standard go compiler. On Linux you can use the gccgo compiler built over the gcc complier and that's pretty damn fast... and runtime performances are only going to get better due the nature of the language.

Do you mean that gccgo compiles really fast, or that the resulting code is much faster than the standard go compiler? Do you have (or know of) any benchmarks?


For gamedev, Go is severely limited in expressing elegant math code.. it doesn't have operator overloading nor function overloading..

Good to know! I hadn't considered that bit. But definitely worth considerign still, given all of the other language benefits.

Share this post


Link to post
Share on other sites

What I mean is, things like strings and maps, which are variable in size. They don't have a fixed memory footprint at compile time.


Unlike C++, which uses no strings or maps or variable size structures in non-trivial programs...

Share this post


Link to post
Share on other sites
[quote=http://www.ferrousmoon.com/forums/viewtopic.php?p=14287#p14287]
With today's release of Go, I thought I would write a version of GenPrime for it, one because I wanted to see if it was really as speedy as it says and two to practice this new language.
First, the C version as a comparison:
Code:
eddie@ganglion:~/dev/genprime$ ./genprime-c 250000 1000000
Found 250000 primes in 5.75923 seconds (last was 3497861)
Found 500000 primes in 16.15777 seconds (last was 7368787)
Found 750000 primes in 29.94442 seconds (last was 11381621)
Found 1000000 primes in 46.37428 seconds (last was 15485863)
Now for Go:
Code:
eddie@ganglion:~/dev/genprime$ ./genprime-go 250000 1000000
Found 250000 primes in 4.253223 seconds (last was 3497861)
Found 500000 primes in 12.105688 seconds (last was 7368787)
Found 750000 primes in 22.779920 seconds (last was 11381621)
Found 1000000 primes in 34.426428 seconds (last was 15485863)

I compiled the Go version with the Plan 9 compiler (6g). Apparently there is a GCC port that is reported to produced more optimized code in some cases, so if anyone wants to test this code with the GCC port I'd be interested to see the results.
I'll be committing my code to my GitHub fork of GenPrime.[/quote]

So not lagging too far behind plain C in that particular test case.

I can't recall where but I vaguely remember finding a .pdf with a few more test cases with very similar results.

There is also this page I found but I don't really know whats going on here: http://golang.org/test/bench/shootout/

Share this post


Link to post
Share on other sites

[quote name='Nairou' timestamp='1354990643' post='5008549']
What I mean is, things like strings and maps, which are variable in size. They don't have a fixed memory footprint at compile time.


Unlike C++, which uses no strings or maps or variable size structures in non-trivial programs...
[/quote]In case anyone hadn't picked up on this, the above was clearly sarcasm.


Also, GC is not a memory leak panacea. Our newer client software at work which is written in C#, "leaks" far worse than the older C++ client.

Share this post


Link to post
Share on other sites

[quote name='Nairou' timestamp='1354990643' post='5008549']
What I mean is, things like strings and maps, which are variable in size. They don't have a fixed memory footprint at compile time.

Unlike C++, which uses no strings or maps or variable size structures in non-trivial programs...
[/quote]
Well in C++ those are just part of STL, not build into the language. You can choose to use a std::string, or you can just use a char array. You aren't forced to use a string, because it isn't actually part of the language. In Go, you just have a string, and it's a part of the language, so they expect you to use it. Which is fine, I just want to understand what's going on behind the scenes.


Also, GC is not a memory leak panacea. Our newer client software at work which is written in C#, "leaks" far worse than the older C++ client.

Exactly. I have more memory leaks in my C# applications than I do in my C++ applications. I want to have some level of control over memory management, especially in a game. I just don't know enough about Go yet to know if it gives that level of control.

Share this post


Link to post
Share on other sites
Sorry, the STL hasn't been around for years. The C++ standard library is part of the language, and that includes strings.

To be explicit, you need not worry about those things in go for performance concerns. Frankly, it sounds as though you worry about using them due to performance in C++, which is absurd.

Share this post


Link to post
Share on other sites

Do you mean that gccgo compiles really fast, or that the resulting code is much faster than the standard go compiler? Do you have (or know of) any benchmarks?


gccgo compile times are not as fast as the standard go compiler but still way faster than C++ code. I was refering to runtime performances where gccgo is surprisingly fast.

I don't understand your obsession with dynamic memory. Every language needs it. Strings, maps, vectors in C++ are all implemented with dynamic memory behind the scenes. Go doesn't move stuff into dynamic memory behind your back. So you know that callig "new" will be a dynamic allocation, calling make will be a dynamic allocation, returing the address of a stack created object will be a dinamic allocation.. and operations like "append" or adds to a map might be dynamic allocs... this is all EXACTLY what you get in every other language.

Share this post


Link to post
Share on other sites
I work with Go on a daily basis, but never in game development. I've never done any benchmarking but it's definitely performant enough for any web server (Google does use it for production web servers) and the amazingly speedy compile time alone is enough to make up for any minor performance downfalls IMO.

To comment on your specific question about string vs char[], you can have fixed-size byte arrays in Go and cast between them and strings. In general I find Go a great language, but the libraries for it are still very immature.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!