Jump to page: 1 28  
Page
Thread overview
Garbage Collection and gamedev - tl;dr Yes we want it, so let's solve it
Nov 22, 2020
Ethan
Nov 23, 2020
rikki cattermole
Nov 23, 2020
aberba
Nov 23, 2020
rikki cattermole
Nov 23, 2020
rikki cattermole
Nov 23, 2020
rikki cattermole
Nov 23, 2020
Jacob Carlborg
Nov 23, 2020
Guillaume Piolat
Nov 23, 2020
Ethan
Nov 22, 2020
Ethan
Nov 23, 2020
Paulo Pinto
Nov 23, 2020
Paulo Pinto
Nov 22, 2020
random
Nov 22, 2020
Ethan
Nov 23, 2020
Paulo Pinto
Nov 23, 2020
RazvanN
Nov 23, 2020
Adam D. Ruppe
Nov 23, 2020
RazvanN
Nov 23, 2020
Adam D. Ruppe
Nov 23, 2020
RazvanN
Nov 25, 2020
ryuukk_
Nov 25, 2020
Paulo Pinto
Nov 25, 2020
Araq
Nov 25, 2020
Araq
Nov 25, 2020
ryuukk_
Nov 25, 2020
Guillaume Piolat
Nov 25, 2020
aberba
Nov 25, 2020
aberba
Nov 25, 2020
Paulo Pinto
Nov 25, 2020
Paulo Pinto
Nov 25, 2020
Paulo Pinto
Nov 25, 2020
Elronnd
Nov 25, 2020
Araq
Nov 26, 2020
ryuukk_
Nov 26, 2020
ryuukk_
Nov 26, 2020
ryuukk_
Nov 27, 2020
rikki cattermole
Nov 27, 2020
Mike Parker
Nov 27, 2020
Paulo Pinto
Nov 27, 2020
Paulo Pinto
Nov 27, 2020
Paulo Pinto
Nov 27, 2020
Guillaume Piolat
Nov 27, 2020
Guillaume Piolat
Nov 27, 2020
Guillaume Piolat
Dec 01, 2020
Paulo Pinto
Dec 09, 2020
Ben Jones
Dec 10, 2020
Paulo Pinto
Nov 22, 2020
jmh530
November 22, 2020
There's many nuanced points to consider here, so given that GC came up on the live Q&A and I got in to a bit of a chat there I figured copy/pasting that log and getting in to a (real, stop-saying-gamedev-doesn't-want-this) longer form discussion about the exact kind of GC we want in game development.

There's a few people in the community here that are involved in console game dev, and they would know the kind of characteristics we require. Similarly, many of the lower level programmers that work with GPUs and the like are well aware that garbage collection is not good enough for releasing resources outside of the main system environment and would know the kind of control we require over deallocation and release paths.

The short form of my view is that we are actively using GC in game dev at all levels. The largest commercial AAA engine has been garbage collecting since the 90s (and go deeper, the original Doom garbage collected). But as we scale up to massively parallel execution across all forms of programming, the monolithic program-halting mark and sweep GC that comes with D is not good enough.

I've not yet sat down to do the full research in to the subject that it demands, but I have ideas on what I want to look at. Conversation copied to below:


TheRealGooberMan
​I want to write a task-based GC, that will handle destruction/deallocation as a task when the last reference to a section of memory is unacquired

FeepingCreature
​is freeing memory that costly in D?

TheRealGooberMan
​The advantage of a collector is that it's a batch process

TheRealGooberMan
​And computers LOVE batch processes

TheRealGooberMan
​But in gamedev, we need a bit more immediate control at times

FeepingCreature
​no I mean, it just feels like you're optimizing the fastest part of the process

FeepingCreature
​ya'll are really sensitive to question marks ending a line 🙂

TheRealGooberMan
​The collector blocks the program currently. That's bad for gamedev

TheRealGooberMan
​And yes, we do have Unreal Engine as the most direct example that does exactly this

TheRealGooberMan
​Anyone saying "gamedev doesn't GC" isn't paying attention

TheRealGooberMan
​We just want a better solution

FeepingCreature
​the collector blocks the program, but it blocks for scanning, and task-based doesn't speed that up, right?

