April 29, 2012
On 29 April 2012 16:53, Sean Kelly <sean@invisibleduck.org> wrote:

> On Apr 29, 2012, at 2:38 AM, Manu <turkeyman@gmail.com> wrote:
>
> On 28 April 2012 18:16, Peter Alexander <peter.alexander.au@gmail.com>wrote:
>
>> On Saturday, 28 April 2012 at 09:14:51 UTC, SomeDude wrote:
>>
>>> On Saturday, 28 April 2012 at 09:12:23 UTC, SomeDude wrote:
>>>
>>>>
>>>> Real time guarantees on a GC is not something we are going to offer anytime soon anyway. While a minimal library, loosely based on the C standard library, with some more bells and whistles that could be borrowed from Phobos, this is a goal that is achievable in a foreseeable future. And both game developers and embedded programmers would be interested.
>>>>
>>>
>>> Note that Kenta Cho, who wrote fast games in D1, used this approach, and it worked very well for him.
>>>
>>
>> I also write games in D.
>>
>> My approach is this: use the GC all you want during loading or other non-interactive parts of the game and then just make sure that you don't use it during gameplay.
>>
>> GC vs. manual memory allocation is a non-issue for real-time guarantees. The simple fact of the matter is that you should be using neither. I also don't use malloc/free during runtime because it has the same non-real-time problems as using the GC. A single malloc can stall for tens of milliseconds or more, and that's simply too much.
>>
>> Just learn how to write code that doesn't allocate memory.
>>
>> A bigger problem with GC for games is memory management i.e. controlling how much memory is currently allocated, and what systems are using what memory. Having deterministic memory usage is preferable for those cases because I know that as soon as I delete something that the memory is available for something else. I don't get that guarantee with a GC.
>>
>
> I think that basically sums it up.
>
> I'm interested to know is whether using a new precise GC will guarantee
> ALL unreferenced stuff will be cleaned on any given sweep.
> I can imagine a model in games where I could:
>  1 Use the GC to allocate as much as I like during initialisation
>  2 During runtime you never allocate anyway, so disable the GC (this is
> when it is important to know about hidden allocations)
>  3 During some clean-up, first run the logic to de-reference all things
> that are no longer required
>  4 Finally, force a precise GC scan, which should guarantee that all
> no-longer referenced memory would be cleaned up at that time.
>
> This would actually be a very convenient working model for games. But it only works if I know everything that was released will definitely be cleaned, otherwise I may not be ale to allocate the next level (games often allocate all memory a machine has within 100k or so).
>
>
> For a use pattern like this, one thing that may work is to add a GC proxy immediately before loading a level. To unload the level, terminate that GC.
>

Interesting work around, although there are many other things that don't
get freed from state to state, and things that are shared by both state A
and B are best to keep around, save the unload/reload time of that resource
(there is always lots of sharing, it adds up).
Is it technically possible to have a precise GC clean up all unreferenced
memory in one big pass?


April 29, 2012
On Sunday, 29 April 2012 at 22:13:22 UTC, Manu wrote:
> Is it technically possible to have a precise GC clean up all unreferenced
> memory in one big pass?

yes, but unless it's also moving/compacting... one would suffer memory fragmentation... so I would imagine TempAlloc is a better fit?

April 29, 2012
On 30 April 2012 01:24, Tove <tove@fransson.se> wrote:

> On Sunday, 29 April 2012 at 22:13:22 UTC, Manu wrote:
>
>> Is it technically possible to have a precise GC clean up all unreferenced memory in one big pass?
>>
>
> yes, but unless it's also moving/compacting... one would suffer memory fragmentation... so I would imagine TempAlloc is a better fit?
>

In some cases I'm comfortable with that type of fragmentation (large regularly sized resources), although that leads me to a gaping hole in D's allocation system...

<OT, but still very important>
There is no way to request aligned memory. I can't even specify an
alignment on a user type and expect it to be aligned if I create one on the
stack, let alone the heap >_<
It seems I can request alignment for items within a struct, but I can't
align the struct its self. In addition, a struct doesn't inherit the
alignment of its aligned members, so the struct is allocated unaligned, and
the aligned member fails its promise anyway.

I frequently align to:
16 bytes for basically everything. This facilitates hardware simd, fast
memcpy, efficient write-combining, better cache usage.
128(ish) bytes for L1 cache alignment (depending on architecture).
Frequently used to guarantee ~128byte sized structs will never straddle
cache lines (wasting a memory fetch/L1 eviction), and supporting
predictable prefetch algorithms.
4k(ish) for texture/gpu page alignment (again, depending on architecture).
Many GPU resources MUST be aligned for the GPU to access them. Swizzling is
applied to aligned pages, resource allocation must match this.
4-64k virtual memory pages. Many uses.

And occasionally other alignments pop up, often where they may be useful to
help reduce/avoid fragmentation for instance.
Sometimes I need to squat some data in a couple of low its in a pointer...
requires the pointers be aligned.

Obviously I can manually align my memory with various techniques, and I
do, but it's rather fiddly and can also be very wasteful.
One fast technique for general allocations is over-allocating by
alignment-1, pasting a little header and padding the allocation. Allocating
a GPU page for instance would waste another whole page just to guarantee
alignment. In that case, you need to allocate a bog pool of pages and
implement some pool system to dish them out, but then you need to know the
precise number of pages to be allocated in advance in order not to waste
memory that way.
</OT>


