Thanks for clarifications. I have a couple of follow-up questions.
1. Could you please provide more information (e.g. source code location)
about the optimization applying non-atomic reference counting? What's the
scope of the optimization? Is it method-based?
2. Looking at the source code, I assume Swift implements immediate
reference counting (i.e. immediate reclamation of dead objects) without
requiring explicit garbage collection phase for techniques, such as
deferred reference counting or coalescing multiple updates. Is it right?
If so, is there any plan to implement such techniques?
···
On Wed, Nov 30, 2016 at 11:41 AM John McCall <rjmccall@apple.com> wrote:
On Nov 30, 2016, at 8:33 AM, Jiho Choi via swift-dev <swift-dev@swift.org> > wrote:
Hi,I am new to Swift, and I have several questions about how ARC works in
Swift.1. I read from one of the previous discussions in the swift-evolution list
(
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009422.html\)
that ARC operations are currently not atomic as Swift has no memory model
and concurrency model. Does it mean that the compiler generates non-atomic
instructions for updating reference counts (e.g. using incrementNonAtomic()
instead of increment() in RefCount.h)?No. We have the ability to do non-atomic reference counting as an
optimization, but we only trigger it when we can prove that an object
hasn't escaped yet. Therefore, at the user level, retain counts are atomic.Swift ARC is non-atomic in the sense that a read/write or write/write race
on an individual property/variable/whatever has undefined behavior and can
lead to crashes or leaks. This differs from Objective-C ARC only in that a
(synthesized) atomic strong or weak property in Objective-C does promise
correctness even in the face of race conditions. But this guarantee is not
worth much in practice because a failure to adequately synchronize accesses
to a class's instance variables is likely to have all sorts of other
unpleasant effects, and it is quite expensive, so we decided not to make it
in Swift.2. If not, when does it use non-atomic ARC operations? Is there an
optimization pass to recognize local objects?3. Without the concurrency model in the language, if not using GCD (e.g.
all Swift benchmark applications), I assume Swift applications are
single-threaded. Then, I think we can safely use non-atomic ARC
operations. Am I right?When we say that we don't have a concurrency model, we mean that (1) we
aren't providing a more complete language solution than the options
available to C programmers and (2) like C pre-C11/C++11, we have not yet
formalized a memory model for concurrency that provides formal guarantees
about what accesses are guaranteed to not conflict if they do race. (For
example, we are unlikely to guarantee that accesses to different properties
of a struct can occur in parallel, but we may choose to make that guarantee
for different properties of a class.)4. Lastly, is there a way to measure the overhead of ARC (e.g. a compiler
flag to disable ARC)?No, because ARC is generally necessary for correctness.
John.