3 ms·
Exactly, gc pauses kind of bugging me in a lot of games based on .net, like Kerbal
by szundi 4y ago
Exactly, gc pauses kind of bugging me in a lot of games based on .net, like Kerbal
- kevingadd 4y agoGenerally speaking if a .NET game has GC pauses, it's probably because they didn't try. You can represent most game state using structs and arrays without significant ergonomics problems, and your GCs for the classes you do heap allocate will be much shorter if you design your data structures to be quick to trace. Things were different for Unity games using the Boehm collector though, since it's a conservative non-generational collector that as a result is very slow to collect and collects more frequently. That's why you saw a lot of frequent pauses in Unity games (my understanding is they no longer use Boehm). The game I'm currently working on GCs maybe 1-2 times per minute and the pauses are short enough that it doesn't drop frames, despite the fact that it frequently allocates strings and uses 'async Task' extensively. If you tune the collector settings you can control this even more, and you also have the option to manually force GCs to happen while the game is waiting for vsync, which hides them further. Visual Studio has a built in allocation profiler that can help if you're looking to optimize your games for fewer GCs, and to make tracing faster what you want to do is avoid having any reference types in your struct arrays (use handles instead), which will let the GC skip tracing your big arrays of structs entirely. So for example the big tables of draw calls I use refer to textures by numeric handle instead of reference, which means I can have a 50mb table without making GCs slower. Using handles instead of references also means that copying the struct doesn't require write barriers, which will boost your overall perf a bit.
- pjmlp 4y agoNot all .NET games are made equal. First of all, there is the runtime they are actually using. Then the language version. Finally, how well the devs know how to do low level optimisations.
- omnicognate 4y agoUnfortunately you mostly don't do low-level optimisations in C#. You can manipulate raw memory but unsafe C# is horrifyingly unsafe - far more dangerous than writing C - and code written with it has to navigate a minefield to interact safely with ordinary C#. Instead, heavy optimisation in C# is usually "high level but knowing the runtime in great detail" optimisation. Stuff like knowing the hairy details of the GC implementation (eg by reading Pro .NET Memory Management and/or the single 30,000 line C++ file that contains the GC implementation [1]) and using this knowledge to write ordinary C# code in such a way that the GC can handle its usage patterns very efficiently, or doing things like object pooling that try to cut the GC out of the picture altogether. Essentially, it's knowing what you want the machine to do and figuring out a way to trick the runtime into doing that instead of what it wants to do. I find it massively frustrating and after doing it for a few years I moved back to languages that try to do what you tell them to do instead of the other way round. Some people seem to thrive on it, though, and manage to get impressive results - see, eg. Marc Gravell's blog. [1] https://github.com/dotnet/runtime/blob/main/src/coreclr/gc/gc.cpp?raw=true https://github.com/dotnet/runtime/blob/main/src/coreclr/gc/g...
- bob1029 4y agoI agree that understanding how the GC was built is very important. Little nuances like forcing workstation mode and explicitly calling GC.Collect can make all the difference. You can get very far with a GC language like this. The part that bothers me are the built-ins that allocate. TPL, AspNetCore, et. al. If I want a truly zero-alloc C# solution, I have to go all the way to the bottom with abstractions like Socket, NetworkStream, SslStream, etc.
- pjmlp 4y agoI advise to update yourself what using C#11 offers in possibilities beyond only unsafe code blocks. Based on my C and C++ years, it is hardly any difference from doing optimization, knowing what the compiler actually generates, how is the runtime and standard library actually implemented, and above all getting to use the proper data structures, algorithms and a profiler.
- omnicognate 4y agoNah, I'm not going back to C# and don't plan to stay up to date with it. If you're talking about ref structs, Spans etc, I'm perfectly aware and have used those features in anger (in more ways than one). It clearly suits some people but it isn't for me.
- pjmlp 4y agoFine, however better focus on good game design and not what language to use, see Minecraft, Stardew Valley, Celeste, Bastion,.... Anyone that disregards languages used by them, should also have better sales numbers to go along.
- adjav 4y ago> Stardew Valley, Celeste, Bastion Those are all games where the average frame time is so low GC pauses are basically irrelevant. And Minecraft was re-written in C++ for a reason.