semi lock-free Signals/Slots
Hi, I've been doing some testing with implementing a semi lock-free Signals/Slots library. Basically: 1. emits are lock-free thanks to atomic shared_ptr's/other atomic operations. 2. Only a single writer is allowed at a time, uses a mutex for locking. The primary goal is to improve low and no slot-count signal emit performance. In tests, I have been able to get substantial performance boosts (~2 to 5 times) on low slot-count signals, approaching the same performance as signals2 in low-contention (basically, single thread testing). I haven't tested high emit contention performance, though I suspect this library will excel quite well here because there is no locking on emit. The test implementation is still incomplete, and notably uses many C++11 features, though I don't think any of features I'm using can't be ported one way or another for C++03 support. Even if the library isn't used in full, some of the ideas might be implemented into the existing Signals2 library. link: https://github.com/helloworld922/signals3
On Wed, Jul 24, 2013 at 9:30 AM, Andrew Ho
1. emits are lock-free thanks to atomic shared_ptr's/other atomic operations. 2. Only a single writer is allowed at a time, uses a mutex for locking.
The primary goal is to improve low and no slot-count signal emit performance.
This is very interesting to me. I have two projects, one OSS and the other non-OSS which shares similar constructs built over boost.signals2. The oss have a gui part which backend could be reused in concurrent context and expose a central "hub" for communications from the backend to the outer world. (I was thinking about proposing this for addition in signal libraries but I don't know how to replace the tbb::concurrent_unordered_map which is necessary to implement this) Here is my oss use case: https://github.com/artofsequence/aos-designer/blob/develop/backend/include/a... (ignore the "source" things, it's specific to my use case) The unit tests: https://github.com/artofsequence/aos-designer/blob/develop/backend/test/even... (consider event::ProjectOpen and event::EditorOpen like if they were structs) My closed-source project (a complex game) uses the same system (without the "source" concept, so a bit simpler) but is in a more concurrent context, where multiple systems (which can be running in different threads either specific or by using a global thread pool - the one from tbb) Some systems provide such kind of hub in their interface to output messages or even for forwarding messages to another system; so it's a complex setup, but is based on this "hub". I'm interested in any way to avoid blocking as much as possible, so it looks like your solution is better than signals2 in this aspect. I read the readme and it looks like the library interface is close enough to signals2 to match my use case, so I could just replace signals2 in the implementation of my "hubs" to try signals3. However I will wait for some of the missing features before testing it. I need connection and scoped connection to work. Also, ====================
Design Goals ==================== The main design goal is observed by what signals/slots are typically used for: 1. Connecting/disconnecting slots is usually not that time critical. 2. Most signals either have no slots, or very few slots connected. 3. Signals may be invoked from multiple threads, and usually can be evaluated asynchronously. It seems like slots usually can be evaluated asynchronously, but they could be strongly ordered, too. In any case, only forward iteration is required for emitting a signal. 4. Emitting should be as fast as possible.
It looks like this matches exactly my closed source project. I'll follow your work, please notify me when you finish the connection and scoped connection so that I can help you test this in real context. Joel Lamotte
please notify me when you finish the connection and scoped connection so that I can help you test this in real context.
Thanks for the interest, connection and scoped_connection are basically done, though some features aren't implemented: 1. Assigning to a scoped connection doesn't disconnect the current connection. 2. Swap isn't implemented/specialized 3. Comparison operators aren't implemented.
participants (2)
-
Andrew Ho
-
Klaim - Joël Lamotte