Deterministic fixed-point port, open source

Discuss topics related to BEPUphysics or physics engine development.
sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Deterministic fixed-point port, open source

Post by sAm_vdP » Sun Feb 11, 2018 12:24 pm

EDIT: Source code is now available at https://github.com/sam-vdp/bepuphysics1int

Hi everyone,

like test44x I was looking for a deterministic fixed-point physics engine and have started porting BEPUv1 to use integer math. I followed the instructions from the previous thread quite closely and the port seems to work so far. I intend to make this open-source ASAP, but I have some stylistic questions I would like to discuss first.

Also, Norbo, thank you so much for your work on BEPUphysics. Going through the entire codebase with search and replace really makes you appreciate the effort that went into it :)

Questions
1. EntityStateChange
In EntityStateWriteBuffer there is a struct EntityStateChange that has some FieldOffset annotations for Windows builds. These broke the build after using the fixed-point type instead of float, I assume because Vector3 and Quaternion doubled in size? I don't quite understand what the annotations do, particularly the overlapping offset for the first two fields. For now I have removed them and it seems like nothing broke. What would be the proper fix there, though?

2. Fixed-point library
I am using https://github.com/asik/FixedMath.Net for the fixed-point operations. I have slightly modified the source and will probably add some performance tweaks later. Which begs the question, where to put the modified source?
  1. Fork on github and maintain separately - makes building BEPU more of a hassle
  2. Add FixedMath project to BEPU solution - requires user to a another reference to their project
  3. Add FixedMath source into BEPUutilities project
I am leaning towards 3, as I couldn't find a way to add a transitive dependency, or did I miss something?

3. Numerical constants in BEPU
There are a good number of float and int constants in the BEPU source and the question is how to translate those to the Fix64 type. Right now I am using a bit of a mixed approach:
  • I've added an implicit cast from int to Fix64. All float instances in the source without a fractional part (like 1f) were replaced with their int counterparts.
  • I've added an implicit cast from decimal to Fix64 and replaced float values with decimal for all initializers.
  • For float constants used inside the code (stuff like x > 0.1f) I have added static constants in a helper class, to avoid the cost of converting from decimal to Fix64 inline.
This seems like kind of a messy way to do this and I'm not sure if I should convert all floats to decimal and drop the static helper class?

4. Fixed-point Pow() function?
FixedMath.Net doesn't have Pow(), do you have a recommendation for a good algorithm?

I want to clean up the code a bit, add some tests for performance and determinism, but I expect I'll put the code on github some time next week.

Thank you all for your and in advance for your help.

Cheers,
Bart
Last edited by sAm_vdP on Tue Feb 27, 2018 11:25 am, edited 1 time in total.

Norbo
Site Admin
Posts: 4517
Joined: Tue Jul 04, 2006 4:45 am

Re: Deterministic fixed-point port, open source

Post by Norbo » Sun Feb 11, 2018 7:56 pm

1. EntityStateChange
EntityStateChange is a union type designed to hold one of two possible data types. Since it can't hold both types at once, it's okay for them to overlap in memory. In other words, the explicit layout and field offsets were simply a mild memory optimization.

You can either set the field offsets to compensate for the new types' larger size, or you can just leave off the attributes completely. The performance impact is trivial, and that feature is almost never used anyway. (It doesn't even exist in v2!)
2. Fixed-point library
That's a little tricky. I might suggest creating a .NET Standard 2.0 nuget for it, but publishing a custom nuget for a third party project isn't ideal.

I'd lean toward adding the project to the solution. It does require more work for someone who is directly referencing the projects, but it maintains unique project settings that would be otherwise difficult to work with in a combined BEPUutilities-FixedMath project.
3. Numerical constants in BEPU
It's hard to say without deeper analysis, but the static helper's extra complexity may be worth it. I doubt the JIT would manage to generate efficient decimal->Fix64 machine code even for a constant literal, and these values are often epsilons in tight loops.
4. Fixed-point Pow() function?
One relatively simple option is to split the exponent into an integer and a value from 0 to 1, making use of x^(a + b) = x^a * x^b. The integer power can be computed fairly straightforwardly (or not- tricky fast implementations do exist), and the remaining fraction can be handled by a series approximation.

