Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

request for Fixed32 too #16

Closed
vpenades opened this issue Apr 10, 2018 · 4 comments
Closed

request for Fixed32 too #16

vpenades opened this issue Apr 10, 2018 · 4 comments

Comments

@vpenades
Copy link

vpenades commented Apr 10, 2018

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:

  • Some constants could be predefined like INTEGER_MASK=0xffffffff00000000; and FRACTIONAL_MASK = 0x00000000ffffffff; that would definitely help porting Fixed64 to other sizes.
  • Instead of using long and ulong, you could declare aliases like this: using RAWSIGNED = long; and using RAWUNSIGNED = ulong; and use the aliases along the code, again, for the sake of porting to other sizes.
  • there's a new struct feature for c# 7.2 which is declaring a public readonly struct { } which enforces the struct to be inmutable; apparently this gives a lot of performance benefits, more here
  • Missing Fix64 Min(Fix64 a, Fix64 b); and Fix64 Max(Fix64 a, Fix64 b); functions
@asik
Copy link
Owner

asik commented Apr 10, 2018

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.

@vpenades
Copy link
Author

vpenades commented Apr 10, 2018

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()
{
...
}

@asik
Copy link
Owner

asik commented Apr 10, 2018

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.

@Krakean
Copy link

Krakean commented Apr 15, 2018

@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!

@asik asik closed this as completed Apr 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants