MADEAPPS / newton-dynamics

Newton Dynamics is an integrated solution for real time simulation of physics environments.
http://www.newtondynamics.com
Other
928 stars 183 forks source link

FATAL: Division By Zero #279

Closed kklouzal closed 2 years ago

kklouzal commented 2 years ago

As of this commit: https://github.com/MADEAPPS/newton-dynamics/tree/31e4d0d43c956e22e79c1e67567fe9c0bccdbaf0 I am getting a division by zero crash:

Unhandled exception at 0x00007FFB3219B0C0 (ndNewton.dll) in Vulkan.exe: 0xC000008E: Floating-point division by zero (parameters: 0x0000000000000000, 0x0000000000009D04).

Call Stack:

ndNewton_d.dll!ndDynamicsUpdate::InitWeights() at newton-4.00\sdk\dNewton\ndDynamicsUpdate.cpp(607) ndNewton_d.dll!ndDynamicsUpdate::Update() at newton-4.00\sdk\dNewton\ndDynamicsUpdate.cpp(1502) ndNewton_d.dll!ndWorld::SubStepUpdate(float timestep) at newton-4.00\sdk\dNewton\ndWorld.cpp(494) ndNewton_d.dll!ndWorld::ThreadFunction() at newton-4.00\sdk\dNewton\ndWorld.cpp(427) ndNewton_d.dll!ndWorldScene::ThreadFunction() at newton-4.00\sdk\dNewton\ndWorldScene.cpp(45) ndNewton_d.dll!ndThread::ThreadFunctionCallback() at newton-4.00\sdk\dCore\ndThread.cpp(111)

JulioJerez commented 2 years ago

that's should neve happens. are you setting the CUDA solver, that's no ready yet. it only work on that test case. I will be some time until it can handle joints. I just try few scene and I did not see that error happening. does that happen in the sandbox demos?

kklouzal commented 2 years ago

Not using CUDA or AVX solver.

//
//  Physics Initialization
_ndWorld = new ndWorld();
_ndWorld->SetThreadCount(std::thread::hardware_concurrency() - 2);
_ndWorld->SetSubSteps(3);
_ndWorld->SetSolverIterations(2);

And no it doesn't appear to be happening in the sandbox demo. All I've done here is update from an older version of Newton, not sure where to look for what's wrong..

kklouzal commented 2 years ago

No, i'm sorry, i've fixed it. _ndWorld->Update(deltaFrame); When the application first starts, deltaFrame is 0 and that was causing the issue. I have simply added a check for this and we're good to go!

if (deltaFrame > 0.0f)
{
    _ndWorld->Update(deltaFrame);
    SceneGraph::updateUniformBuffer(currentFrame);
    //
    //  Draw Frame
    Render();
}
JulioJerez commented 2 years ago

oh, I was going to say the only divide on the crash is 1 / timestep.
so maybe some how the app is passing a time step of zero.

but you found it before I made the comments. so it should be cool now.

One note, I see you are using function std::thread::hardware_concurrency() that is cool, but one of the thing the engine is that when using hyperthreaded, does no really make much differences since when dealing with large scenes, it is all dominated by memory bandwidth

I have seen occasions where setting many thread has a negative impact once it start using more thread than actual cores. it is my experience, that it is better to use about half the number of threads so that the OS does the core assignment but still have enough thread for the rest of the system.

basically what happen is that many threads causes that each thread has a lighter workload, so when a thread complete its task, it has to do a preemption or a task switch and those are not cheap.

I have struggled for years to reduces that, and does not seem to be a solution no a lest of pc os. and Newton 4 is by far my best solution, but this is not something that can be manipulated easy of a PC. and now with c++11 and more is even less controllable.

In fact I found that windows is in fact the most lenient OS of all, all others, Linux and OSX task switching is a ferociously expensive. So what I found is that a Good rule of thumb is to use a number of threads equal to the number of actual cores, about half, so that each thread get large enough task that consume a good part of the time slice. more threads causes the OS to do more task switching, and that time goes to waste.