I wrote a small test program where a function with two arguments (one int, one void *) is called from a timed for loop. Results below. This is with -O2. lts@today aesop % tests/blocking-overhead (master‣2…) Making 40000000 calls. Starting regular test... regular calls: 9.53674e-07 (2.38419e-14 / call) Starting blocking test... blocking calls: 2.23765 (5.59412e-08 / call) First number of total time in seconds, second is / call. I haven't looked at the assembler output to make sure that the compiler isn't inlining the regular call or just dropping it all together. (The only thing done within the call is an assignment to a variable). I haven't tried moving the function in another object file (which would make inlining much much for a compiler (and impossible for gcc)). I'm going to check the assembler output first. I did put a malloc()/free() in the regular call, just as a test to see how much the memory allocations contribute to the time. For the results below, 'regular calls' refers to a non-blocking call doing a 'free (malloc (100))', while the aesop blocking call was not modified. Making 40000000 calls. Starting regular test... regular calls: 0.946443 (2.36611e-08 / call) Starting blocking test... blocking calls: 2.24125 (5.60312e-08 / call) Since we cannot really get rid of the malloc/free except in certain special cases, this basically shows the best we can possibly hope to do. Using tcmalloc (Google's alternative malloc library) this reduces to: Making 40000000 calls. Starting regular test... regular calls: 0.664825 (1.66206e-08 / call) Starting blocking test... blocking calls: 1.47122 (3.67805e-08 / call) (or about ~30% improvement for both the simple malloc/free and the aesop blocking call). Remember: this is a synthetic benchmark! Results not guaranteed. No refunds if you don't see 30% improvement. :-) Adding 'pthread_mutex_lock' and 'pthread_mutex_unlock' to the REGULAR call (so that it contains both the malloc and pthread operations) changes the results to: Making 40000000 calls. Starting regular test... regular calls: 1.15233 (2.88083e-08 / call) Starting blocking test... blocking calls: 1.50091 (3.75227e-08 / call) Instead of using a pthread mutex, using OPA compare-and-swap on an integer makes it: Making 40000000 calls. Starting regular test... regular calls: 0.782022 (1.95505e-08 / call) Starting blocking test... blocking calls: 1.48202 (3.70506e-08 / call) Note that aesop internally already uses OPA atomics in certain places, but not everywhere. So, summary (numbers are seconds / call): regular call: 2.384e-14 regular with malloc/free: 2.366e-08 regular, malloc/free, tcmalloc: 1.662e-08 regular, malloc/free,tcmalloc,mutex: 2.881e-08 regular, malloc/free,tcmalloc,OPA cas: 1.995e-08 aesop blocking: 5.594e-08 aesop blocking, tcmalloc: 3.678e-08 In all cases, the aesop generated code still contains ae_debug_blocking () calls which translate to 'if (aesop_dbg_blocking) { ...}', but I don't think this affects the performance too much. Also: gcc 4.5.3, glibc 2.13-r4. Test code is in the repository. Dries
participants (1)
-
Dries Kimpe