April 30, 2012
On Sunday, 29 April 2012 at 23:04:00 UTC, Manu wrote:
> In some cases I'm comfortable with that type of fragmentation (large
> regularly sized resources), although that leads me to a gaping hole in D's
> allocation system...
>

Hmmm I see, also I was thinking... since we have TLS, couldn't we abuse killing threads for fast deallocations? While adding persistent data to __gshared?

> <OT, but still very important>
> There is no way to request aligned memory. I can't even specify

I feel your pain, couldn't agree more.

April 30, 2012
On 4/29/2012 2:38 AM, Manu wrote:
> I'm interested to know is whether using a new precise GC will guarantee ALL
> unreferenced stuff will be cleaned on any given sweep.

The new hook put into the typeinfo will do precise collection for references within GC allocated objects. For references that sit on the stack or in static data, it will still use the current conservative scheme.

Some things will always be imprecise, like if you have a union of a pointer with an integer, or if you allocate untyped data.
April 30, 2012
"Manu" <turkeyman@gmail.com> wrote in message news:mailman.93.1335691450.24740.digitalmars-d@puremagic.com...
> On 28 April 2012 04:10, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>
>> On Sat, Apr 28, 2012 at 01:31:32AM +0200, SomeDude wrote: [...]
>> > The other thing that would make it attractive among the C++ developers, would be the development of a lightweight, high performance, minimal library that doesn't use the GC at all.  Ideally, it would be compatible with Phobos. I bet if such a library existed, flocks of C++ developers would suddenly switch to D.
>>
>> I know the current GC leaves much room for improvement, but what's the hangup about the GC anyway? If -- and yes this is a very big if -- the GC has real-time guarantees, would that make it more palatable to C++ devs? Or is it just because they have trouble with the idea of having a GC in the first place?
>>
>
> If the GC guarantees to behave in a deterministic and predictable way, I
> have no problem with it. And even if it doesn't, as long as it's lightning
> fast, and I can control the sweeps.
> One major concern to me is invisible allocations. I want to know when I'm
> allocating, I like allocate operations to be clearly visible. There are a
> lot of operations that cause invisible allocations in D, but they are
> avoidable.
> Games are both embedded and realtime code at the same time, this unions
> the
> strict requirements of both worlds into a system that demands very tight
> control of these things. Fragmentation is the enemy, so is losing 1ms (GC
> takes WAY longer than this currently) at random moments.
>
> There is a problem right now where the GC doesn't actually seem to work,
> and I'm seeing D apps allocating gigabytes and never releasing the memory.
> A great case study for the GC is VisualD, if any GC experts would like to
> check it out. It shows a use case where the GC utterly fails, and makes
> the
> software borderline unusable as a result. It seems to 'leak' memory, and
> collects can take 5-10 seconds at a time (manifested by locking up the
> entire application).
> VisualD has completely undermined by faith and trust in the GC, and I've
> basically banned using it. I can't afford to run into that situation a few
> months down the line.
>

I once tried to create a batch image processing tool in D, and false pointers rendered the whole thing unusable. I've been wary about such things since.

This was a number of years ago, though.


April 30, 2012
On 04/30/2012 08:45 PM, Nick Sabalausky wrote:
>
> I once tried to create a batch image processing tool in D, and false
> pointers rendered the whole thing unusable. I've been wary about such things
> since.
>
> This was a number of years ago, though.
>
>

False pointers in the image data? Why would that even be scanned?
April 30, 2012
On 4/30/2012 12:09 PM, Timon Gehr wrote:
> On 04/30/2012 08:45 PM, Nick Sabalausky wrote:
>>
>> I once tried to create a batch image processing tool in D, and false
>> pointers rendered the whole thing unusable. I've been wary about such things
>> since.
>>
>> This was a number of years ago, though.
>>
>>
>
> False pointers in the image data? Why would that even be scanned?

Such was scanned in early D.

Anyhow, a large allocation is more likely to have false pointers into it than a small one. For very large allocations, I would suggest handling them explicitly rather than using the GC.
May 01, 2012
On Apr 30, 2012, at 12:09 PM, Timon Gehr wrote:

> On 04/30/2012 08:45 PM, Nick Sabalausky wrote:
>> 
>> I once tried to create a batch image processing tool in D, and false pointers rendered the whole thing unusable. I've been wary about such things since.
>> 
>> This was a number of years ago, though.
> 
> False pointers in the image data? Why would that even be scanned?

It was probably back when the GC scanned everything.  BlkAttr.NO_SCAN has only been around for a few years.

May 03, 2012
On 30/04/12 01:03, Manu wrote:
> On 30 April 2012 01:24, Tove <tove@fransson.se
> <mailto:tove@fransson.se>> wrote:
>
>     On Sunday, 29 April 2012 at 22:13:22 UTC, Manu wrote:
>
>         Is it technically possible to have a precise GC clean up all
>         unreferenced
>         memory in one big pass?
>
>
>     yes, but unless it's also moving/compacting... one would suffer
>     memory fragmentation... so I would imagine TempAlloc is a better fit?
>
>
> In some cases I'm comfortable with that type of fragmentation (large
> regularly sized resources), although that leads me to a gaping hole in
> D's allocation system...
>
> <OT, but still very important>
> There is no way to request aligned memory. I can't even specify an
> alignment on a user type and expect it to be aligned if I create one on
> the stack, let alone the heap >_<
> It seems I can request alignment for items within a struct, but I can't
> align the struct its self. In addition, a struct doesn't inherit the
> alignment of its aligned members, so the struct is allocated unaligned,
> and the aligned member fails its promise anyway.

Bug 2278.