I wanted to know what would be better/faster to use POSIX calls like pthread_once()
and sem_wait()
or the dispatch_* functions, so I created a litt
sem_wait() and sem_post() are heavy weight synchronization facilities that can be used between processes. They always involve round trips to the kernel, and probably always require your thread to be rescheduled. They are generally not the right choice for in-process synchronization. I'm not sure why the named variants would be slower than the anonymous ones...
Mac OS X is actually pretty good about Posix compatibility... But the Posix specifications have a lot of optional functions, and the Mac doesn't have them all. Your post is actually the first I've ever heard of pthread_barriers, so I'm guessing they're either relatively recent, or not all that common. (I haven't paid much attention to pthreads evolution for the past ten years or so.)
The reason the dispatch stuff falls apart under forced extreme contention is probably because under the covers the behavior is similar to spin locks. Your dispatch worker threads are very likely wasting a good chunk of their quanta under the optimistic assumption that the resource under contention is going to be available any cycle now... A bit of time with Shark would tell you for sure. The take-home point, though, should be that "optimizing" the thrashing during contention is a poor investment of programmer time. Instead spend the time optimizing the code to avoid heavy contention in the first place.
If you really have a resource that is an un-avoidable bottleneck within your process, putting a semaphore around it is massively sub-optimal. Put it on its own serial dispatch queue, and as much as possible dispatch_async blocks to be executed on that queue.
Finally, dispatch_once() is faster than pthread_once() because it's spec'd and implemented to be fast on current processors. Probably Apple could speed up the pthread_once() implementation, as I suspect the reference implementation uses pthread synchronization primitives, but... well... they've provided all of the libdispatch goodness instead. :-)