-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: "strictfp"/"fastfp" modifier #3896
Comments
Just out of curiosity is there a real need for something like this? Note that the modifier was added to Java 1.2 because prior to that it was the default behavior, but it was inherently slower and more error prone, so the default behavior was changed and this modifier added. And my understanding is that the |
I believe so. This should be viewed as the equivalent of compiling a C++ program with a fp:strict flag. It might be slower, but predictable results are important in many applications. Especially in games where different hardware producing different results can lead to synchronization issues. Currently, there is a work around in C# but its awful, and requires you to basically write your code like so: public float SomeComputations(float x, float y)
{
var s1 = (float)(x-y);
var s2= (float)(y-x);
var s3= (float)(s1*s2);
return (float)s3*s3;
} If you throw in a cast at every step, the JIT will truncate at each step. Another alternative is to stick your working variable into an array, which should round trap the operation through memory (which is slow). However, if you only stick with SSE registers you don't have to worry about the extra precision. Also before someone invokes Eric Lippert, this is an awful answer http://stackoverflow.com/a/14864871. Using integers is hardly an acceptable solution. |
So from a perspective of implementation, does the spec guarantee that those casts would be honored by the JIT, or would we need changes to the CLR/JIT such as a pseudo-attribute? If the casts can be expected to be honored then the implementation sounds relatively simple; the compiler can just emit additional |
The spec does guarantee that the casts are honored. See the following quote (important part in bold at the end). From ECMA-335, §I.12.1.3 Handling of floating-point data types:
|
Er, that bold text to me reads that these casts are explicitly honored by the spec. |
@HaloFour We agree: that's what I said :) |
Oops, my reading comprehension ain't so good on a Monday morning. So it does sound like this feature could be handled purely within the language just by having the compiler spit out a slew of those IL opcodes. |
That's true, the compiler can just choose to emit those additional opcodes. Unfortunately, there is no guarantee about the trigonometric and transcendental functions. Java has a |
We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages. See also #18002 for a general discussion of closing and/or moving language issues out of this repo. |
I'm not sure which repo this issue belongs in, as it is both a language and compiler feature.
Currently, the CLR makes no guarantee about the result of floating point operations. In cases where applications communicate to each other and need to simulate floating point results locally, the lack of strict mode causes their to be differences in the result of calculation.
I propose a modifier that can be placed on either a class, method or as a standalone block.
This should Similar to the method modifier available in Java. When strict mode is enabled, anything computed on a single or double would be truncated to either 32 or 64 bits of precision, and when a fused operation like a multiple and add operation would be called each should be called separately to avoid producing a non-reproducible result.
All of these operations should be done using SSE operators, which I believe should always be reproducible.
As a nice to have, it'd be good if the trig functions were to switch to a strict implementation as well if the current implementation is not.
As part of this proposal, I also suggest adding the opposite modifier "fastfp", when in a block that would be in strict mode, "fastfp" would result in switching back to the normal "fast" behavior.
The text was updated successfully, but these errors were encountered: