diff options
author | Julian Taylor <jtaylor.debian@googlemail.com> | 2013-08-09 19:30:53 +0200 |
---|---|---|
committer | Julian Taylor <jtaylor.debian@googlemail.com> | 2013-08-09 21:23:06 +0200 |
commit | e91acdb17b2a9c65a0fb9b7a97764aa375819784 (patch) | |
tree | 1d6d0981d1efdf0ca05b0ddd2f64352a6186d77d /numpy/core | |
parent | 433f8968e4df729093ca627546a647a31fc2ed8c (diff) | |
download | numpy-e91acdb17b2a9c65a0fb9b7a97764aa375819784.tar.gz |
ENH: add NPY_LIKELY and NPY_UNLIKELY macros for branching hints
Use it for npy_is_aligned expecting alignments of the power of two.
Cuts down the time spent in _IsAligned by the testsuite relative
to the rest of multiarray.so from 0.6% to 0.4%
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/include/numpy/npy_common.h | 18 | ||||
-rw-r--r-- | numpy/core/setup_common.py | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.h | 12 |
3 files changed, 28 insertions, 3 deletions
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h index ac2e631e6..e5fd09e91 100644 --- a/numpy/core/include/numpy/npy_common.h +++ b/numpy/core/include/numpy/npy_common.h @@ -18,6 +18,24 @@ #define NPY_GCC_UNROLL_LOOPS #endif +/* + * give a hint to the compiler which branch is more likely or unlikely + * to occur, e.g. rare error cases: + * + * if (NPY_UNLIKELY(failure == 0)) + * return NULL; + * + * the double !! is to cast the expression (e.g. NULL) to a boolean required by + * the intrinsic + */ +#ifdef HAVE___BUILTIN_EXPECT +#define NPY_LIKELY(x) __builtin_expect(!!(x), 1) +#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define NPY_LIKELY(x) (x) +#define NPY_UNLIKELY(x) (x) +#endif + #if defined(_MSC_VER) #define NPY_INLINE __inline #elif defined(__GNUC__) diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py index 9f745e965..9a630225d 100644 --- a/numpy/core/setup_common.py +++ b/numpy/core/setup_common.py @@ -111,6 +111,7 @@ OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'), ("__builtin_isfinite", '5.'), ("__builtin_bswap32", '5u'), ("__builtin_bswap64", '5u'), + ("__builtin_expect", '5, 0'), ] # gcc function attributes diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h index 636d9c67d..82b66123c 100644 --- a/numpy/core/src/multiarray/common.h +++ b/numpy/core/src/multiarray/common.h @@ -1,5 +1,6 @@ #ifndef _NPY_PRIVATE_COMMON_H_ #define _NPY_PRIVATE_COMMON_H_ +#include <numpy/npy_common.h> #define error_converting(x) (((x) == -1) && PyErr_Occurred()) @@ -71,11 +72,16 @@ offset_bounds_from_strides(const int itemsize, const int nd, static NPY_INLINE int npy_is_aligned(const void * p, const npy_uintp alignment) { - /* test for the and is still faster than a direct modulo */ - if ((alignment & (alignment - 1)) == 0) + /* + * alignment is usually a power of two + * the test is faster than a direct modulo + */ + if (NPY_LIKELY((alignment & (alignment - 1)) == 0)) { return ((npy_uintp)(p) & ((alignment) - 1)) == 0; - else + } + else { return ((npy_uintp)(p) % alignment) == 0; + } } |