summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorJulian Taylor <jtaylor.debian@googlemail.com>2013-05-06 18:09:44 +0200
committerJulian Taylor <jtaylor.debian@googlemail.com>2013-05-06 19:20:09 +0200
commitc8228126ac0a00e058fb5a2c6106184b03d3fbb0 (patch)
treea0952c6696a99ab53e16cf104fa3842c7129b47b /numpy/core
parent7d76c744007afa6bb3af3b9d9fb64a65201e3635 (diff)
downloadnumpy-c8228126ac0a00e058fb5a2c6106184b03d3fbb0.tar.gz
ENH: use intrinsics for isnan, isfinite and isinf
Use of intrinsics avoids expensive function calls in tight loops on x86 cpus where these operations are implemented in hardware while still retaining same portability. More than doubles performance of np.isnan/isinf/isfinite.
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/include/numpy/npy_math.h48
1 files changed, 32 insertions, 16 deletions
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
index a7c50f6e6..bfb35a1a0 100644
--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
@@ -148,33 +148,49 @@ double npy_spacing(double x);
/*
* IEEE 754 fpu handling. Those are guaranteed to be macros
*/
-#ifndef NPY_HAVE_DECL_ISNAN
- #define npy_isnan(x) ((x) != (x))
+
+/* use a builtins to avoid function calls in tight loops
+ * documented only on 4.4, but available in at least 4.2 */
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+ #define npy_isnan(x) __builtin_isnan(x)
#else
- #ifdef _MSC_VER
- #define npy_isnan(x) _isnan((x))
+ #ifndef NPY_HAVE_DECL_ISNAN
+ #define npy_isnan(x) ((x) != (x))
#else
- #define npy_isnan(x) isnan((x))
+ #ifdef _MSC_VER
+ #define npy_isnan(x) _isnan((x))
+ #else
+ #define npy_isnan(x) isnan(x)
+ #endif
#endif
#endif
-#ifndef NPY_HAVE_DECL_ISFINITE
- #ifdef _MSC_VER
- #define npy_isfinite(x) _finite((x))
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+ #define npy_isfinite(x) __builtin_isfinite(x)
+#else
+ #ifndef NPY_HAVE_DECL_ISFINITE
+ #ifdef _MSC_VER
+ #define npy_isfinite(x) _finite((x))
+ #else
+ #define npy_isfinite(x) !npy_isnan((x) + (-x))
+ #endif
#else
- #define npy_isfinite(x) !npy_isnan((x) + (-x))
+ #define npy_isfinite(x) isfinite((x))
#endif
-#else
- #define npy_isfinite(x) isfinite((x))
#endif
-#ifndef NPY_HAVE_DECL_ISINF
- #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+ #define npy_isinf(x) __builtin_isinf(x)
#else
- #ifdef _MSC_VER
- #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+ #ifndef NPY_HAVE_DECL_ISINF
+ #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
#else
- #define npy_isinf(x) isinf((x))
+ #ifdef _MSC_VER
+ #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+ #else
+ #define npy_isinf(x) isinf((x))
+ #endif
#endif
#endif