DIP60: @nogc attribute

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 21 13:29:46 PDT 2014


On Mon, 21 Apr 2014 15:03:18 -0400, Walter Bright  
<newshound2 at digitalmars.com> wrote:

> On 4/21/2014 10:57 AM, Steven Schveighoffer wrote:
>> On Mon, 21 Apr 2014 13:28:24 -0400, Walter Bright  
>> <newshound2 at digitalmars.com>
>> wrote:
>>
>>> On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:
>>>>> Total replacement of GC with ARC in D will:
>>>> This is the wrong straw-man, I'm not advocating for this at all.
>>>
>>> Many are when they advocate ARC for D.
>>
>> Does that preclude you from accepting any kind of ARC for D?
>
> No. My objection is to pervasive ARC, i.e. all gc is replaced with ARC,  
> and it all magically works.

With slicing, I don't think it's possible. Looking up the owner of a block  
for an INTERNAL pointer costs O(lg(n)), where n is all of your memory,  
because you must find out what block the pointer is accessing. Doing this  
during mark and sweep is bad enough, doing it for every ref count add or  
remove would be ghastly.

ARC, and ref counting in general, is MUCH better implemented as having a  
reference count inside the object referenced. This means the type MUST BE  
AWARE of ref counting, or be wrapped in an aware type.

Slices couldn't possibly do this correctly, since they do not point at the  
general block where all the info is maintained, but just at "some memory."  
An ARC-aware slice would be fatter, or less performant.

>>> 5. Numerous posters here have posited that the overhead of ARC can be
>>> eliminated with a sufficiently smart compiler (which does not exist).
>>
>> You continue to speak in extremes. People are saying that the compiler  
>> can
>> eliminate most of the needless ARC increments and decrements, not all  
>> of them.
>
> Manu, for example, suggests it is good enough to make the overhead  
> insignificant. I'm skeptical.

I think you are misunderstanding something. This is not for a pervasive  
ARC-only, statically guaranteed system. The best example he gives (and I  
agree with him) is iOS. Just look at the success of iOS, where the entire  
OS API is based on ARC (actually RC, with an option for both ARC and  
manual, but the latter is going away). If ARC was "so bad", the iOS  
experience would show it. You may have doubts, but I can assure you I can  
build very robust and performant code with ARC in iOS.

Let us consider that the single most difficult thing with memory  
management is giving away a piece of memory you created, never to see  
again, either via pushing into something, or returning it. The code that  
is responsible for creating that memory is not the code that is  
responsible for reclaiming it. This means you need an agreement between  
your code and the code that's accepting it, as to what the recipient needs  
to do once he's done. The giving away piece is easy, it's the "when am I  
done with this?" that makes it difficult. If it's going to one place,  
that's pretty simple, but if it's going to multiple places, that's where  
it becomes a headache. Basically, as long as someone is looking at this,  
it needs to exist, and you don't know who else is looking!

In that respect, both ARC and GC handle the job admirably. But it so  
happens that some of the load that GC happens to require (more memory;  
infrequent but lagging pauses) is not conducive to the environments Manu  
is targeting (embedded games). The tradeoffs are not a complete win for  
ARC, and I don't think D should switch to ARC (I think it's impossible  
anyway), but providing a builtin compiler-assisted mechanism to use ARC  
would allow a style of coding that would complement D's existing tools.  
Consider that with D's version of pure, I can easily do functional and  
imperative programming, even mixing the two, without even thinking about  
it! I'd like to see something with ARC that makes it easy to intermix with  
GC, and replace some of the Object management in D. It can never be a  
fully generic solution, except by object wrapping, because the type needs  
to be aware of the RC.

Other memory management tasks are simple. For example, owned arrays  
encapsulated inside an object, or temporary buffer space that you free  
before exiting a function. Those don't need complex memory management  
tools to make safe or effective. These have *defined lifetimes*.

>> Compilers that do this do exist.
>
> I can't reconcile agreeing that ARC isn't good enough to be pervasive  
> with compiler technology eliminates unnecessary ARC overhead.

It's pretty pervasive on iOS. ARC has been around since iOS 4.3 (circa  
2011).

It's pretty difficult to use manual RC and beat ARC. In fact in some  
cases, ARC can beat manual, because the compiler has more insight and  
knowledge of the rules being followed.

-Steve


More information about the Digitalmars-d mailing list