
On Monday, October 31, 2011 15:01:35 Helge Bahmann wrote:
a) IMHO atomics for inter-process coordination is the exception, while inter-thread coordination is the norm
I have to disagree. Atomics may be used to communicate processes just as well as threads, if not better. I often use atomics to perform lock-free IPC between processes. Aside from performance reasons, this often adds to application resillience to process crashes, when classic primitives like mutex may be left in an invalid state. Multi-process applications (with shared memory to communicate between processes) are less common than other kinds of applications, yes. But that doesn't make this use case exceptional in any way.
b) "per-object" lock is expensive (sizeof(pthread_mutex_t) can be 40 bytes)
c) when you hit the fallback path, then you are better off using a datastructure with locking to begin with
*If* I change the implementation to a per-object lock then this would in my view mean to optimize for an uncommon case, with noticable memory overhead penalties for the common case, to allow using the atomic objects as "drop-in" replacements in an environment where they are not the best solution anyways. (I would favor to move the distinction between using atomic objects for a given data structure versus locking upwards, instead of moving everything downwards and shoe-horning it into boost.atomic).
Well, yes and no. Consider this example, which illustrates the control structure of a lock-free ring buffer: struct index_t { uint32_t version; uint32_t index; }; I want to be able to write atomic< index_t > so that it compiles and works on any platform, even without 64-bit CAS support in hardware. It may work slower, yes, but it will. On the other hand, I agree that there is no sense in atomic< std::string > or something like that. But hey, nothing prevents you from shooting in your foot.
I have serious difficulties justifying such a change, maybe others can offer their opinion?
I think, having a mutex per atomic instance is an overkill. However, a spinlock per instance might just be the silver bullet. The size overhead should be quite modest (1 to 4 bytes, I presume) and the performance would still be decent. After all, atomic<> is intended to be used with relatively small types with simple operations, such as copying and arithmetics. In other cases it is natural to use explicit mutexes, and we could emphasise it in the docs.