Closed vpenades closed 6 years ago
There's a Fix32 type in the Experimental folder if you want to play with it. The big performance advantage would be multiplication because you could write it as simply the multiplication of two 64-bit integers and not have to deal with all the splitting and checking for overflow BS that Fix64 has to do (because there are no hardware 128-bit integers). Also in x86 of course it would be faster because the type fits in registers. Apart from that though I wouldn't expect much difference. Most of the perf. loss vs floating-point math is the poor codegen (lack of inlining, enregistering of function parameters etc.) as far as I can tell.
Good ideas about readonly struct and Min/Max functions. Note that Fix64 is fairly immune to those defensive copy issues because almost all the operations are static methods, but it could help for .ToString()
and .RawValue
.
Oh, there's a Fix32 already, I'll take a look at it!
You can specify an attribute so the compiler knows you want inlining:
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AgressiveInlining)]
public static void SomeMethod()
{
...
}
Yeah, and I just noticed it's mistakenly called Fix16 but it's really a 32-bit Q15.16 type. Use at your own risk, it's really a draft I didn't spend much time on. I played around with AgressiveInlining before but I know some people compile this for .NET 4 (Unity3D). Would be worth revisiting indeed.
@asik
I played around with AgressiveInlining before but I know some people compile this for .NET 4 (Unity3D).
There is already .NET 4.6 support in up-to-date Unity3D which support AggressiveInlining, so forgot worry about legacy for optimizations sake :) And, anyway, thanks for your work on FixedMath, please keep going!
I am working on imaging stuff, like triangle rasterization, etc, where I need fast, fixed point arithmetics within small range sizes (typically between -10000 to 10000) for fast line/triangle gradient calculation on images. Fixed64 is probably too big, but Fixed32 would be more than enough.
Performance wise, I don't know if on modern CPUs a Fixed32 would be faster than Fixed64... but if it is, it could be worth having a Fixed32 type.
Exploring the current code of Fixed64, I've found some details that I think could be improved:
INTEGER_MASK=0xffffffff00000000;
andFRACTIONAL_MASK = 0x00000000ffffffff;
that would definitely help porting Fixed64 to other sizes.long
andulong
, you could declare aliases like this:using RAWSIGNED = long;
andusing RAWUNSIGNED = ulong;
and use the aliases along the code, again, for the sake of porting to other sizes.public readonly struct { }
which enforces the struct to be inmutable; apparently this gives a lot of performance benefits, more hereFix64 Min(Fix64 a, Fix64 b);
and Fix64Max(Fix64 a, Fix64 b);
functions