Another common option is to implement pow on top of a single known base, such as e or 2, given that x^y = base^(logbase(x) * y). Then you have to come up with a speedy implementation for the base^exponent and logbase(x) parts.

You could use the same splitting trick as before for base^exponent. If you choose 2 as the base, the integer part becomes trivial, and the series approximation also gets more constant terms. Making a good log function is more difficult; it would probably look something like this: https://stackoverflow.com/questions/979 ... 5#44232045

Good luck with everything!

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Re: Deterministic fixed-point port, open source

Post by sAm_vdP » Tue Feb 13, 2018 7:38 am

Thank you for your help!

I managed to get the Pow-function implemented, but now I've hit some more issues. Most of the demos work as expected, if a bit slower, but two behave weirdly:

1. The moving object in the PathFollowingDemo is a bit jittery, I guess that's just a lack of precision converting from the double to the fixed precision. Do you think using decimal only for the path interpolation would be feasible? I believe that is supposed to be cross-platform deterministic, right?

2. The spring-loaded platform in the EarthQuakeDemo starts shaking increasingly more and eventually flies away. Do you have an idea what might be causing this?

Again, thank you so much for your work and your help!

Norbo
Site Admin
Posts: 4517
Joined: Tue Jul 04, 2006 4:45 am

Re: Deterministic fixed-point port, open source

Post by Norbo » Tue Feb 13, 2018 8:29 pm

1. The moving object in the PathFollowingDemo is a bit jittery
I'm not sure if decimal can be relied upon for cross platform determinism, especially if you're dealing with different runtimes. However, I would be surprised if the jitteriness is actually caused by a lack of precision; I would assume the problem is elsewhere.
2. The spring-loaded platform in the EarthQuakeDemo starts shaking increasingly more and eventually flies away. Do you have an idea what might be causing this?
Probably something small like a sign error in the DistanceJoint.Update, ExclusiveUpdate, or SolveIteration functions. Hard to say for sure.

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Re: Deterministic fixed-point port, open source

Post by sAm_vdP » Thu Feb 15, 2018 11:31 am

EDIT: Problems solved (for now), just posting for general info.

As always, thank you for your brilliant help!
However, I would be surprised if the jitteriness is actually caused by a lack of precision; I would assume the problem is elsewhere.
Spot on. FixedMath uses a pretty rough approximation for Atan2, so my Acos was sloppy, so Quaternion.Slerp is visibly jerky. Using Atan with a Euler series approximation is a lot more precise.

Matrix-inversion overflow
The trouble just doesn't end though :( The matrix invert functions return incorrect results when matrix components get a bit larger (e.g. the InertiaTensor of the platform in the EarthQuakeDemo). The determinant of the matrix overflows the 2^31 range of the Fix64 type rather easily. I am looking into alternative ways to invert the matrix, but seeing that it is used in a number of per-frame functions it seems it would have to be pretty fast.
I'll try implementing Gauss-elimination and see how that performs, but if you have other ideas, I would be very happy to hear them!

Please do not feel obliged to spend your time on this! I appreciate your help very much, but I am very aware that you have a lot more exciting things to do.

EDIT:Using the Gauss elimination fixed both platform falling through the ground as well as the constraints blowing up.

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

[RELEASED] Deterministic fixed-point port, open source

Post by sAm_vdP » Mon Feb 26, 2018 9:16 am

I have released the current state of the fork: https://github.com/sam-vdp/bepuphysics1int

All existing BEPUphysics demos work as expected. However, the performance is still quite bad, about 4 times slower than the float version.

I am getting quite different profiler results when using sampling or instrumentation. Norbo, you seem to be an expert on writing fast code, what tools do you use when optimizing your code?

