Hi all,


I am working on a C++ application which involves a thread. My application draws the waveform on screen. The drawing speed should be 25mm/s and the thread should run every 10.56ms for this speed to obtain.

But with either 10ms or 11ms set as the Time period for the periodic thread, i am not able to get the exact drawing speed of 25mm/s. Its 26.41mm/s for 10ms and 24.04 for 11ms. So Error of more than 4% which is not acceptable.

/* Main Thread routine handling the waveform draw */
	DWORD virtual CntrlThread()
	{
		while(true)
		{
		
			if(TRUE == WaitForSignal())
			{
				if(this->m_bStopThr == false)
				{
					//Sleep(m_pWaveform->m_i32SampleInterval);
					if(!m_pWaveform->m_bPaused)
					{
						/* Waveform drawn in Green color */
						m_pWaveform->DrawWave();
					}
					if(m_pWaveform->m_vRequestQueue.size() > 0U)
					{
						/* Waveform Request handler */
						m_pWaveform->UserRequestHandler();
					}
				}
				else
				{
					break;
				}
			}
			else
			{
				break;
			}

		}
		return THR_STATE_COMPLETED;
	}

Please let me know what can be the possible resolutions to get the exact drawing speed.

I'm not sure if there is one that exists but try to use a sleep call with microsecond precision instead of millisecond. You will be able to have a finer control over the period.
However, there are issues with this. Usually, you are not guaranteed to have an exact sleep time. Often times the microsecond times are estimated or 'binned' and not true measurements. Also, other factors/processes can influence the reliability of your performance on a shared system.

You can use the Boost.Date-Time library and the Boost.Thread library, they offer timing functions with, in theory, a precision up to nano-seconds and similarly for the thread sleeping functions. Of course, when your system cannot support nanosecond timing then it will be rounded to the smallest possible precision your computer supports (usually some fraction of a micro-second, most recent computers support at least micro-second precision, unless it is really old).

In general, you can't really depend on the thread system to be precise even if your clock is precise enough. The problem is that putting threads to sleep, scheduling them, waking them up and such, are all things that the OS can't guarantee to do with precise timing. But, for fractions of milliseconds, it's not so bad. To get really precise timing on thread executions, you need a Real-Time Operating System (RTOS), which means that it can implement what is called "hard real-time" where you can specify very precise interrupt intervals to restart a thread (it uses low-level interrupts that can provide real guarantees for precise timing, close to the clock-freq. of your processor).

I recommend that you decouple your drawing from the actual framerate. Basically, you keep track of how much time has elapsed since the last frame, and then draw only the part of the waveform that should have been drawn in that amount of time. That way, your framerate can be imprecise or even highly variable, but the effect is that the waveform appears to be drawn at a constant speed.

You might want to read Glenn Fiedler's article on this topic, especially starting at the "Free the physics" section. It's written with a focus on physics engines, but the concept applies just as well here.

commented: Yes +11

Thanks for various suggestions.

I am working on Windows Embedded CE 6.0 platform, so it is a Real Time Operating System(RTOS) & am assuming it to be Hard one.
I know using Sleep within the thread will even leads to performance degradation, since sleep for some microsecond time will not produce the sleep of exact that period.

I mean to say.
If Sleep(10)//Sleep for 10 millisecond will cause sleep between 10ms and 11ms.

Because of these limitations i am registering a Periodic thread for 10ms Periodic Interval(This thread should service me every 10ms---Ideal case).

Then you need to use an interrupt based on the real-time clock alarms. This is the only method to precisely wake-up a thread based on hard real-time constraints. I don't know much about windows CE so I can't really help you with the details, you need to browse msdn reference pages for instruction of setting up the RTC timer and handling the interrupt.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.