www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - blog post about how you can make your gc code faster

reply Adam D Ruppe <destructionator gmail.com> writes:
Putting aside new GC implementation tweaks like I discussed last 
week, and not just switching to other functions, this week I 
wanted to lecture a bit about how you can reduce your GC pause 
times in stock D today:

http://dpldocs.info/this-week-in-d/Blog.Posted_2022_11_07.html
Nov 07 2022
parent reply Guillaume Piolat <first.last spam.org> writes:
On Monday, 7 November 2022 at 14:34:38 UTC, Adam D Ruppe wrote:
 Putting aside new GC implementation tweaks like I discussed 
 last week, and not just switching to other functions, this week 
 I wanted to lecture a bit about how you can reduce your GC 
 pause times in stock D today:

 http://dpldocs.info/this-week-in-d/Blog.Posted_2022_11_07.html
 By far, the biggest benefit you can tweak in D's gc is making 
 your bulk allocations be completely pointer-free, since then it 
 is entirely removed from the scan job, saving potentially 
 significant amounts of time.
I've been avoiding void[] for this reason (I mean, void[] _could_ contain pointers), but I think I'm cargo-culting this? If I do: ubyte[] arr = new ubyte[100_000_000]; void[] arr2 = cast(void[]) arr; // will this still avoid scanning? Does the GC still know that this area is NO_SCAN?
Nov 09 2022
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 November 2022 at 11:55:28 UTC, Guillaume Piolat 
wrote:
 I've been avoiding void[] for this reason (I mean, void[] 
 _could_ contain pointers), but I think I'm cargo-culting this?
Yeah, it actually doesn't really matter. It is the allocation type that sets the flag. So
 If I do:
     ubyte[] arr = new ubyte[100_000_000];
Since you `new ubyte`, it set NO_SCAN at the allocation. That's attached to the memory block now.
     void[] arr2 = cast(void[]) arr; // will this still avoid 
 scanning?
Meaning this will not scan the block. Where you get in trouble with void is if it was allocated that way to begin with. Then it will be scanned... but I'm pretty sure `new void[]` doesn't work anyway. Other potential trouble with this would be if you allocate as ubyte, then cast to a pointer type and store something in there. That might be freed prematurely since the block flags is set at allocation time, and not changed when you cast the slice. Even the precise collector doesn't really care since the type in a struct being ubyte[] or void[] are both themselves a pointer - the pointer to the array - so it'd count. But the array itself is stored elsewhere so the GC will look that up in its separate metadata. So you are OK using void[] here to hold things wrt gc scans. Just make sure it is allocated as a concrete type.
Nov 09 2022
prev sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Wednesday, 9 November 2022 at 11:55:28 UTC, Guillaume Piolat 
wrote:
 I've been avoiding void[] for this reason (I mean, void[] 
 _could_ contain pointers), but I think I'm cargo-culting this?

 If I do:
     ubyte[] arr = new ubyte[100_000_000];
     void[] arr2 = cast(void[]) arr; // will this still avoid 
 scanning?

 Does the GC still know that this area is NO_SCAN?
Yes (as per Adam's post). However, it's easy to lose it with operations like concatenation or appending. `a ~ b` will allocate `void[]` (without `NO_SCAN`) if either are `void[]`. This is why I still use `ubyte[]` (or, in ae, `Data` / `DataVec`) for raw data.
Nov 19 2022