[libdispatch-dev] fastpath() and slowpath() usage

Dave Zarzycki zarzycki at apple.com
Sat Jul 17 13:30:27 PDT 2010


It has been my experience that the effect is the same. The compiler tracks all sorts of meta-data about variables being passed around code. For example: what type is a given variable named "x", whether the variable is const or not, whether the variable is initialized or not, etc. The expected value (overridden via __builtin_expect()) is just another piece of meta-data. Therefore, rather than tagging each and every branch, one can simply tag the value and let all of the subsequence branches be optimized the same way (as long as the variable isn't subsequently updated).

Having said that, the example below isn't a good technical example of why one would do this. The code below appears to be a practical attempt to maintain readability by keeping the width of the code to a reasonable length. *shrug*


On Jul 17, 2010, at 3:18 PM, Mark Heily wrote:

> I've noticed some strange usage of the fastpath() and slowpath() macros in the libdispatch sources. These are wrappers for the __builtin_expect() branch prediction macro and defined as:
>    #define fastpath(x)	((typeof(x))__builtin_expect((long)(x), ~0l))
>    #define slowpath(x)	((typeof(x))__builtin_expect((long)(x), 0l))
> Everything I have read about __builtin_expect() says that it should be used within a conditional expression, like this:
>    if (__builtin_expect(foo == NULL, 0)) {
>             /* fast path */
>    } else {
>             /* slow path */
>    }
> There are several cases in libdispatch where the __builtin_expect() macro is used separately from the conditional. Here's one example from semaphore.c:
>    dispatch_semaphore_t
>    dispatch_get_thread_semaphore(void)
>    {
> 	dispatch_semaphore_t dsema;
>        dsema = fastpath(_dispatch_thread_getspecific(dispatch_sema4_key));
>        if (!dsema) {
>       	        while (!(dsema = dispatch_semaphore_create(0))) {
>               	        sleep(1);
>               	}
>    	}
>       _dispatch_thread_setspecific(dispatch_sema4_key, NULL);
>       return dsema;
>    }
> Can anyone explain the reason for using __builtin_expect() in this manner, and what the practical effect is?
> Thanks,
> - Mark
> _______________________________________________
> libdispatch-dev mailing list
> libdispatch-dev at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev

More information about the libdispatch-dev mailing list