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