Какова лучшая замена для timeGetTime для предотвращения циклического возврата?

timeGetTime, кажется, довольно хорош для запросов в течение системного времени. Однако его возвращаемое значение является 32-разрядным только, таким образом, оно переносит каждые 49 дней приблизительно.

Не слишком трудно обнаружить трансформацию в коде вызова, но это добавляет, что некоторая сложность, и (хуже) требует хранения состояния.

Есть ли некоторая замена для timeGetTime, который не имел бы этой всеобъемлющей проблемы (вероятно, путем возвращения 64-разрядного значения), и имел бы примерно ту же точность и стоил бы?

5
задан Paweł Hajdan 13 May 2010 в 09:54
поделиться

5 ответов

Нет, для отслеживания перехода требуется состояние. Это может быть так же просто, как увеличение вашего собственного 64-битного счетчика при каждом обратном вызове.

Довольно необычно отслеживать периоды времени с разрешением всего 1 миллисекунда на срок до 49 дней. Вам придется беспокоиться о том, что точность все еще сохраняется после такого длительного периода. Следующим шагом является использование часов, GetTickCount (64), GetSystemTimeAsFileTime имеют разрешение 15,625 миллисекунд и сохраняются с точностью до сервера времени.

2
ответ дан 18 December 2019 в 10:42
поделиться

Вы можете использовать RDTSC встроенный. Чтобы получить время в миллисекундах, вы можете получить коэффициент преобразования:

double get_rdtsc_coeff() {
  static double coeff = 0.0;
  if ( coeff < 1.0 ) { // count it only once
    unsigned __int64 t00 = __rdtsc();
    Sleep(1000);
    unsigned __int64 t01 = __rdtsc();
    coeff = (t01-t00)/1000.0;
  }

  return coeff; // transformation coefficient
}

Теперь вы можете получить количество миллисекунд с момента последнего сброса:

__int64 get_ms_from_start() {
  return static_cast<__int64>(__rdtsc()/get_rdtsc_coeff());
}

Если ваша система использует SpeedStep или аналогичные технологии, вы можете использовать QueryPerformanceCounter / ] QueryPerformanceFrequency функций. Windows дает гарантии, что частота не может измениться во время работы системы.

0
ответ дан 18 December 2019 в 10:42
поделиться

Как вы пытаетесь его использовать? Я часто использую эквивалент Win32 при проверке длительности, которая, как я знаю, будет меньше 49 дней. Например, следующий код всегда будет работать.

DWORD start = timeGetTime();
DoSomthingThatTakesLessThen49Days();
DWORD duration = timeGetTime() - start;

Даже если timeGetTime перекатывается при вызове DoSomthingThatTakesLessThen49Days , продолжительность все равно будет правильной.

Обратите внимание, что следующий код может завершиться ошибкой при опрокидывании.

DWORD start = timeGetTime();
DoSomthingThatTakesLessThen49Days();
if (now + 5000 < timeGetTime())
{
}

, но может быть легко переписан для работы следующим образом

DWORD start = timeGetTime();
DoSomthingThatTakesLessThen49Days();
if (timeGetTime() - start < 5000)
{
}
1
ответ дан 18 December 2019 в 10:42
поделиться

На какой платформе?

Вы можете использовать GetTickCount64 () , если вы работаете в Vista или более поздней версии. , или синтезируйте свой собственный GetTickCount64 () из GetTickCount () и таймер ...

Я имею дело с проблемой пролонгации в GetTickCount () и синтезирование GetTickCount64 () на платформах, которые его не поддерживают здесь, в моем блоге о тестировании нетривиального кода: http://www.lenholgate.com/blog/2008/04/practical -testing-17 --- a-Совершенно новый-подход.html

5
ответ дан 18 December 2019 в 10:42
поделиться

Посмотрите на GetSystemTimeAsFileTime(). Она заполняет FILETIME struct, который содержит "64-битное значение, представляющее количество 100-наносекундных интервалов с 1 января 1601 года (UTC)"

1
ответ дан 18 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: