Я нашел полезную информацию об использовании QueryPerformanceCounter в эта почта но я столкнулся с проблемой, для которой я не нашел ответа.
Я разрабатываю приложение для Windows CE 6.0 и мне нужно лучшее разрешение, которое может предложить GetTickCount. Вот почему я выбрал функцию QueryPerformanceCounter.
Я заметил, что значение счетчика, которое я получаю, идет туда-сюда. Хотя это не окончательное приложение, этот маленький пример иллюстрирует проблему:
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);
}
}
Он печатает серию из 100 значений счетчиков, которые, как ожидается, будут инкрементными. Однако есть некоторые значения счетчиков, которые уменьшаются относительно предыдущего значения. Например:
…
Значение счетчика: 6536266821
Значение счетчика: 6536266262
Значение счетчика: 6536266604
…
Такое поведение проблематично, поскольку в конечном приложении (endCounterValue-startCoutnerValue) выполняются операции типа, и в тех же случаях обнаруживаются отрицательные интервалы времени.
Я прочитал (Вот) эта проблема может быть обнаружена при использовании многоядерных платформ. Однако это не так, поскольку Windows CE 6.0 не поддерживает многоядерную обработку.
Мы будем благодарны за любую помощь в поиске причины, по которой это происходит, и / или любые обходные пути, позволяющие избежать этой проблемы.
[Редактировать]Я редактирую вопрос, чтобы включить больше информации:
Более длинный список последовательных чтений (отличается от списка выше):
Значение счетчика: 15234261579
Значение счетчика: 15234261594
Значение счетчика: 15234261609
Значение счетчика: 15234261624
Значение счетчика: 15234261640
Значение счетчика: 15234261064
Значение счетчика: 15234261079
Значение счетчика: 15234261094
Значение счетчика: 15234261109
Значение счетчика: 15234261125
Значение счетчика: 15234261140
Значение счетчика: 15234261155
Значение счетчика: 15234261170
Значение счетчика: 15234261185
Значение счетчика: 15234261201
Значение счетчика: 15234261216
Значение счетчика: 15234261231
Значение счетчика: 15234261246
Что касается аппаратного обеспечения, то используются процессор Intel Celeron 1047UE и чипсет HM76.
При вызове QueryPerformanceFrequency считывается частота 1,19 МГц.
Значение счетчика: 6536266821
Значение счетчика: 6536266262
Значение счетчика: 6536266604
даже третье чтение меньше первого! Но какая здесь уместность? Вы должны прочитать частоту счетчика производительности, используя QueryPerformanceFrequency()
исследовать, что на самом деле означает разница в несколько сотен единиц. С частотой в диапазоне МГц это все равно будет намного лучше, чем миллисекунда. Можете ли вы предоставить более длинный список последовательных чтений QueryPerformanceCounter()
Вы также должны предоставить более подробную информацию об оборудовании. Какой ресурс используется для счетчика производительности? Получение меток времени с высоким разрешением может помочь вам получить более подробное представление.
Учитывая линейное поведение вашего цикла, вы можете построить график зависимости значений от времени. Это может конкретизировать проблему. Это также может позволить установить схему отклонения / интерполяции.
QueryPerformanceCounter приводит к вызову внутри OAL (часть BSP), где должен использоваться прогрессивный счетчик с самым высоким разрешением, доступный в системе, для возврата 64-битного значения.
Похоже, проблема с этим конкретным BSP.
На x86 количество таймеров HW ограничено, и может случиться так, что некоторые драйверы используют счетчик, который используется QueryPerformanceCounter, чтобы иметь таймеры с разрешением менее 1 мс. Кажется, что значение сбрасывается, а затем продолжает увеличиваться, это может быть связано с тем, что драйвер устанавливает для себя таймер (возможно, использует только нижнюю 32-битную часть регистров таймеров).
Если у вас есть исходный код вашего BSP, вы можете выполнить поиск реализации OEMQueryPerformanceCounter, проверить, какие регистры используются, и проверить, обращаются ли к ним другие компоненты BSP (или другие регистры, которые могут повлиять на их работоспособность).