Cheers!

Norbo
Site Admin
Posts: 4517
Joined: Tue Jul 04, 2006 4:45 am

Re: Deterministic fixed-point port, open source

Post by Norbo » Mon Feb 26, 2018 8:23 pm

Nice work!
what tools do you use when optimizing your code?
A few of the most common:
1) VS's default profiler for very high level investigation and sanity checks. Sampling profiler modes will tend to be less warped by overhead in small functions.

2) For anything more in depth, VTune on Intel and CodeXL on AMD. These can be critical when trying to figure out what part of the pipeline is actually bottlenecking. And if you use them on v1, you'll see why bepuphysics v2 is an order of magnitude faster :)

3) Microbenchmarks. While these can be a little misleading (e.g. spending a week on optimizing some math to find that it provides a 0% speedup, since when executed in its full context it is completely memory bound), but when you already have reason to believe the issue is local, they can be a very useful tool.

4) Manually examining the post-JIT disassembly. There isn't always a lot you can do with the disassembly, but it's sometimes useful to check for easily prevented pitfalls. Historically, these tend to be related to a lack of inlining, incomplete inlining of pass-by-value parameters (very common with operators), unnecessary zero initialization, and other similar codegen surprises.

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Re: Deterministic fixed-point port, open source

Post by sAm_vdP » Tue Feb 27, 2018 11:23 am

Thank you for the hints! The disassembly in particular looks interesting, if a bit overwhelming at first.

I think one relative low hanging fruit should be the fixed point multiplication:

Code: Select all

		
var xl = x.RawValue;
var yl = y.RawValue;

var xlo = (ulong)(xl & 0x00000000FFFFFFFF);
var xhi = xl >> FRACTIONAL_PLACES;
var ylo = (ulong)(yl & 0x00000000FFFFFFFF);
var yhi = yl >> FRACTIONAL_PLACES;

var lolo = xlo * ylo;
var lohi = (long)xlo * yhi;
var hilo = xhi * (long)ylo;
var hihi = xhi * yhi;

var loResult = lolo >> FRACTIONAL_PLACES;
var midResult1 = lohi;
var midResult2 = hilo;
var hiResult = hihi << FRACTIONAL_PLACES;

var sum = (long)loResult + midResult1 + midResult2 + hiResult;
return new Fix64(sum);
Which turns into this:

Code: Select all

000007FE766C04C8  mov         eax,0FFFFFFFFh  
000007FE766C04CD  and         rax,rsi  
000007FE766C04D0  mov         edx,0FFFFFFFFh  
000007FE766C04D5  and         rdx,rcx  
000007FE766C04D8  sar         rcx,20h  
000007FE766C04DC  mov         r8,rax  
000007FE766C04DF  imul        r8,rdx  
000007FE766C04E3  imul        rax,rcx  
000007FE766C04E7  mov         r9,rsi  
000007FE766C04EA  sar         r9,20h  
000007FE766C04EE  imul        rdx,r9  
000007FE766C04F2  shr         r8,20h  
000007FE766C04F6  imul        r9,rcx  
000007FE766C04FA  mov         rcx,r9  
000007FE766C04FD  shl         rcx,20h  
000007FE766C0501  add         r8,rax  
000007FE766C0504  add         r8,rdx
Which is obviously a good bit worse than

Code: Select all

000007FE766C04D4  vmulss      xmm0,xmm0,xmm6 
I'm not great with machine code, but from my understanding the single-argument version of the imul instruction should be able to multiply two 64bit integers into the full 128bit result in one instruction, right?
Do you have an idea how I could write the multiplication in C# to allow the compiler to optimize to that?

Norbo
Site Admin
Posts: 4517
Joined: Tue Jul 04, 2006 4:45 am

Re: Deterministic fixed-point port, open source

Post by Norbo » Tue Feb 27, 2018 9:45 pm

