March 06, 2017
On Monday, 6 March 2017 at 15:40:54 UTC, Rico Decho wrote:
> ...
> For instance, you ask for GC when the game is in a menu or after a background resource loading.
> ...

maybe that's what you're looking for: https://dlang.org/phobos/core_memory.html#.GC.collect

March 06, 2017
> GC.disable doesn't guarantee the garbage collector won't run: https://dlang.org/phobos/core_memory.html#.GC.disable I'm not sure how much impact that has in practice.

That's why I'd like D to allow also Nim's alternative GC method.

https://nim-lang.org/docs/gc.html

Basically, you have the choice between a standard GC and a real-time GC.

With the real-time version, you ask regularly for a partial time-limited GC.

They say you can normally expect it to take less than 2 ms.

And you can also decide not to call it if you know that it's not needed at the moment (no resource loading, etc), or if it's the wrong time to call it.

What worries C++ game developers like me is not a regular 2 ms GC at each frame, it's actually an occasional 200 ms GC once in a while...

Hence the need to allocate manually and disable the GC at the moment.
March 06, 2017
> maybe that's what you're looking for: https://dlang.org/phobos/core_memory.html#.GC.collect

Indeed !

I'll try to make some benchmarks with a 3D rendering loop to see how much time it takes if there is not much to GC.
March 06, 2017
> maybe that's what you're looking for: https://dlang.org/phobos/core_memory.html#.GC.collect

What is nice with Nim it that it has a GC heap PER THREAD. No need to stop the other threads during a GC...

https://nim-lang.org/docs/threads.html
https://nim-lang.org/docs/manual.html#threads

"Nim's memory model for threads is quite different than that of other common programming languages (C, Pascal, Java): Each thread has its own (garbage collected) heap and sharing of memory is restricted to global variables. This helps to prevent race conditions. GC efficiency is improved quite a lot, because the GC never has to stop other threads and see what they reference. Memory allocation requires no lock at all! This design easily scales to massive multicore processors that are becoming the norm."

I'd suggest taking inspiration from that for D's memory allocations and garbage collection...

March 06, 2017
On Mon, Mar 06, 2017 at 05:30:56PM +0000, Rico Decho via Digitalmars-d wrote:
> > maybe that's what you're looking for: https://dlang.org/phobos/core_memory.html#.GC.collect
> 
> Indeed !
> 
> I'll try to make some benchmarks with a 3D rendering loop to see how much time it takes if there is not much to GC.

If you have a lot of total allocated memory, GC may still be somewhat slow (because it has to scan a lot of memory, most of which is still live).  One possible approach is to do your large-scale, long-term allocations outside the GC heap (i.e., use malloc) so that the amount of GC memory that needs to be scanned is small.

One approach of reducing the amount of GC allocations that people new to D seem to overlook, is to avoid string allocations by using D's range-based algorithms instead.  E.g., instead of:

	auto s = "abc" ~ myString ~ "def"; // lots of allocations
	writeln(s);

Do this instead:

	import std.range;
	auto r = chain("abc", myString, "def"); // no allocation
	writeln(r);

This isn't always possible, e.g., if you need to store the result of a concatenation and access it later, but a lot of on-the-fly allocations (i.e., short-term garbage) could be eliminated this way.


T

-- 
If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
March 06, 2017
Btw, I'm not promoting Nim here, just asking to take inspiration from its memory model ;)

I've used Nim in the past, and while it's a nice language, D is much closer to perfection regarding my personal needs and tastes.

I've actually converted all my Nim scripts to D, because :
1/ it doesn't force you to declare the types and functions before using them;
2/ it uses a standard curly-brace block syntax, which helps a lot when porting C++ or Node.js code to D.

March 06, 2017
On Mon, Mar 06, 2017 at 05:52:40PM +0000, Rico Decho via Digitalmars-d wrote:
> Btw, I'm not promoting Nim here, just asking to take inspiration from its memory model ;)

Nevertheless, it's certainly true that D's GC could use a major upgrade at some point.  While it's not horrible, the present implementation does leave more to be desired.  Hopefully the various efforts at GC by forum members will at some point turn into some major improvements to D's GC. There was talk a year or two ago about a precise for D (with fallback to conservative GC for cases where that wouldn't work), but I'm not sure what has come of it.


[...]
> 2/ it uses a standard curly-brace block syntax, which helps a lot when porting C++ or Node.js code to D.

<even-more-offtopic>
It's kinda ironic how the times have changed, that people these days
regard curly-brace block syntax as "standard".  I still remember not too
many decades ago (har har) when C's curly-brace syntax was regarded as
too obscure or line-noise-y, and people preferred "begin ...  end", "if
.. fi", or similar things popular at the time.
</even-more-offtopic>


T

-- 
Unix is my IDE. -- Justin Whear
March 06, 2017
On Monday, 6 March 2017 at 16:40:02 UTC, bachmeier wrote:
> GC.disable doesn't guarantee the garbage collector won't run

In only exceptional cases

> deems necessary for correct program behavior, such as during an out of memory condition
March 06, 2017
On Monday, 6 March 2017 at 18:22:53 UTC, H. S. Teoh wrote:
>but I'm not sure what has come of it.

https://github.com/dlang/druntime/pull/1603
March 06, 2017
> If you have a lot of total allocated memory, GC may still be somewhat slow (because it has to scan a lot of memory, most of which is still live).  One possible approach is to do your large-scale, long-term allocations outside the GC heap (i.e., use malloc) so that the amount of GC memory that needs to be scanned is small.
>
> One approach of reducing the amount of GC allocations that people new to D seem to overlook, is to avoid string allocations by using D's range-based algorithms instead.  E.g., instead of:
>
> 	auto s = "abc" ~ myString ~ "def"; // lots of allocations
> 	writeln(s);
>
> Do this instead:
>
> 	import std.range;
> 	auto r = chain("abc", myString, "def"); // no allocation
> 	writeln(r);
>
> This isn't always possible, e.g., if you need to store the result of a concatenation and access it later, but a lot of on-the-fly allocations (i.e., short-term garbage) could be eliminated this way.
>
>
> T

PERFECT !!!