As far as I understand, currently Math/MathF native code is compiled with /fp:fast (only on Windows) however, a pure C# code behaves more like /fp:precise
So it could be a problem for e.g. developers who develop games (or backends for them) where they want all floating point operations to be 100% repeatable on all clients/hardware or different software compiled in /fp:precise mode. E.g. online games with client-side physics.
However, most users don't care about it and could gain an additional performance from /fp:fast for both native and managed code.
/fp:fast mode for C# could allow us to apply the following optimizations in JIT (inspired by LLVM):
// could be:floatz=MathF.Tan(x);
This one doesn't really look useful but there can be more, need to check
See godbolt and sharplab playgrounds to compare all of these cases between .NET Core and clang/LLVM.
So we could have 3 modes: precise, mixed (current) and fast to set via some env variable e.g. COMPlus_FpMode=fast or an attribute [FloatingPointMode(FloatingPointModeOptions.Fast)] to be able to set the mode per method. Also, a runtime constant e.g.
// simdify only when fast math is allowed
The only problem - we would need a second version of Math internal calls compiled in /fp:precise mode. If it's a problem then two modes: mixed and fast.
PS: Since Mono has LLVM back-end all of these optimizations can be easily turned on there (but only globally):
I think, in general, it would be good to expose something like this long term. Developers have varying needs and sometimes precision is desired (and should be the default) and sometimes speed is desired instead.
I think in general, it should be easy enough to allow optimizations at a per-method level and that for a method users should be able to impact how System.Math calls operate. What isn't clear is how far that should be taken, such as if methods can opt into the caller's precision control when inlined (which may be desirable for some libraries).
I had thought we already had an issue along these lines, but I can't find it, so it probably doesn't yet exist.
What isn't clear is how far that should be taken, such as if methods can opt into the caller's precision control when inlined (which may be desirable for some libraries).
This is the tricky design issue, and not just for inlining but whether and how these decisions are made across methods, classes, assemblies, etc. I think a reasonable position can be taken and supported, but it will certainly require some design and discussion.