1

I have aliases for radians and degrees that use float as the storage type.

When I convert between these two units I see the assembly promote the values to doubles and then back to floats when doing conversions.

Q: How can I make sure that all operations and conversions stay in floats?

My Code:

using radians_f = boost::units::quantity<boost::units::si::plane_angle, float>;
using degrees_f = boost::units::quantity<boost::units::degree::plane_angle, float>;

degrees_f to_degrees(const radians_f& angle) { return static_cast<degrees_f>(angle); }
radians_f to_radians(const degrees_f& angle) { return static_cast<radians_f>(angle); }

From compiler explorer I see the following assembly instructions: https://godbolt.org/z/Gnjr54dn6

  • cvtss2sd - Converts a single-precision floating-point value in the “convert-from” source operand to a double-precision floating-point value in the destination operand.

  • mulsd - Multiplies the low double-precision floating-point value in the second source operand by the low double-precision floating-point value in the first source operand.

  • cvtsd2ss - Converts a double-precision floating-point value in the “convert-from” source operand to a single-precision floating-point value

PS: I would not be surprised if I have defined my aliases or/and my conversion functions incorrectly.

CJCombrink
  • 3,738
  • 1
  • 22
  • 38

1 Answers1

1

I found a hacky workaround (which I'm sure can be "productionized" by making Boost Units compute the 57.x degrees per radian constant) to avoid the conversions to and from double, but it really highlights the fact that Boost Units is causing another surprising sort of overhead: memory loads and stores which aren't necessary if you use float directly, or even your own wrapper for float.

Demo: https://godbolt.org/z/afPE7baxT

So while the above shows one (unrefined) way to force calculations to stay as floats, if your real question is "How do I avoid overhead" you're still a bit far from nirvana.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • unfortunately using angles were the minimal reproducible example in the question of "How do I avoid overhead" since the problem applies to many other units that I need as well. – CJCombrink Nov 23 '21 at 10:51
  • @CJCombrink: Yeah, what I'm saying is that it looks like avoiding (all) overhead might require ditching Boost Units, based on the demo I made above. – John Zwinck Nov 23 '21 at 10:56
  • 1
    Having a destructor or a copy constructor in your wrapper can cause this suboptimality. – n. m. could be an AI Nov 23 '21 at 11:38