简体   繁体   中英

Need to use floats for performance yet want double-precision calculations

MonoGame is an open-source version of Microsoft's XNA. It's a framework for building cross-platform games.

It has a number of mathematical types such as Vector and Quaternion.

I am a bit baffled by they way they are using doubles and floats.

So far I have gathered the following information:

  • floats are likely to be more efficient than doubles;
  • doubles have higher precision than floats.

Here is a kind of method that confuses me:

/// <summary>
/// Transforms a single Vector2, or the vector normal (x, y, 0, 0), by a specified Quaternion rotation.
/// </summary>
/// <param name="value">The vector to rotate.</param><param name="rotation">The Quaternion rotation to apply.</param>
public static Vector2 Transform(Vector2 value, Quaternion rotation)
{
  float num1 = rotation.X + rotation.X;
  float num2 = rotation.Y + rotation.Y;
  float num3 = rotation.Z + rotation.Z;
  float num4 = rotation.W * num3;
  float num5 = rotation.X * num1;
  float num6 = rotation.X * num2;
  float num7 = rotation.Y * num2;
  float num8 = rotation.Z * num3;
  float num9 = (float) ((double) value.X * (1.0 - (double) num7 - (double) num8) + (double) value.Y * ((double) num6 - (double) num4));
  float num10 = (float) ((double) value.X * ((double) num6 + (double) num4) + (double) value.Y * (1.0 - (double) num5 - (double) num8));
  Vector2 vector2;
  vector2.X = num9;
  vector2.Y = num10;
  return vector2;
}

Why not use either doubles of floats throughout (eg inline num1..num8 as double expressions into num9 and num10)?

The key point here is that a series of calculations are all being done in double , without rounding the intermediate results to float . That may result in the final float result being closer to the one that would have resulted from infinitely precise arithmetic, given the float inputs.

There is little performance difference between 32-bit and 64-bit floating point arithmetic. There is a big space difference between storing 32-bit and storing 64-bit.

Halving the number of bytes to store each value may make a big difference in performance. It effectively doubles size of each cache, and the bandwidth of each data transfer path.

floats are likely to be more efficient than doubles

This used to be true. You have to go back decades, around the time that graphics algorithms were first designed and had to run on hardware that wasn't very good at accelerating floating point math. Either because it simply didn't have any and it had to be emulated in software, making single precision automatically faster. Or because it ran on specially built graphics terminals, the kind that had a custom graphics processor that couldn't handle anything better than single-precision floats. An FPU wasn't guaranteed on-board until the first Pentium, add a handful of years for a programmer to count on his software running on a machine that has one, a mere 16 years ago.

Of course all the known graphics algorithm were designed to use single-precision. Getting them re-written to use double-precision requires an enormous amount of courage . Because that will inevitably introduce bugs, such an algorithm will not behave the same way as the single-precision one. Floating point math is not precise math. Just the fact that the outcome is different is enough to generate a bug report, the single-precision version will be held-up as the normative standard because that's what everybody has been using. With absolutely nothing the programmer can do to make the user happy, other than recommending "don't use it".

So graphics code doesn't use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM