digitalmars.D - A thought about garbage collection
- Benjamin Thaut <code benjamin-thaut.de> Dec 19 2012
- "bearophile" <bearophileHUGS lycos.com> Dec 19 2012
- "Robert Jacques" <rjacque2 live.johnshopkins.edu> Dec 19 2012
- "jerro" <a a.com> Dec 19 2012
- "bearophile" <bearophileHUGS lycos.com> Dec 19 2012
- "jerro" <a a.com> Dec 19 2012
- "deadalnix" <deadalnix gmail.com> Dec 19 2012
- "David Nadlinger" <see klickverbot.at> Dec 19 2012
- "bearophile" <bearophileHUGS lycos.com> Dec 19 2012
- "deadalnix" <deadalnix gmail.com> Dec 19 2012
- "Jonathan M Davis" <jmdavisProg gmx.com> Dec 19 2012
- "deadalnix" <deadalnix gmail.com> Dec 19 2012
- "bearophile" <bearophileHUGS lycos.com> Dec 19 2012
- "Jonathan M Davis" <jmdavisProg gmx.com> Dec 19 2012
- "deadalnix" <deadalnix gmail.com> Dec 19 2012
- "SomeDude" <lovelydear mailmetrash.com> Dec 19 2012
An article I just read. It even mentions D: http://sebastiansylvan.wordpress.com/2012/12/01/garbage-collection-thoughts/ I my opinion he especially has a point with the "each object consists mostly out of pointers" argument. Kind Regards Benjamin Thaut
Dec 19 2012
Benjamin Thaut:http://sebastiansylvan.wordpress.com/2012/12/01/garbage-collection-thoughts/
It seems a nice blog post. I don't remember what D does regarding per-thread heaps. Maybe Phobos emplace() is not enough and a bigger/better gun is needed to safely allocate in-place a higher percentage of class instances. Bye, bearophile
Dec 19 2012
On Wed, 19 Dec 2012 16:58:59 -0600, bearophile <bearophileHUGS lycos.com> wrote:Benjamin Thaut:http://sebastiansylvan.wordpress.com/2012/12/01/garbage-collection-thoughts/
It seems a nice blog post. I don't remember what D does regarding per-thread heaps.
It's been proposed and (sadly) rejected.Maybe Phobos emplace() is not enough and a bigger/better gun is needed to safely allocate in-place a higher percentage of class instances.
It would be fairly easy to build a library function(i.e. Scope!T or InPlace!T) that uses emplace to store a class inside of a wrapper struct.
Dec 19 2012
It would be fairly easy to build a library function(i.e. Scope!T or InPlace!T) that uses emplace to store a class inside of a wrapper struct.
There already is such function, std.typecons.scoped.
Dec 19 2012
jerro:There already is such function, std.typecons.scoped.
In your D code what's the percentage of class instantiations done with scoped()? Bye, bearophile
Dec 19 2012
In your D code what's the percentage of class instantiations done with scoped()? Bye, bearophile
I don't think I've ever actually used it (other than just trying it). When I use classes, I usually want them to be heap allocated. But if you need a class instance on the stack, scoped() looks useful. Are there some issues with it that I'm not aware of?
Dec 19 2012
On Thursday, 20 December 2012 at 00:56:30 UTC, jerro wrote:In your D code what's the percentage of class instantiations done with scoped()? Bye, bearophile
I don't think I've ever actually used it (other than just trying it). When I use classes, I usually want them to be heap allocated. But if you need a class instance on the stack, scoped() looks useful. Are there some issues with it that I'm not aware of?
It is unsafe :D But otherwise works properly. LDC also plan to provide a pass that remove many allocation when it can prove that thing don't escape scope. I don't know if that went into the lastest version, last time I heard of it it was experimental.
Dec 19 2012
On Thursday, 20 December 2012 at 01:15:51 UTC, deadalnix wrote:LDC also plan to provide a pass that remove many allocation when it can prove that thing don't escape scope.
Unfortunately, »many« is not quite true, as escape analysis is hard (and we e.g. currently don't lower D 'scope' on parameters to LLVM's equivalent) – »some« would be better.I don't know if that went into the lastest version, last time I heard of it it was experimental.
It's quite an old pass, but has been disabled for a long time. I recently resurrected it, but unfortunately it triggers an unrelated miscompilation, so I couldn't merge it into Git master (and the release) yet: https://github.com/ldc-developers/ldc/pull/206 David
Dec 19 2012
jerro:I don't think I've ever actually used it (other than just trying it). When I use classes, I usually want them to be heap allocated.
I think to make a difference for the GC (and to improve locality for the cache, and reduce the fan out discussed in the blog post), a good percentage (50%? 70%?) of the class instances need to be allocated in-place. I say "in-place", because a fixed-sized array is allocated in place inside a class instance, even if the instance is allocated on the heap. ------------------------ deadalnix:It is unsafe :D But otherwise works properly.
In this thread there are some notes: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Maybe some language support is needed to improve the situation. And this stuff can't want D3. Taking a good look at the design of Rust language is an option.LDC also plan to provide a pass that remove many allocation when it can prove that thing don't escape scope. I don't know if that went into the lastest version, last time I heard of it it was experimental.
Escape analysis helps, but it's not a good enough solution. This is said in that blog post too. Bye, bearophile
Dec 19 2012
On Wednesday, 19 December 2012 at 20:47:39 UTC, Benjamin Thaut wrote:An article I just read. It even mentions D: http://sebastiansylvan.wordpress.com/2012/12/01/garbage-collection-thoughts/ I my opinion he especially has a point with the "each object consists mostly out of pointers" argument.
He neglect to consider immutability (or maybe wasn't aware of) and how, combined with GC it allow some idioms that are very fast. Very good article overall. D's GC should really be aware of TL and immutability of what it does allocate.
Dec 19 2012
On Thursday, December 20, 2012 02:37:16 deadalnix wrote:D's GC should really be aware of TL and immutability of what it does allocate.
The problem is casting. It's not uncommon to create something as mutable and then cast it to immutable when done. It's stuff like that screws with being able to per-thread GCs. Which thread owns what isn't always clear. - Jonathan M Davis
Dec 19 2012
On Thursday, 20 December 2012 at 01:54:42 UTC, Jonathan M Davis wrote:On Thursday, December 20, 2012 02:37:16 deadalnix wrote:D's GC should really be aware of TL and immutability of what it does allocate.
The problem is casting. It's not uncommon to create something as mutable and then cast it to immutable when done. It's stuff like that screws with being able to per-thread GCs. Which thread owns what isn't always clear.
This is where the concept of island make sense, but this is unreasonable to introduce that in D in any short term. However, this kind of cast is explicitly specified as unsafe, and can have unexpected consequences, even in today's code. Obviously if the GC start to play with that, consequences will never be the same !!! (and by that I mean the consequences of a misuse can be way more dramatic)
Dec 19 2012
Jonathan M Davis:The problem is casting. It's not uncommon to create something as mutable and then cast it to immutable when done. It's stuff like that screws with being able to per-thread GCs. Which thread owns what isn't always clear.
I nearly never cast mutables to immutable. The purpose of casts is to subvert the type system. If you accept that some type system assumption doesn't hold just because casts exist, then you are doomed to ignore every kind of type system assumption, like immutability, safety, purity, nothrowness, and so on. And this is so wrong. So I can't accept your justification that the existence casts disallow per-thread GCs. Do not use cast that way, and give us a "better" GC. Bye, bearophile
Dec 19 2012
On Thursday, December 20, 2012 03:19:17 bearophile wrote:Jonathan M Davis:The problem is casting. It's not uncommon to create something as mutable and then cast it to immutable when done. It's stuff like that screws with being able to per-thread GCs. Which thread owns what isn't always clear.
I nearly never cast mutables to immutable. The purpose of casts is to subvert the type system. If you accept that some type system assumption doesn't hold just because casts exist, then you are doomed to ignore every kind of type system assumption, like immutability, safety, purity, nothrowness, and so on. And this is so wrong. So I can't accept your justification that the existence casts disallow per-thread GCs. Do not use cast that way, and give us a "better" GC.
It's perfectly legal to cast from mutable to immutable. You just have to make sure that you don't have any other references to that data. In many cases, it's the only way to get an immutable version of an object (e.g. if you wanted an immutable AA). There's even a helper function for this in the standard library: std.exception.assumeUnique. There's no way that this is going away, and the GC is going to have to take that into account with however it works. It may still be possible to have a per-thread GC, but it definitely complicates things. Casting to and from shared has similar issues and happens for similar reasons. And such casts are essentially forced by std.concurrency. So, you're overly optimistic if you think that the GC can ignore such casts. It must take them into account in whatever it does. - Jonathan M Davis
Dec 19 2012
On Thursday, 20 December 2012 at 02:29:09 UTC, Jonathan M Davis wrote:On Thursday, December 20, 2012 03:19:17 bearophile wrote:Jonathan M Davis:The problem is casting. It's not uncommon to create something as mutable and then cast it to immutable when done. It's stuff like that screws with being able to per-thread GCs. Which thread owns what isn't always clear.
I nearly never cast mutables to immutable. The purpose of casts is to subvert the type system. If you accept that some type system assumption doesn't hold just because casts exist, then you are doomed to ignore every kind of type system assumption, like immutability, safety, purity, nothrowness, and so on. And this is so wrong. So I can't accept your justification that the existence casts disallow per-thread GCs. Do not use cast that way, and give us a "better" GC.
It's perfectly legal to cast from mutable to immutable. You just have to make sure that you don't have any other references to that data. In many cases, it's the only way to get an immutable version of an object (e.g. if you wanted an immutable AA). There's even a helper function for this in the standard library: std.exception.assumeUnique. There's no way that this is going away, and the GC is going to have to take that into account with however it works. It may still be possible to have a per-thread GC, but it definitely complicates things. Casting to and from shared has similar issues and happens for similar reasons. And such casts are essentially forced by std.concurrency. So, you're overly optimistic if you think that the GC can ignore such casts. It must take them into account in whatever it does.
I think the right way to do that is to actually clone the object. You can argue that is a performance cost, but considering the implication on the GC, I'm pretty sure it is a win. Another way to do it safely is to use pure function, but it require that notion of isolated island, and as much as I love the idea, I won't be in favor of introducing it right now into D.
Dec 19 2012
On Wednesday, 19 December 2012 at 20:47:39 UTC, Benjamin Thaut wrote:An article I just read. It even mentions D: http://sebastiansylvan.wordpress.com/2012/12/01/garbage-collection-thoughts/ I my opinion he especially has a point with the "each object consists mostly out of pointers" argument. Kind Regards Benjamin Thaut
Another page of interest: http://wiki.luajit.org/New-Garbage-Collector
Dec 19 2012









"bearophile" <bearophileHUGS lycos.com> 