diff options
author | Julian Taylor <jtaylor.debian@googlemail.com> | 2013-05-06 18:09:44 +0200 |
---|---|---|
committer | Julian Taylor <jtaylor.debian@googlemail.com> | 2013-05-06 19:20:09 +0200 |
commit | c8228126ac0a00e058fb5a2c6106184b03d3fbb0 (patch) | |
tree | a0952c6696a99ab53e16cf104fa3842c7129b47b /numpy/core | |
parent | 7d76c744007afa6bb3af3b9d9fb64a65201e3635 (diff) | |
download | numpy-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.h | 48 |
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 |