TheRealGooberMan
​No, it's not about speeding it up at that point. It's about not blocking anything else from running

FeepingCreature
​right but mark phase has to block inherently, unless you get really clever with your design or get hardware support

TheRealGooberMan
​This is an extra advantage of the pointer acquire/unacquire runtime hooks that I want. It's a bit more code, but it also negates the need to do any kind of sweep

TheRealGooberMan
​And it is something that should be opt-in, yeah. If your GC doesn't define the hooks, then the code gen shouldn't try to insert them

TheRealGooberMan
​Pay as you go functionality!

FeepingCreature
​I don't know the background of that, but yeah, I don't know how the relative cost of mark and sweep is, if sweep is using a lot of the fraction than speed it up by all means

Lawrence Aberba
​I love GC 🐱‍🏍

FeepingCreature
​😆
November 22, 2020
On Sunday, 22 November 2020 at 14:30:45 UTC, Ethan wrote:
> There's many nuanced points to consider here, so given that GC came up on the live Q&A and I got in to a bit of a chat there I figured copy/pasting that log and getting in to a (real, stop-saying-gamedev-doesn't-want-this) longer form discussion about the exact kind of GC we want in game development.

You cannot have incremental collection as that requires barriers and there is no way in D to tell whether you should or should not emit costly barriers statically during code gen. D would need to add an actor concept to get there.

So that means there are only three options left: single threaded GC pool, non-language GC or ARC.


November 22, 2020
On Sunday, 22 November 2020 at 14:30:45 UTC, Ethan wrote:
> ...longer form discussion about the exact kind of GC we want in game development...

So chatting with Atila on beerconf. The conversation that comes up, apart from this needing to be a DIP, is that I need to fill out some of the ideas that I have here.

One of the things I mentioned is that I don't get why library solutions are pursued for handling memory allocations/garbage collecting when the runtime already exists and can be used for the same purpose. This led to highlighting that the runtime should be more templatised anyway so that it can get that deeper knowledge of objects via DbI. The runtime as designed and implemented is about ten years behind how the language progressed, so there's definitely some work that needs to happen there.

But the single reason I'm focused on runtime versus a library solution. If you get the pointer acquire/release hooks in to the runtime that I talk about, then the whole argument between ARC GC and other forms comes down to a single question: "Who cares?"

A library solution actively requires the user to specify the kind of memory management they want. This is not what most modern programmers need to care about. A runtime solution means that if you want to switch between ARC GC and a traditional mark/sweep GC then you just swap the runtime implementation out. The user's code does not change, and it should not need to.

But yeah, this all comes down to the fact that the runtime really needs work these days. And to a degree, I imagine user-provided templates that dictate how code should be generated is an interesting compiler design paradigm that can help there.

So tl;dr - DIP, but I can't think about writing one for a few months because time, but there's bound to be interesting discussion that can come up as a result of this.
November 22, 2020
On Sunday, 22 November 2020 at 19:54:14 UTC, Ethan wrote:
> But yeah, this all comes down to the fact that the runtime really needs work these days. And to a degree, I imagine user-provided templates that dictate how code should be generated is an interesting compiler design paradigm that can help there.

If you want to mix ARC and GC in the same executable, for high efficiency, you need at least two types of pointers: owning and nonowning, and to break cycles you also need weak pointers (turns to null on destruction) which are useful for speculative caching as well.

The good news is that going from ARC to GC is free and that ARC annotated pointers will collect faster with a precise tracing GC than is the case today. So clearly a win for libraries, either way.

The bad news is that doing ARC in the LLVM IR is nontrivial so you may need a new intermediary typed language specific IR. But you need that to do @live well anyway... So, why not?


November 22, 2020
On Sunday, 22 November 2020 at 20:20:50 UTC, Ola Fosheim Grostad wrote:
> If you want to mix ARC and GC in the same executable, for high efficiency, you need at least two types of pointers: owning and

