Разрешение по времени API GetLocalTime () - PullRequest
6 голосов
/ 08 сентября 2008

Мне нужно узнать время, затраченное функцией в моем приложении. Приложение представляет собой решение MS VIsual Studio 2005, весь C-код.

Я использовал API Windows GetLocalTime (SYSTEMTIME *) для получения текущего системного времени до и после вызова функции, для которой я хочу измерить время. Но это имеет недостаток, что самое низкое разрешение составляет всего 1 мсек. Ничего ниже этого. Так что я не могу получить детальность времени в микросекундах.

Я знаю, что время (), которое дает время, прошедшее с начала эпохи, также имеет разрешение 1 мс (без микросекунд)

1.) Есть ли какой-либо другой API-интерфейс Windows, который дает время в микросекундах, которое я могу использовать для измерения времени, потребляемого моей функцией?

-AD

Ответы [ 4 ]

10 голосов
/ 08 сентября 2008

Есть и другие возможности.

QueryPerformanceCounter и QueryPerformanceFrequency

QueryPerformanceCounter вернет «счетчик производительности», который фактически является 64-разрядным счетчиком, управляемым ЦП, который увеличивается с 0, начиная с включения компьютера. Частота этого счетчика возвращается QueryPerformanceFrequency . Чтобы получить эталон времени в секундах , разделите счетчик производительности на частоту выполнения. В Delphi:

function QueryPerfCounterAsUS: int64;     
begin
  if QueryPerformanceCounter(Result) and
     QueryPerformanceFrequency(perfFreq)
  then
    Result := Round(Result / perfFreq * 1000000);
  else
    Result := 0;
end;

На многопроцессорных платформах QueryPerformanceCounter должен возвращать согласованные результаты независимо от того, на каком процессоре в данный момент выполняется поток. Однако иногда возникают проблемы, обычно вызванные ошибками в аппаратных чипах или BIOS. Обычно патчи предоставляются производителями материнских плат. Два примера из MSDN:

Другая проблема с QueryPerformanceCounter заключается в том, что он работает довольно медленно.

инструкция RDTSC

Если вы можете ограничить свой код одним ЦП (SetThreadAffinity), вы можете использовать RDTSC инструкцию ассемблера для запроса счетчика производительности непосредственно из процессора.

function CPUGetTick: int64;
asm
  dw 310Fh // rdtsc
end;

Результат RDTSC увеличивается с той же частотой, что и QueryPerformanceCounter. Разделите его на QueryPerformanceFrequency, чтобы получить время в секундах.

QueryPerformanceCounter намного медленнее, чем RDTSC, потому что он должен учитывать несколько процессоров и процессоров с переменной частотой. От Блог Раймона Чена :

(QueryPerformanceCounter) считает прошедшее время. Он должен, так как его значение регулируется функцией QueryPerformanceFrequency, которая возвращает число указав количество единиц в секунду, а частота указана как не меняется во время работы системы.

Для процессоров, которые могут работать с переменной скоростью, это означает, что HAL не может используйте инструкцию, подобную RDTSC, поскольку она не коррелирует с прошедшим временем.

timeGetTime

TimeGetTime относится к мультимедийным функциям Win32 Win32. Возвращает время в миллисекундах с разрешением 1 мс, по крайней мере, на современном оборудовании. Это не повредит, если вы запустите timeBeginPeriod (1) до того, как начнете измерять время и timeEndPeriod (1), когда закончите.

GetLocalTime и GetSystemTime

До Vista оба GetLocalTime и GetSystemTime возвращают текущее время с точностью до миллисекунды, но они не с точностью до миллисекунд. Их точность обычно находится в диапазоне от 10 до 55 миллисекунд. ( Точность не совпадает с точностью ) В Vista, GetLocalTime и GetSystemTime работают с разрешением 1 мс.

2 голосов
/ 10 декабря 2008

Одно предупреждение для многопроцессорных систем:

от http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspx

На многопроцессорном компьютере не должно иметь значения, какой процессор называется. Однако вы можете получить разные результаты на разных процессорах из-за ошибок в базовой системе ввода / вывода (BIOS) или на уровне аппаратной абстракции (HAL). Чтобы указать привязку процессора к потоку, используйте функцию SetThreadAffinityMask.

Аль Вейнер

1 голос
/ 08 сентября 2008

В Windows вы можете использовать «высокопроизводительный счетчик API». Проверьте: QueryPerformanceCounter и QueryPerformanceCounterFrequency для получения подробной информации.

1 голос
/ 08 сентября 2008

Вы можете попробовать использовать clock () , который обеспечит количество «тиков» между двумя точками. «Тик» - это наименьшая единица времени, которую процессор может измерить.

В качестве примечания вы не можете использовать clock () для определения фактического времени - только количество тактов между двумя точками в вашей программе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...