4

I have found useful information regarding the use of QueryPerformanceCounter in this post but I am facing an issue for which I have not found an answer.

I am developing an application for Windows CE 6.0 and need a better resolution that GetTickCount can offer. That is why I chose QueryPerformanceCounter function.

I have observed that the counter value I get goes back and forth. Although it is not the final application this little example ilustrates the problem:

int i;
BOOL bRet;
LARGE_INTEGER liCounter;


for ( i = 0; i < 100; i++)
{
    bRet = QueryPerformanceCounter(&liCounter);
    if(bRet)
    {
        printf("Counter Value: %llu \n", liCounter.QuadPart);
    }

}

It prints a series of 100 counter values which are expected to be incremental. However, there are some counter values which decrement with respect to the previous value. For example:

...

Counter Value: 6536266821

Counter Value: 6536266262

Counter Value: 6536266604

...

This behaviour is problematic since in the final application (endCounterValue-startCoutnerValue) type operations are carried out and negative time intervals are found in same cases.

I have read (here) this problem can be found when using multicore platforms. However, this is not the case since Windows CE 6.0 does not support multicore processing.

Any help to find a reason why does this happen and/or any workaround to avoid this problem would be appreciated.

[Edit]

I edit the question in order to include more information:

A longer list of consecutive reads (different from the list above):

Counter Value: 15234261579

Counter Value: 15234261594

Counter Value: 15234261609

Counter Value: 15234261624

Counter Value: 15234261640

Counter Value: 15234261064

Counter Value: 15234261079

Counter Value: 15234261094

Counter Value: 15234261109

Counter Value: 15234261125

Counter Value: 15234261140

Counter Value: 15234261155

Counter Value: 15234261170

Counter Value: 15234261185

Counter Value: 15234261201

Counter Value: 15234261216

Counter Value: 15234261231

Counter Value: 15234261246

Regarding the hardware, an Intel Celeron 1047UE processor and HM76 chipset are being used.

When calling to QueryPerformanceFrequency, 1.19MHz frequency is read.

Community
  • 1
  • 1
ISZ
  • 43
  • 4
  • Ignore the result if it is less than the previous one. Also:http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx – 2501 Dec 11 '14 at 10:02
  • If I ignore the result I am losing the time data of that interval. I have to prevent this from happening. – ISZ Dec 11 '14 at 10:10
  • Smells like a BSP bug. You might want to contact your device/BSP vendor on this. – ctacke Dec 11 '14 at 15:46

2 Answers2

1

QueryPerformanceCounter leads to a call inside the OAL (part of the BSP) where the highest-resolution progressive counter available in the system should be used to return a 64 bits value. Looks like an issue with that specific BSP. On x86 the amount of HW timers is limited and it may be that some drivers are using the counter that is used by QueryPerformanceCounter to have timers with less that 1ms resolution. It seems that the value is re-set and then continues to increase, this may be due to a driver setting a timer for itself (maybe useing only the lower 32bit part of the timers registers). If you have the source code of your BSP you can search OEMQueryPerformanceCounter implementation, check wich registers is using and check if other components of the BSP are accessing them (or other registers that can impact their operativity).

Valter Minute
  • 2,177
  • 1
  • 11
  • 13
0

Counter Value: 6536266821

Counter Value: 6536266262

Counter Value: 6536266604

even the third read is smaller than the first! But what is the relevance here? You should read the performance counter frequency using QueryPerformanceFrequency() to investigate what a difference of a few hundred counts actually means. With a frequence in the MHz range this would still be much better than a millisecond. Can you provide a longer list of consecutive reads of QueryPerformanceCounter()

You should also provide more details about the hardware. What resource is used for the performance counter? Acquiring high-resolution time stamps may help you to get a more detailed view.

Considering a linear behavior of your loop you could do a plot of values vs. time. This may particularize the problem. It may also allow to establish a rejection/interpolation scheme.

Community
  • 1
  • 1
Arno
  • 4,994
  • 3
  • 39
  • 63
  • Thanks for your answer. I have edited the question in order to include more information – ISZ Dec 11 '14 at 11:10
  • 1.19MHz is read with QueryPerformanceFrequency. Just as an example, 400 counts make 0.335ms. In the end application the time that it takes to execute a given function is measured by making (endCounterValue - startCounterValue) type operation. Therefore, even if the backwards jump is "small", this jump is not acceptable because negative time intervals appear. – ISZ Dec 11 '14 at 11:21
  • 1.19 MHz is the signature of an 8253 timer chip. Have you considered using the cpu TSC? – Arno Dec 11 '14 at 12:48
  • You are right, it seems QueryPerformanceCounter is using 8253 timer or similar. I have tried measuring time by reading TSC register and this works OK. Thanks for the suggestion. However I still don't understand why counter value jump sometimes backwards when using 8253 timer chip. Any idea on this? – ISZ Dec 11 '14 at 14:57