diff options
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; + } } |