The high level nature of C# combined with the JIT nature of the compiler is going to make that a bit tricky. There might exist some peephole optimizations that you could trigger with the right combination of operations, but that's a long shot. Other than trying borderline random things with no guarantee of success, one of the only options is to go dive into ryujit and see if it does anything relevant you could exploit. That would be quite an undertaking, and I suspect the maximum benefit would be limited.

Typically, to get that kind of specialized codegen, I'd suspect a dedicated intrinsic would be necessary- and I'm not aware of any relevant ones off the top of my head.

test44x
Posts: 15
Joined: Tue Jan 20, 2015 1:40 am

Re: Deterministic fixed-point port, open source

Post by test44x » Wed Feb 28, 2018 5:20 am

If you read my last post in that thread you linked. I mentioned that the biggest performance problem is due to fixed math calls not being inlined and passing struct as copies. For example a simple a * b calls: Fix64 operator *(Fix64 x, Fix64 y) with two copies of the struct. That makes it really expensive.

If you inline the code you should see around 2x better performance. Good place to start is in vector3. Try this - in vector3.Dot, inline the part:

Code: Select all

 return a.X * b.X + a.Y * b.Y + a.Z * b.Z; 
If you think about it, in that little expression above you are doing 5 method calls and passing about a total of 10 copies of struct..


Since Vector3.Dot is used so many times in the engine, you will see noticeable performance boost just from that one method when inlined. This obviously not going to be easy. It's going to be a really messy block of code in Vector3.Dot, but much better performance. Make sure to inline all Dot methods in Vector3.

I had to manually inline most of my code. It was messy and introduced some hard to track down bugs. I wish there was an easy way of doing it automatically, but I was not able to find any. I looked into Resharper for Visual Studio, it actually helped me in some cases to automatically inline parts of my code, but sometimes, it just messed up my code. Maybe someone here could find a way to automatically inline the code that would make it a lot easier. In my experience, MethodImplOptions.AggressiveInlining never worked properly, I have no idea what good comes out of it.

Norbo
Site Admin
Posts: 4517
Joined: Tue Jul 04, 2006 4:45 am

Re: Deterministic fixed-point port, open source

Post by Norbo » Wed Feb 28, 2018 5:38 am

