What is "Time-slicing"?

From Newton Wiki
Jump to: navigation, search

from the official Newton forums:

(user: cleathley)

here is a bit of code that might help..

define this somewhere.. this allows you to set the # of times to call newton per second. I call it 300 times a second but unless you are doing some very heavy stuff you won't need to call it that fast.

Code:

#define PHYSICS_UPDATE_FPS         300.0f
#define PHYSICS_THREAD_SLEEPTIME   (1000.0f / PHYSICS_UPDATE_FPS)

I have a variable called m_AccumlativeTimeSlice which I set to 0 in my init function.

and in your main loop (which is generally passed in the number of milliseconds since the last main loop)

Code:

  // add the number of millisconds passed to our accumlative total
   m_AccumlativeTimeSlice += milliseconds;
   while (m_AccumlativeTimeSlice > PHYSICS_THREAD_SLEEPTIME)
   {
      NewtonUpdate(m_pNewtonWorld, (PHYSICS_THREAD_SLEEPTIME / 1000.0f));       // convert to seconds
      m_AccumlativeTimeSlice -= PHYSICS_THREAD_SLEEPTIME;
   }


if you really want to get tricky (or want some timing statistics) then you can use

Code:

   __int64   timer;
   DWORD   startTime, endTime;

   QueryPerformanceCounter((LARGE_INTEGER *)&timer);         // Grab Current Value In Performance Counter
   startTime = (DWORD)timer;

   // add the number of millisconds passed to our accumlative total
   m_AccumlativeTimeSlice += milliseconds;

   while (m_AccumlativeTimeSlice > PHYSICS_THREAD_SLEEPTIME)
   {
      NewtonUpdate(m_pNewtonWorld, (PHYSICS_THREAD_SLEEPTIME / 1000.0f));      // convert to seconds
       m_AccumlativeTimeSlice -= PHYSICS_THREAD_SLEEPTIME;
   }

   QueryPerformanceCounter((LARGE_INTEGER *)&timer);
   endTime = (DWORD)timer;

   m_PhysicsTickTotalTime += (endTime - startTime) * m_Window.TimerResolution * 1000.0f;


then you just zero out PhysicsTickTotalTime each second much like you handle any fps display.

m_Window.TimerResolution is just a variable which is set via

Code:

   // Grab The Counter Frequency
   QueryPerformanceFrequency((LARGE_INTEGER *) &timer);
   // Set The Timer Resolution (1.0f / Timer Frequency)
   TimerResolution = (float) (((double)1.0f)/((double)timer));


hope that helps.



Remark :

In certain circonstance, the use of time-slicing can lead to a paradoxe in which the time required to update physics will become greater than the time-slice itself.

When the application enters this paradoxe, it starts to works more and more slowly. Each use of the « while » loop (as described in this example) will require more and more time to be completed, and the application will quickly seems to be frozen.

To avoid to enter this paradoxe, one solution is to filter the delta-time (the « milliseconds » variable in the example) so it will never get greater than a limit of your choice.

Let's say that you choose to limit your delta-time to 100ms (10 FPS). Where you get the delta-time, you will add :

if (milliseconds>100) milliseconds=100;

Then, when the actual delta-time will be, for example, 150ms, the rest of your application will think it is 100ms. It will think that it works at a minimum frame rate of 10FPS.

In other words, when your application will become too much slow (for a reason or an other), it will quit the real-time mode to start to work in simulated-time. It will come back to real-time mode when the delta-time will be smaler than 100.

Entering into simulated-time will not avoid your application to work slowly if the computer is too slow. It will just avoid to enter the paradoxe and to « freeze »-like your application.



back to the FAQ