Jump to content
  • Advertisement
Sign in to follow this  
Chicktopus

C++ Thread-Safe Low Resolution Timer

This topic is 2696 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys.

I'm having trouble timing my code on a muti-threaded application. Only the one thread uses the timing code, but I'm getting some odd results. Basically, what I need is for a set of spheres updated in a loop to drop with gravity (calculated by curVel += gravity * deltaTime). Unfortunately, the gravitational acceleration is shooting up extremely fast. I've tried converting from seconds to ms and changing gravity, but it doesn't seem to make any difference.

Here's my timer class:



#ifndef Timer
#include "Timer.h"
#define Timer
#endif


typedef struct
{
LARGE_INTEGER start;
LARGE_INTEGER stop;
} StopWatch;
LARGE_INTEGER g_freq;
CStopWatch::CStopWatch()
{
g_timer.start.QuadPart=0;
g_timer.stop.QuadPart=0;
//g_freq = SetFrequency();
QueryPerformanceFrequency(&g_freq);
}//Default Constructor
float CStopWatch::LIToSecs(LARGE_INTEGER &p_largeInt)
{
return ((float)p_largeInt.QuadPart * (1 / (float)g_freq.QuadPart));
}//LIToSecs
void CStopWatch::StartTimer()
{
QueryPerformanceCounter(&g_timer.start);
}//StartTimer
void CStopWatch::StopTimer()
{
QueryPerformanceCounter(&g_timer.stop);
}//StopTimer
float CStopWatch::GetElapsedTime()
{
LARGE_INTEGER m_time;
LARGE_INTEGER m_curTime;
QueryPerformanceCounter(&m_curTime);
m_time.QuadPart = m_curTime.QuadPart - g_timer.start.QuadPart;
return LIToSecs(m_time);
}//GetElapsedTime



And here's my update loop:





Gravity m_gravity;
CStopWatch m_timer;
m_timer.StartTimer();
float m_time = m_timer.GetElapsedTime();
float m_deltaT2 = 0.0f;
float m_timeLastIter = m_time;

while(!m_terminate)
{
m_sphereArr = *m_params->spheres; //Get sphere info from the main thread (spheres are created and destroyed there as they are being sent/received from a server)
m_mutex[1] = *m_params->colMutex;

if(m_sphereArr != NULL && m_mesh != NULL)
{
m_time = m_timer.GetElapsedTime(); //Get the time since the last call to this thread
WaitForSingleObject(m_mutex[1], INFINITE);
m_deltaT2 = (m_time - m_timeLastIter)/1000;
for (int i = 0; i < m_totalSpheres; i++)
{
Vertex m_v = m_sphereArr.GetVelocity();
m_gravity.Calculate(m_v.z, m_deltaT2); //Stepping through reveals time values of about 0.002 seconds
m_sphereArr.SetVelocity(m_v);

//---------------------------------------Do additional update stuff----------------------------

m_sphereArr.Update(m_deltaT);
}
*m_params->spheres = m_sphereArr; //Assign updated values back to the main thread
m_timeLastIter = m_time;
ReleaseMutex(m_mutex[1]);

}

}
m_timer.StopTimer();




Any help would be great!

Share this post


Link to post
Share on other sites
Advertisement

Unfortunately, the gravitational acceleration is shooting up extremely fast.
What does this mean?

I've tried converting from seconds to ms and changing gravity, but it doesn't seem to make any difference.[/quote]So the units or the formula might be completely wrong?

It's also undesirable to use variable time step unless you can prove your simulation is stable and accurate (highly unlikely). Use fixed step. Variable step is used for rendering where linear interpolation doesn't affect simulation accuracy beyond one frame. Fixed step also avoids some precision related issues since it can run at fairly low update rate so it is less common to degenerate when times to process single loop are low (<1ms).

You can test if this is an issue by inserting Sleep(5) or Sleep(10) in outer body of update loop.

Share this post


Link to post
Share on other sites
Aha! Sorted it. I'm not sure exactly what it was. Something to do with the thread synchronisation, so I reworked the synchronisation and it works just dandy now. Cheers for the answer, though, it's something to think about!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!