MethodImplOptions.AggressiveInlining tends to work best (at least on the versions of coreclr 2.0.X that I've tested) when dealing with functions that pass by reference exclusively. When passing by value, many copies tend to persist, so even if the call itself is inlined the value is somewhat limited.

There is some work in this area (for example https://github.com/dotnet/coreclr/blob/ ... structs.md), but I haven't kept track of how far along things are.

Unfortunately, going full ref-mode can be just about as ugly as manually inlining, so there's no wonderful solution right now.

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Re: Deterministic fixed-point port, open source

Post by sAm_vdP » Wed Feb 28, 2018 7:48 am

Thank you both so much for your help with this, I very much appreciate it!

@test44x:
I did see your inlining comment, but I think there's more going on:

Code: Select all

(a.M11.rawVal * b.M11.rawVal) >> Fast64.Q
This should more or less turn into a single mul machine instruction and a shift, but aren't you losing half the range of your fixed-point value to the potential overflow in the multiplication? Which is why the multiplication method in FixedMath.Net is such a convoluted thing.

I'll try your suggestion of starting with Vector3.Dot and Norbo's of using full ref-mode.

EDIT: Does not seem to make any difference. (Sorry, wall of code incoming)

New code:

Code: Select all

public static void Dot(ref Vector3 a, ref Vector3 b, out Fix64 product)
{
	Fix64 result = Fix64.Zero;
	Fix64 temp = new Fix64();

	Fix64.mul(ref a.X, ref b.X, ref result);
	Fix64.mul(ref a.Y, ref b.Y, ref temp);
	Fix64.add(ref result, ref temp, ref result);
	Fix64.mul(ref a.Z, ref b.Z, ref temp);
	Fix64.add(ref result, ref temp, ref result);

	product = result;
}
Resulting assembly:

Code: Select all

Fix64 result = Fix64.Zero;
000007FE76702D10  push        rdi  
000007FE76702D11  push        rsi  

			Fix64.mul(ref a.X, ref b.X, ref result);
000007FE76702D12  mov         rax,qword ptr [rcx]  
000007FE76702D15  mov         r9,qword ptr [rdx]  
000007FE76702D18  mov         r10d,0FFFFFFFFh  
000007FE76702D1E  and         r10,rax  
000007FE76702D21  mov         r11d,0FFFFFFFFh  
000007FE76702D27  and         r11,r9  
000007FE76702D2A  sar         r9,20h  
000007FE76702D2E  mov         rsi,r10  
000007FE76702D31  imul        rsi,r11  
000007FE76702D35  imul        r10,r9  
000007FE76702D39  sar         rax,20h  
000007FE76702D3D  imul        r11,rax  
000007FE76702D41  shr         rsi,20h  
000007FE76702D45  imul        rax,r9  
000007FE76702D49  shl         rax,20h  
000007FE76702D4D  add         rsi,r10  
000007FE76702D50  add         rsi,r11  
000007FE76702D53  add         rax,rsi  
			Fix64.mul(ref a.Y, ref b.Y, ref temp);
000007FE76702D56  cmp         dword ptr [rcx],ecx  
000007FE76702D58  lea         r9,[rcx+8]  
000007FE76702D5C  cmp         dword ptr [rdx],edx  
000007FE76702D5E  lea         r10,[rdx+8]  
000007FE76702D62  mov         r9,qword ptr [r9]  
000007FE76702D65  mov         r10,qword ptr [r10]  
000007FE76702D68  mov         r11d,0FFFFFFFFh  
000007FE76702D6E  and         r11,r9  
000007FE76702D71  mov         esi,0FFFFFFFFh  
000007FE76702D76  and         rsi,r10  
000007FE76702D79  sar         r10,20h  
000007FE76702D7D  mov         rdi,r11  
000007FE76702D80  imul        rdi,rsi  
000007FE76702D84  imul        r11,r10  
000007FE76702D88  sar         r9,20h  
000007FE76702D8C  imul        rsi,r9  
000007FE76702D90  shr         rdi,20h  
000007FE76702D94  imul        r9,r10  
000007FE76702D98  shl         r9,20h  
000007FE76702D9C  add         rdi,r11  
000007FE76702D9F  add         rdi,rsi  
000007FE76702DA2  add         r9,rdi  
			Fix64.add(ref result, ref temp, ref result);
000007FE76702DA5  add         rax,r9  
			Fix64.mul(ref a.Z, ref b.Z, ref temp);
000007FE76702DA8  cmp         dword ptr [rcx],ecx  
000007FE76702DAA  add         rcx,10h  
000007FE76702DAE  cmp         dword ptr [rdx],edx  
000007FE76702DB0  add         rdx,10h  
000007FE76702DB4  mov         rcx,qword ptr [rcx]  
000007FE76702DB7  mov         rdx,qword ptr [rdx]  
000007FE76702DBA  mov         r9d,0FFFFFFFFh  
000007FE76702DC0  and         r9,rcx  
000007FE76702DC3  mov         r10d,0FFFFFFFFh  
000007FE76702DC9  and         r10,rdx  
000007FE76702DCC  sar         rdx,20h  
000007FE76702DD0  mov         r11,r9  
000007FE76702DD3  imul        r11,r10  
000007FE76702DD7  imul        r9,rdx  
000007FE76702DDB  sar         rcx,20h  
000007FE76702DDF  imul        r10,rcx  
000007FE76702DE3  shr         r11,20h  
000007FE76702DE7  imul        rcx,rdx  
000007FE76702DEB  mov         rdx,rcx  
000007FE76702DEE  shl         rdx,20h  
000007FE76702DF2  add         r11,r9  
000007FE76702DF5  add         r11,r10  
000007FE76702DF8  add         rdx,r11  
			Fix64.add(ref result, ref temp, ref result);
000007FE76702DFB  add         rax,rdx  

			product = result;
000007FE76702DFE  mov         qword ptr [r8],rax  
000007FE76702E01  pop         rsi  
000007FE76702E02  pop         rdi  
000007FE76702E03  ret  
Old code:

Code: Select all

public static void Dot(ref Vector3 a, ref Vector3 b, out Fix64 product)
{
	product = a.X * b.X + a.Y * b.Y + a.Z * b.Z;
}
Assembly:

Code: Select all

			product = a.X * b.X + a.Y * b.Y + a.Z * b.Z;
000007FE76722D10  push        rdi  
000007FE76722D11  push        rsi  
000007FE76722D12  mov         rax,qword ptr [rcx]  
000007FE76722D15  mov         r9,qword ptr [rdx]  
000007FE76722D18  mov         r10d,0FFFFFFFFh  
000007FE76722D1E  and         r10,rax  
000007FE76722D21  mov         r11d,0FFFFFFFFh  
000007FE76722D27  and         r11,r9  
000007FE76722D2A  sar         r9,20h  
000007FE76722D2E  mov         rsi,r10  
000007FE76722D31  imul        rsi,r11  
000007FE76722D35  imul        r10,r9  
000007FE76722D39  sar         rax,20h  
000007FE76722D3D  imul        r11,rax  
000007FE76722D41  shr         rsi,20h  
000007FE76722D45  imul        rax,r9  
000007FE76722D49  shl         rax,20h  
000007FE76722D4D  add         rsi,r10  
000007FE76722D50  add         rsi,r11  
000007FE76722D53  add         rax,rsi  
000007FE76722D56  mov         r9,qword ptr [rcx+8]  
000007FE76722D5A  mov         r10,qword ptr [rdx+8]  
000007FE76722D5E  mov         r11d,0FFFFFFFFh  
000007FE76722D64  and         r11,r9  
000007FE76722D67  mov         esi,0FFFFFFFFh  
000007FE76722D6C  and         rsi,r10  
000007FE76722D6F  sar         r10,20h  
000007FE76722D73  mov         rdi,r11  
000007FE76722D76  imul        rdi,rsi  
000007FE76722D7A  imul        r11,r10  
000007FE76722D7E  sar         r9,20h  
000007FE76722D82  imul        rsi,r9  
000007FE76722D86  shr         rdi,20h  
000007FE76722D8A  imul        r9,r10  
000007FE76722D8E  shl         r9,20h  
000007FE76722D92  add         rdi,r11  
000007FE76722D95  add         rdi,rsi  
000007FE76722D98  add         r9,rdi  
000007FE76722D9B  add         rax,r9  
000007FE76722D9E  mov         rcx,qword ptr [rcx+10h]  
000007FE76722DA2  mov         rdx,qword ptr [rdx+10h]  
000007FE76722DA6  mov         r9d,0FFFFFFFFh  
000007FE76722DAC  and         r9,rcx  
000007FE76722DAF  mov         r10d,0FFFFFFFFh  
000007FE76722DB5  and         r10,rdx  
000007FE76722DB8  sar         rdx,20h  
000007FE76722DBC  mov         r11,r9  
000007FE76722DBF  imul        r11,r10  
000007FE76722DC3  imul        r9,rdx  
000007FE76722DC7  sar         rcx,20h  
000007FE76722DCB  imul        r10,rcx  
000007FE76722DCF  shr         r11,20h  
000007FE76722DD3  imul        rcx,rdx  
000007FE76722DD7  mov         rdx,rcx  
000007FE76722DDA  shl         rdx,20h  
000007FE76722DDE  add         r11,r9  
000007FE76722DE1  add         r11,r10  
000007FE76722DE4  add         rdx,r11  
000007FE76722DE7  add         rax,rdx  
000007FE76722DEA  mov         qword ptr [r8],rax  
000007FE76722DED  pop         rsi  
000007FE76722DEE  pop         rdi  
000007FE76722DEF  ret  
As far as I can tell the assembly code is 95% identical (somehow loading the .Y and .Z values happens slightly differently?). I don't think the issue lies with the inlining or method overhead, but simply with the complexity of the multiplication method. Or am I missing something?

test44x
Posts: 15
Joined: Tue Jan 20, 2015 1:40 am

Re: Deterministic fixed-point port, open source

Post by test44x » Wed Feb 28, 2018 12:25 pm

Write a benchmark for timing both the inline/ref-mode and old Vector3.Dot method - that's the best way to see the difference. In my tests it was very apparent to me that ref-mode/inlined method was significantly faster.

This should more or less turn into a single mul machine instruction and a shift, but aren't you losing half the range of your fixed-point value to the potential overflow in the multiplication? Which is why the multiplication method in FixedMath.Net is such a convoluted thing.
Yes, I was not checking for overflow in most areas of the code since at least for my game I did not have to worry about calculating large numbers. However, anything to do with GJK algorithm in the engine must use a fixedmath that can handle very large range of numbers. I was actually using three different fixed math struct that I made and wrote conversion methods between them. Each type being used at different parts of the code.

Like I said it, it was a really messy messy project. Sadly, I couldn't find any other way around it. Without hand picked optimization, changing all floats to Fix64 would result in a extremely slow engine. I am really surprised it is running for you only 4 times slower, for me I think it was running 8 to 10 times slower when I did a direct swap of floats to Fix64.

Unfortunately, I don't have my code anymore to show you how I did it. I moved on to achieve the same multiplayer function through alternative methods. I forgot which HD/folder I placed that project. Believe me.. it was such a messy project that the folder was around 4GB because of keeping so many backups and alternative methods of the code. I cringe every time I think about that pile of mess lol.

My next step was to convert bepu project completely to c++ and that's where I decided it's enough for me. If you are really determined, you can pick up where I left off. IMO, converting the project to c++ and then implementing fixed math could give you the best balance between performance and determinism. C++ can open up many more options for optimization, such as easy inclining and etc. It won't be easy..

Best of luck to you in your journey though, you will need it lol.

sAm_vdP
Posts: 10
Joined: Fri Feb 09, 2018 1:00 pm

Re: Deterministic fixed-point port, open source

Post by sAm_vdP » Wed Feb 28, 2018 12:42 pm

I am of course measuring the results with a benchmark. I am using four of the BEPUphysics demos and running them for 1000 steps each and measuring the full runtime:

Old version (inlined without ref):

Code: Select all

DiscreteVsContinuousBenchmark... 0.21s
InverseKinematicsBenchmark... 17.31s
PathFollowingBenchmark... 3.58s
SelfCollidingClothBenchmark... 68.03s
PyramidBenchmark... 5.22s
Cumulative runtime: 94.35
ref version:

Code: Select all

DiscreteVsContinuousBenchmark... 0.22s
InverseKinematicsBenchmark... 17.28s
PathFollowingBenchmark... 3.45s
SelfCollidingClothBenchmark... 67.21s
PyramidBenchmark... 5.31s

Cumulative runtime: 93.47
How can there be a performance difference if the generated assembly code is identical?

I'd really rather not make too many assumptions about value ranges and necessary datatypes - I feel the risk of introducing bugs and breaking the demos is not worth it, particularly in light of the complexity of maintaining the "pile of mess" :)
That said, I still hope I can somehow squeeze a bit more speed out of it.

issingle
Posts: 1
Joined: Thu Mar 01, 2018 1:58 pm

Re: Deterministic fixed-point port, open source

Post by issingle » Thu Mar 01, 2018 2:09 pm

great work.HOPE USE IT IN MY PROJECT.
Unity3d physics lost so many api. It hasn't ReCreate physics system API ,so it is not Deterministic in same pc. oooch

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest