On 4/16/2014 8:13 PM, Manu via Digitalmars-d wrote:
On 17 April 2014 03:37, Walter Bright via Digitalmars-d
<digitalmars-d@puremagic.com <mailto:digitalmars-d@puremagic.com>> wrote:
    ARC has very serious problems with bloat and performance.
This is the first I've heard of it, and I've been going on about it for ages.

Consider two points:

1. I can't think of any performant ARC systems.

2. Java would be a relatively easy language to implement ARC in. There's probably a billion dollars invested in Java's GC. Why not ARC?


Obviously, a critical part of ARC is the compilers ability to reduce redundant
inc/dec sequences. At which point your 'every time' assertion is false. C++
can't do ARC, so it's not comparable.

C++ has shared_ptr, with all kinds of escapes.


With proper elimination, transferring ownership results in no cost, only
duplication/destruction, and those are moments where I've deliberately committed
to creation/destruction of an instance of something, at which point I'm happy to
pay for an inc/dec; creation/destruction are rarely high-frequency operations.

inc/dec isn't as cheap as you imply. The dec usually requires the creation of an exception handling unwinder to do it.


Have you measured the impact?

No. I don't really know how I could, as I haven't seen an ARC system.


I've never heard of Obj-C users complaining about the inc/dec costs.

Obj-C only uses ARC for a minority of the objects.


How often does ref fiddling occur in reality? My guess is that with redundancy
elimination, it would be surprisingly rare, and insignificant.

Yes, I would be surprised.

    Further problems with ARC are inability to mix ARC references with non-ARC
    references, seriously hampering generic code.
That's why the only workable solution is that all references are ARC references.
The obvious complication is reconciling malloc pointers, but I'm sure this can
be addressed with some creativity.

I imagine it would look something like:
By default, pointers are fat: struct ref { void* ptr, ref_t* rc; }

First off, now pointers are 24 bytes in size. Secondly, every pointer dereference becomes two dereferences (not so good for cache performance).


malloc pointers could conceivably just have a null entry for 'rc' and therefore
interact comfortably with rc pointers.
I imagine that a 'raw-pointer' type would be required to refer to a thin
pointer. Raw pointers would implicitly cast to fat pointers, and a fat->thin
casts may throw if the fat pointer's rc is non-null, or compile error if it can
be known at compile time.

Now we throw in a null check and branch for pointer operations.


Perhaps a solution is possible where an explicit rc record is not required (such
that all pointers remain 'thin' pointers)...
A clever hash of the pointer itself can look up the rc?
Perhaps the rc can be found at ptr[-1]? But then how do you know if the pointer
is rc allocated or not? An unlikely sentinel value at ptr[-1]? Perhaps the
virtual memory page can imply whether pointers allocated in that region are ref
counted or not? Some clever method of assigning the virtual address space so
that recognition of rc memory can amount to testing a couple of bits in 
pointers?

I'm just making things up,

Yes.

but my point is, there are lots of creative
possibilities, and I have never seen any work to properly explore the options.

ARC has been known about for many decades. If you haven't seen it "properly explored", perhaps it isn't as simple and cost-effective as it may appear at first blush.


So then consider ARC seriously. If it can't work, articulate why. I still don't
know, nobody has told me.
It works well in other languages, and as far as I can tell, it has the potential
to produce acceptable results for _all_ D users.

What other languages?


iOS is a competent realtime platform, Apple are well known for their commitment
to silky-smooth, jitter-free UI and general feel.

A UI is a good use case for ARC. A UI doesn't require high performance.


Okay. Where can I read about that? It doesn't seem to have surfaced, at least,
it was never presented in response to my many instances of raising the topic.
What are the impasses?

I'd have to go look to find the thread. The impasses were as I pointed out here.


I'm very worried about this. ARC is the only imaginary solution I have left. In
lieu of that, we make a long-term commitment to a total fracturing of memory
allocation techniques, just like C++ today where interaction between libraries
is always a massive pain in the arse. It's one of the most painful things about
C/C++, and perhaps one of the primary causes of incompatibility between
libraries and frameworks. This will transfer into D, but it's much worse in D
because of the relatively high number of implicit allocations ('~', closures, 
etc).

There are only about 3 cases of implicit allocation in D, all easily avoided, and with @nogc they'll be trivial to avoid. It is not "much worse".


Frameworks and libraries become incompatible with each other, which is a problem
in C/C++ that modern languages (java, C#, python, etc) typically don't suffer.

A GC makes libraries compatible with each other, which is one reason why GCs are very popular.


Reply via email to