Le 9 déc. 2012 à 02:27, Richard Heard <[email protected]> a écrit :
> Greg,
>
> So, from what you are saying, either of these snippets should be valid, right?
>
>> +(id)sharedInstance{
>> static id _sharedInstance = nil;
>>
>> …
>> OSMemoryBarrier();
>> return _sharedInstance;
>> }
OSMemoryBarrier are not cheap. If dispatch_once uses it only on the write side,
then it should be faster than forcing a full barrier at each access.
By the way, as nobody mention it until then, all this discussion look like to
me as pointless premature optimization. If accessing your singleton is a
bottleneck (and nothing tell us it is), there is probably simpler way to avoid
this cost.
> vs
>
>> +(id)sharedInstance{
>> static id _sharedInstance = nil;
>>
>> static dispatch_once_t onceToken;
>> dispatch_once(&onceToken, ^{
>> _sharedInstance = [[super allocWithZone:NULL] init];
>> });
>>
>> return _sharedInstance;
>> }
>
>
> Any massive advantages / disadvantages with either approach?
>
> -Richard
>
> On 08/12/2012, at 4:45:37 PM, Greg Parker <[email protected]> wrote:
>
>> On Dec 8, 2012, at 11:17 AM, Steve Sisak <[email protected]> wrote:
>>> At 10:24 AM -0800 12/8/12, Kyle Sluder wrote:
>>>> On Dec 8, 2012, at 10:06 AM, Steve Sisak <[email protected]> wrote:
>>>>
>>>>> Further, if writes were not complete at the end of the block, the
>>>>> construct would besentially useless for its intended purpose.
>>>>
>>>> By the way, you're wrong about this too. All @synchronized does is act as
>>>> a mutex around a code block. It does not cause the compiler to reorder
>>>> instructions and issue memory barriers in such a way that initialization
>>>> is guaranteed to precede assignment from the perspective of all threads.
>>>
>>> Please cite a source for this assertion.
>>
>> Source: me, the author of the current @synchronized implementation.
>> @synchronized performs the same synchronization as a pthread mutex.
>>
>>
>>> From:
>>>
>>> <https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html>
>>>
>>> "If you are already using a mutex to protect a section of code, do not
>>> automatically assume you need to use the volatile keyword to protect
>>> important variables inside that section. A mutex includes a memory barrier
>>> to ensure the proper ordering of load and store operations."
>>
>> To a close approximation, you should pretend that `volatile` does not exist
>> in C-based languages.
>>
>> The above says that if you already have mutexes then you do not need
>> `volatile`. The mutex alone does all of the work.
>>
>> Conversely, `volatile` with no mutex is also not a safe multithreading
>> pattern.
>>
>>
>>> I acknowledge that, without proper memory barriers, double-checked locking
>>> is problematic, but am providing an example using a construct which I'm
>>> fairly sure uses proper memory barriers.
>>>
>>> - (NSDictionary *)someDictionary;
>>> {
>>> if (!_someDictionary)
>>> {
>>> @synchronized (self)
>>> {
>>> if (!_someDictionary)
>>> {
>>> // create a temp dictionary (might take some time)
>>> _someDictionary = temp;
>>> }
>>> }
>>> }
>>>
>>> return _someDictionary;
>>> }
>>
>>
>> The example provided does not use proper memory barriers.
>>
>> In general, memory barriers need to occur in pairs, one on each thread. The
>> coordination of the two memory barriers achieves the desired
>> synchronization, so that both sides observe events occurring in the same
>> order.
>>
>> Mutexes and similar constructs achieve this. The mutex lock() and unlock()
>> procedures form a barrier pair. Code running with the mutex held is
>> therefore correctly synchronized with respect to other code that runs with
>> the mutex held. But code running outside the mutex is not protected, because
>> it didn't call the barrier inside the lock() procedure.
>>
>> In faulty double-checked locking code, the problem is that the writer has a
>> memory barrier but the reader does not. Because it has no barriers, the
>> reader may observe events occur out of the desired order. That's why it
>> fails. (Here the "writer" is the thread actually calling the initializer and
>> the "reader" is a second thread simultaneously performing the double-check
>> sequence.)
>>
>> (Faulty double-checked locking code has a second problem because the
>> writer-side barrier inside the mutex unlock is the wrong barrier to use with
>> a reader that is not locking the mutex.)
>>
>> You need to do one of two things to fix the reader side of a double-checked
>> lock:
>> * add appropriate barriers to the reader side, or
>> * cheat in a way that is guaranteed to work on all architectures you care
>> about.
>>
>> dispatch_once() actually cheats. It performs a very expensive barrier on the
>> writer side (much more expensive than the barriers used in ordinary mutexes
>> and @synchronized), which guarantees that no barrier is needed on the reader
>> side on the CPUs that run OS X and iOS. The expensive barrier on the reader
>> side is an acceptable trade-off because the writer path runs only once.
>>
>>
>> --
>> Greg Parker [email protected] Runtime Wrangler
>>
>>
>>
>> _______________________________________________
>>
>> Cocoa-dev mailing list ([email protected])
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>> https://lists.apple.com/mailman/options/cocoa-dev/heardrwt%40gmail.com
>>
>> This email sent to [email protected]
>
> _______________________________________________
>
> Cocoa-dev mailing list ([email protected])
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/devlists%40shadowlab.org
>
> This email sent to [email protected]
-- Jean-Daniel
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]