Floating Point Constants - Inlining Questions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Leslie Sanford

    Floating Point Constants - Inlining Questions

    I want to define a set of floating point constants using templates insteand
    of macros. I'd like to determine whether these constants are floats or
    doubles at compile time. In my header file, I have this:

    template<bool DoublePrecision >
    struct Constants
    {
    typedef double SampleType;

    static const double pi;
    static const double piDoubled;
    static const double SampleRateDefau lt;
    static const double DenormalOffset;
    };

    template<>
    struct Constants<false >
    {
    typedef float SampleType;

    static const float pi;
    static const float piDoubled;
    static const float SampleRateDefau lt;
    static const float DenormalOffset;
    };

    In my implementation file, I have this

    #include "Constants. h"

    const double Constants<true> ::pi = 3.1415926535897 9;
    const double Constants<true> ::piDoubled = Constants<true> ::pi * 2.0;
    const double Constants<true> ::SampleRateDef ault = 44100.0;
    const double Constants<true> ::DenormalOffse t = 1.0E-25;

    const float Constants<false >::pi = 3.141593f;
    const float Constants<false >::piDoubled = 6.283185f;
    const float Constants<false >::SampleRateDe fault = 44100.0f;
    const float Constants<false >::DenormalOffs et = 1.0E-25f;

    My question is whether the values definined here will ultimately be inlined
    by the compiler where they are used. They are definined in one compilation
    unit but will be used in other compilation units. Will this prevent them
    from being inlined? In other words, will this ultimately be less efficient
    than using macros?




  • blargg

    #2
    Re: Floating Point Constants - Inlining Questions

    In article <g7659k$df5$1@r egistered.motza rella.org>, "Leslie Sanford"
    <jabberdabber@b itemehotmail.co mwrote:
    I want to define a set of floating point constants using templates insteand
    of macros. I'd like to determine whether these constants are floats or
    doubles at compile time.
    [ ...]
    In my implementation file, I have this
    >
    #include "Constants. h"
    >
    const double Constants<true> ::pi = 3.1415926535897 9;
    [ ...]
    My question is whether the values definined here will ultimately be inlined
    by the compiler where they are used. They are definined in one compilation
    unit but will be used in other compilation units. Will this prevent them
    from being inlined? In other words, will this ultimately be less efficient
    than using macros?
    Probably. If the compiler knows the value where it's used, it can do
    constant propagation, for example

    float f( float n ) { return n * (pi/2); }

    could be compiled to a single multiply. With static constants defined
    elsewhere, it's going to be hard to compile it to anything except what's
    written.

    You don't need macros, though, just constants in a header file.

    #include "config.h" // typedef float/double Real;

    const Real pi = 3.1415926535897 9;
    ...

    You could also put the constants in inline member functions.

    template<typena me T>
    struct Constants
    {
    typedef T SampleType;

    static SampleType pi() { return 3.1415926535897 9; }
    };

    If treating them as values is important, you could make each a class which
    had an operator SampleType(). That should allow the compiler to optimize
    fully.

    template<typena me T>
    struct Constants
    {
    typedef T SampleType;

    struct pi_ {
    operator SampleType () const { return 3.1415926535897 9; }
    };

    static pi_ const pi;
    };

    template<typena me T>
    Constants<T>::p i_ const Constants<T>::p i;

    You could use a macro to generate the structs for each constant.

    Comment

    • James Kanze

      #3
      Re: Floating Point Constants - Inlining Questions

      On Aug 4, 7:49 am, "Leslie Sanford" <jabberdab...@b itemehotmail.co m>
      wrote:
      I want to define a set of floating point constants using
      templates insteand of macros. I'd like to determine whether
      these constants are floats or doubles at compile time. In my
      header file, I have this:
      template<bool DoublePrecision >
      struct Constants
      {
      typedef double SampleType;
      >
      static const double pi;
      static const double piDoubled;
      static const double SampleRateDefau lt;
      static const double DenormalOffset;
      };
      template<>
      struct Constants<false >
      {
      typedef float SampleType;
      >
      static const float pi;
      static const float piDoubled;
      static const float SampleRateDefau lt;
      static const float DenormalOffset;
      };
      In my implementation file, I have this
      #include "Constants. h"
      const double Constants<true> ::pi = 3.1415926535897 9;
      const double Constants<true> ::piDoubled = Constants<true> ::pi * 2.0;
      const double Constants<true> ::SampleRateDef ault = 44100.0;
      const double Constants<true> ::DenormalOffse t = 1.0E-25;
      const float Constants<false >::pi = 3.141593f;
      const float Constants<false >::piDoubled = 6.283185f;
      const float Constants<false >::SampleRateDe fault = 44100.0f;
      const float Constants<false >::DenormalOffs et = 1.0E-25f;
      My question is whether the values definined here will
      ultimately be inlined by the compiler where they are used.
      What does it mean to "inline" a double. A double is not code.

      And of course, what code the compiler generates will depend on
      the compiler (and the machine it is generating the code for).
      They are definined in one compilation unit but will be used in
      other compilation units. Will this prevent them from being
      inlined? In other words, will this ultimately be less
      efficient than using macros?
      The only way to find out is to measure both. And that will only
      give you an answer for one particular compiler.

      As a general rule, however: the more the compiler knows, the
      better it can do its job. Arranging for the constant to be
      visible in the translation unit (e.g. by making it the return
      value of an inline function) cannot generally hurt, and it may
      help for some compilers, on some machines.

      I might also add that on a lot of machines, whether you use
      float or double, or even if you mix them, makes no difference in
      terms of spead. So your best solution might be to just declare
      your constants as static doubles (or even long doubles) in a
      namespace, and forget the template and the class.

      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      Working...