That was a bit terse. What I meant is that you could use the same library for both ARC and GC if you have a distinction between nonowning and owning pointers, and that this would be needed for efficient ARC/precise GC. If you also attatch a magic hidden template parameter to functions then you can have one thread using ARC and another one using a thread local GC using the same templated libraries.
November 22, 2020
On Sunday, 22 November 2020 at 19:54:14 UTC, Ethan wrote:
> One of the things I mentioned is that I don't get why library solutions are pursued for handling memory allocations/garbage collecting when the runtime already exists and can be used for the same purpose.

A benefit of the library solution is that the user can always create their own
implementation when needed.
You can write your own malloc in C, which is useful if you want to program an os... (for example)

> A library solution actively requires the user to specify the kind of memory management they want. This is not what most modern programmers need to care about. A runtime solution means that if you want to switch between ARC GC and a traditional mark/sweep GC then you just swap the runtime implementation out. The user's code does not change, and it should not need to.

I'm not a gamedev but I can imagine that (unlike most programmers) they care about it.
You might want to use ARC for resources on the GPU, but mark and sweep on CPU.
You could use region-based memory management for some objects to optimize performance.

> So tl;dr - DIP, but I can't think about writing one for a few months because time, but there's bound to be interesting discussion that can come up as a result of this.

Would it be possible that you have different pointer types, but code which doesn't care about it is somehow generic?


November 22, 2020
On Sunday, 22 November 2020 at 14:30:45 UTC, Ethan wrote:
> There's many nuanced points to consider here, so given that GC came up on the live Q&A and I got in to a bit of a chat there I figured copy/pasting that log and getting in to a (real, stop-saying-gamedev-doesn't-want-this) longer form discussion about the exact kind of GC we want in game development.
>
> There's a few people in the community here that are involved in console game dev, and they would know the kind of characteristics we require. Similarly, many of the lower level programmers that work with GPUs and the like are well aware that garbage collection is not good enough for releasing resources outside of the main system environment and would know the kind of control we require over deallocation and release paths.
>
> [snip]

Maybe organize a group to meet once a week to discuss issues and a path forward?
November 22, 2020
On Sunday, 22 November 2020 at 20:49:19 UTC, random wrote:
> A benefit of the library solution is that the user can always create their own
> implementation when needed.

The runtime is 100% overridable by the user. Walter continually says that the linker will just take the most recent symbol provided, ignoring symbols provided by the pack-in static libraries.

We even have the beginnings of a gamedev focused runtime in the works. Whatever, they're symbols the linker expects to find, we can define them however we want.
November 23, 2020
On 23/11/2020 4:48 AM, Ola Fosheim Grostad wrote:
> So that means there are only three options left: single threaded GC pool, non-language GC or ARC.

Concurrent GC (aka fork) and concurrent DS GC with i.e. fork.

We are only missing Windows support for a partially concurrent GC atm.

This is the direction I believe our default should be. It covers pretty much all use cases with reasonable performance.
November 23, 2020
On Sunday, 22 November 2020 at 19:54:14 UTC, Ethan wrote:
> On Sunday, 22 November 2020 at 14:30:45 UTC, Ethan wrote:
>> ...longer form discussion about the exact kind of GC we want in game development...
>
> So chatting with Atila on beerconf. The conversation that comes up, apart from this needing to be a DIP, is that I need to fill out some of the ideas that I have here.
>
> One of the things I mentioned is that I don't get why library solutions are pursued for handling memory allocations/garbage collecting when the runtime already exists and can be used for the same purpose. This led to highlighting that the runtime should be more templatised anyway so that it can get that deeper knowledge of objects via DbI. The runtime as designed and implemented is about ten years behind how the language progressed, so there's definitely some work that needs to happen there.

I've been looking into this and the main issue that has caused slow progress in templatizing the runtime is the fact that the hooks need to be `@trusted pure @nogc nothrow`. Why? Because those hooks may get called from `@trusted pure @nogc nothrow` code and you do not want the user getting errors like "you cannot do that because our runtime implementation is not pure". This leads to all sorts of problems: some functions cannot be pure, others cannot be @nogc etc.

I don't know if this can be fixed without a major redesign of druntime. Actually, I'm not even sure that all of the hooks can be `pure @nogc nothrow`.




« First   ‹ Prev
1 2 3 4 5 6 7 8