Version 24, last updated by metlos at May 16, 2009 03:08 UTC
beacons
thread-safe signals & slots in C++. Aims to be faster than Qt by creating a specialized library not “cluttered” by the GUI support features. Inspired by boost::signals and fastsig but adding the thread safety to the mix.
Currently only Linux is supported as that’s where I develop the thing and don’t have access to any other OS. But since all the dependencies are cross-platform and the library itself shouldn’t use any platform specific features, it shouldn’t be too difficult to port it.
Features
- thread-safe, see ThreadSafety,
- type safe templated signals with the same syntax as boost::signals, see LibraryUsage,
- function pointers, functors and instance methods supported as slots for the signals,
- arbitrary collection of slot’s return values using user defined combiners, see UsingCombiners.
Speed comparison for a single threaded scenario (#define BEACONS_SINGLE_THREADED which makes some optimizations on the signal invocation) (using this comparison program modified to include fastsig and beacons) (compiled with -Wall -O3, run on AMD Sempron 2800, 512MB RAM):
===== 1000000 Total Calls ===== Num Slots Calls/Slot Boost SigC FastSig beacons --------- ---------- ------- ------- ------- ------- 1 1000000 0.3514 0.2530 0.0670 0.1604 10 100000 0.0828 0.0422 0.0231 0.0584 50 20000 0.0591 0.0234 0.0179 0.0496 100 10000 0.0584 0.0206 0.0191 0.0492 250 4000 0.0605 0.0213 0.0209 0.0525 500 2000 0.0672 0.0255 0.0255 0.0610 1000 1000 0.0688 0.0312 0.0334 0.0664 5000 200 0.1957 0.1123 0.1220 0.2256 10000 100 0.1986 0.1228 0.1301 0.2262 50000 20 0.1986 0.1226 0.1304 0.2281 100000 10 0.2146 0.1166 0.1265 0.2321 500000 2 0.2071 0.1216 0.1281 0.2319
If we run the test with beacons in the default “thread-safe” mode, we get a much worse picture due to the overhead imposed by concurrent access checks:
===== 1000000 Total Calls =====
Num Slots Calls/Slot Boost SigC FastSig beacons
--------- ---------- ------- ------- ------- -------
1 1000000 0.3450 0.2369 0.0677 1.1244
10 100000 0.0832 0.0404 0.0238 0.4253
50 20000 0.0595 0.0230 0.0189 0.3777
100 10000 0.0579 0.0225 0.0203 0.3705
250 4000 0.0601 0.0210 0.0217 0.3843
500 2000 0.0675 0.0268 0.0269 0.4184
1000 1000 0.0711 0.0288 0.0311 0.6036
5000 200 0.1977 0.1232 0.1301 1.0957
10000 100 0.1972 0.1172 0.1274 1.0680
50000 20 0.1981 0.1219 0.1304 1.0961
100000 10 0.1971 0.1173 0.1279 1.0897
500000 2 0.1985 0.1168 0.1275 1.3767
Boost, sigc++ and fastsig don’t support multi-threaded signals, so for comparison of concurrent signal invocations we can only compare with Qt.
To test the concurrent speed the following test was created. 1 to 10 “sender” threads invoke a signals (1 signal per sender) connected to a single receiver “living” in its own thread:
3628800 receiver invocations
Threads Qt beacons
--------- --------- --------
1 11.911721 4.186925
2 9.445567 3.544994
3 9.503437 3.266201
4 9.589862 3.466755
5 9.452489 3.494147
6 9.488123 3.519546
7 9.434790 3.563731
8 9.282081 3.676266
9 9.329531 3.801608
10 9.272442 3.950309
This shows more than anything else that there are probably some interesting optimizations for larger number of threads in Qt but it doesn’t help it being approximately 2.5 times slower than beacons.
Dependencies
- boost_thread (http://www.boost.org)
- atomic_ops (http://www.hpl.hp.com/research/linux/atomic_ops)