summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorJulian Taylor <jtaylor.debian@googlemail.com>2013-08-09 19:30:53 +0200
committerJulian Taylor <jtaylor.debian@googlemail.com>2013-08-09 21:23:06 +0200
commite91acdb17b2a9c65a0fb9b7a97764aa375819784 (patch)
tree1d6d0981d1efdf0ca05b0ddd2f64352a6186d77d /numpy/core
parent433f8968e4df729093ca627546a647a31fc2ed8c (diff)
downloadnumpy-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.h18
-rw-r--r--numpy/core/setup_common.py1
-rw-r--r--numpy/core/src/multiarray/common.h12
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;
+ }
}