From 585a0b464cf8ce81b2c779c7223a7f8163726169 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 20 Mar 2015 01:32:56 +1100 Subject: [PATCH] maths: make sign query inline code which needs this function tends to require a fairly simple implementation inline for the optimiser to reach more successfully. we tended to generate function calls to this which slowed this inner loops. --- maths.cpp | 25 ------------------------- maths.hpp | 4 +++- maths.ipp | 12 ++++++++++++ 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/maths.cpp b/maths.cpp index 9e89ff88..2afc319d 100644 --- a/maths.cpp +++ b/maths.cpp @@ -152,31 +152,6 @@ template uint32_t round_pow2 (uint32_t); template uint64_t round_pow2 (uint64_t); -//----------------------------------------------------------------------------- -template -int -sign (T val) { - return val >= 0 ? 1 : -1; -} - - -template <> -int -sign (float val) { - return static_cast (copysign (1.0f, val)); -} - - -template <> -int -sign (double val) { - return static_cast (copysign (1.0, val)); -} - - -template int sign (int); - - //----------------------------------------------------------------------------- // Simple instantiations. Some functions aren't used internally to the library // so it's easier to instantiate early and check for broken code at library diff --git a/maths.hpp b/maths.hpp index b5bbf50e..5f0e0adf 100644 --- a/maths.hpp +++ b/maths.hpp @@ -21,6 +21,7 @@ #define __MATHS_HPP #include "debug.hpp" +#include "types/traits.hpp" #include #include @@ -104,7 +105,8 @@ digits [[gnu::pure]] (const T& value); //----------------------------------------------------------------------------- template -int sign [[gnu::pure]] (T val); +typename try_signed::type +sign [[gnu::pure]] (T val); //----------------------------------------------------------------------------- diff --git a/maths.ipp b/maths.ipp index 482aaacc..207113ff 100644 --- a/maths.ipp +++ b/maths.ipp @@ -45,6 +45,18 @@ pow (T x, unsigned y) } +///---------------------------------------------------------------------------- +/// Return a unit type with a sign that matches the provided value +/// +/// This really needs to be inline for performance as it's used in a few inner +/// loops where the possibility of a function call is a deal breaker. +template +typename try_signed::type +sign (T val) { + return val >= 0 ? T{1} : T{-1}; +} + + //----------------------------------------------------------------------------- template <> struct constants