Stopwatch.Gettimestamp когда-либо переворачивается? Или откатиться? - PullRequest
6 голосов
/ 24 января 2012

При использовании Stopwatch.GetTimestamp () мы обнаруживаем, что если вы запишите возвращаемое значение, а затем продолжите вызывать его и сравнивать с предыдущим возвращаемым значением, оно в конечном итоге, но непредсказуемо, вернет значение меньше исходного.

Это ожидаемое поведение?

Цель выполнения этого в производственном коде - получить точное время микросекунды.

Техника включает в себя вызов DateTime.UtcNow, а также вызов Stopwatch.GetTimestamp () как originalUtcNow и originalTimestamp соответственно.

С этого момента приложение просто вызывает Stopwatch.GetTimestamp () и, используя Stopwatch.Frequency, вычисляет разницу от переменной originalTimestamp, а затем добавляет эту разницу к originalUtcNow.

Тогда, Вуаля ... эффективная и точная микросекунда DateTime.

Но мы обнаруживаем, что иногда Stopwatch.GetTimestamp () возвращает меньшее число.

Это случается довольно редко. Мы думаем просто «перезагрузиться», когда это произойдет, и продолжить.

ОДНАКО, это заставляет нас сомневаться в точности Stopwatch.GetTimestamp () или подозревать, что в библиотеке .Net есть ошибка.

Если вы можете пролить свет на это, пожалуйста, сделайте.

FYI, основанный на текущем значении временной метки, частоте и long.MaxValue, маловероятно, что он будет пролонгирован в течение нашей жизни, если только это не будет аппаратная проблема.

РЕДАКТИРОВАТЬ: Теперь мы вычисляем это значение «на поток», а затем «зажимаем его», чтобы отследить скачки между ядрами для его сброса.

Ответы [ 3 ]

6 голосов
/ 24 января 2012

Вполне возможно, что вы получите скачок во времени, потому что ваш поток прыгает ядра.Смотрите "примечание" на этой странице: http://msdn.microsoft.com/en-us/library/ebf7z0sw.aspx

2 голосов
/ 24 января 2012

Поведение класса Секундомер будет зависеть от системы к системе в зависимости от аппаратной поддержки.

См .: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.ishighresolution.aspx

Кроме того, я считаю, что основной эквивалентный вызов win32 ()QueryPerformanceCounter ) содержит полезную документацию: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx

1 голос
/ 19 декабря 2013

Я не знаю точно, что делать с обратным ходом (что звучит как маленькое изменение назад), но я до сих пор испытывал три раза, что значение Stopwatch.GetTimestamp () может изменяться так сильночто он вызывает исключения переполнения в некоторых дальнейших вычислениях формы примерно так:
(Stopwatch.GetTimestamp() - ProgramStartStopwatchTimestamp) * n
где n - это какое-то большое значение, но достаточно маленькое, чтобы, если секундомересли бы не было огромных скачков, то программа могла бы работать годами без исключения переполнения.Также обратите внимание, что эти исключения возникали через много часов после запуска программы, поэтому проблема не только в том, что секундомер запускался назад немного сразу после запуска.Он просто перепрыгнул в совершенно другой диапазон в любом направлении.

Что касается переворачивания секундомера, то в одном из приведенных выше случаев он (не разница, а секундомер) получил значение чего-то в стиле 0xFF4?????????Причем, так что он прыгнул на диапазон, который был очень близок к опрокидыванию.После многократного перезапуска программы этот новый диапазон продолжал действовать последовательно.Если это больше не имеет значения, учитывая необходимость обработки скачков в любом случае ...

Если было дополнительно необходимо определить, на каком ядре была взята временная метка, то это, вероятно, помогает узнать номер выполняемого ядра.Для этого есть функции, называемые GetCurrentProcessorNumber (доступны с Server 2003 и Vista) и GetCurrentProcessorNumberEx (доступны с Server 2008 R2 и Windows 7).См. Также ответы на этот вопрос , чтобы получить дополнительные параметры (включая Windows XP).
Обратите внимание, что номер ядра может быть изменен планировщиком в любое время.Но когда кто-то читает номер ядра до считывания метки времени секундомера, а после и номер ядра остается прежним, то, возможно, можно предположить, что чтение секундомера также было выполнено на этом ядре ...

...