Как получить количество циклов процессора в Win32?

StackOverflow https://stackoverflow.com/questions/138932

  •  02-07-2019
  •  | 
  •  

Вопрос

В Win32 есть ли способ получить уникальное количество циклов процессора или что-то подобное, что было бы единообразным для нескольких процессов/языков/систем/и т. д.

Я создаю несколько файлов журналов, но мне приходится создавать несколько файлов журналов, поскольку мы размещаем среду выполнения .NET, и я бы хотел избежать вызова одного из них для регистрации.Таким образом, я думал, что просто создам два файла, объединим их, а затем отсортируем, чтобы получить последовательную временную шкалу, включающую вызовы между мирами.

Однако GetTickCount не увеличивается при каждом вызове, поэтому это ненадежно.Есть ли лучший номер, чтобы при сортировке звонки располагались в правильном порядке?


Редактировать:Благодаря @Грег это привело меня к QueryPerformanceCounter, и это помогло.

Это было полезно?

Решение

Вы можете использовать РДТСК Инструкция ЦП (при условии, что x86).Эта инструкция дает счетчик циклов ЦП, но имейте в виду, что он очень быстро увеличится до максимального значения, а затем сбрасывается до 0.Как упоминается в статье в Википедии, возможно, вам лучше использовать ЗапросPerformanceCounter функция.

Другие советы

Вот интересная статья! говорит не использовать RDTSC, а вместо этого использовать ЗапросPerformanceCounter.

Заключение:

Использование обычного старого timeGetTime() Для выполнения времени не является надежным во многих операционных системах на основе Windows, потому что гранулярность таймера системы может достигать 10-15 миллисекунд, что означает, что timeGetTime() Точно только до 10-15 миллисекунд.Обратите внимание, что высокие гранулярности встречаются в операционных системах на основе NT, таких как Windows NT, 2000 и XP.Windows 95 и 98, как правило, имеют гораздо лучшую гранулярность, около 1-5 мс.

Однако, если вы позвоните timeBeginPeriod(1) в начале вашей программы (и timeEndPeriod(1) в конце), timeGetTime() Обычно становится точным до 1-2 миллисекунд и предоставит вам чрезвычайно точную информацию времени.

Sleep() ведет себя аналогично;продолжительность времени Sleep() на самом деле спит, чтобы идти рука об руку с гранулярностью timeGetTime(), так что после вызова timeBeginPeriod(1) один раз, Sleep(1) на самом деле будет спать на 1-2 миллисекунд,Sleep(2) на 2-3 и т. Д. (Вместо того, чтобы спать с шагом до 10-15 мс).

Для более высокого времени точности (точность субмиллисекунды), вы, вероятно, захотите избежать использования Mnemonic RDTSC сборки, потому что его трудно калибровать;вместо этого используйте QueryPerformanceFrequency и QueryPerformanceCounter, которые точны до менее чем 10 микросекунд (0,00001 секунды).

Для простого времени как TimegetTime, так и QueryPerformanceCounter работают хорошо, а QueryPerformanceCounter, очевидно, более точные.Однако, если вам нужно сделать какие -либо «временные паузы» (например, которые необходимы для ограничения кадров), вы должны быть осторожны, сидя в петле вызова QueryperformanceCounter, ожидая, что он достигнет определенной ценности;Это будет съесть 100% вашего процессора.Вместо этого рассмотрим гибридную схему, где вы называете сон (1) (не забывайте Завершите последний <1/1000 секунды от необходимой вам задержки.Это даст вам ультра-точные задержки (точные до 10 микросекунд), с очень минимальным использованием процессора.Смотрите код выше.

System.Diagnostics.Stopwatch.GetTimestamp() возвращает количество циклов ЦП с момента начала времени (возможно, при запуске компьютера, но я не уверен), и я никогда не видел, чтобы оно не увеличивалось между двумя вызовами.

Циклы ЦП будут специфичны для каждого компьютера, поэтому вы не сможете использовать их для объединения файлов журналов между двумя компьютерами.

Выходной сигнал RDTSC может зависеть от текущей тактовой частоты ядра, которая для современных процессоров не является ни постоянной, ни, в многоядерных машинах, постоянной.

Используйте системное время, а при работе с каналами из нескольких систем используйте источник времени NTP.Таким образом вы можете получить надежные и стабильные показания времени;если накладные расходы слишком велики для ваших целей, используйте HPET Чтобы определить время, прошедшее с момента последнего известного надежного измерения времени, лучше, чем использовать только HPET.

Используйте GetTickCount и добавьте еще один счетчик при объединении файлов журналов.Это не даст вам идеальной последовательности между различными файлами журналов, но, по крайней мере, сохранит все журналы из каждого файла в правильном порядке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top