Получение максимально точной временной метки
Сценарий:
Я разрабатываю новый модуль для генерации файлов протоколов в специальном формате, который будет интегрирован в более крупное программное обеспечение. Основное программное обеспечение состоит из нескольких частей, некоторые из которых написаны на языке C# .Net и некоторые из них на c++ с MFC (включая многопоточность), а API, который я использую, тоже имеет файл .c.
Мое тестовое приложение-это консоль C++ с поддержкой MFC и ATL в VS2017 Professional.
Хотя основное программное обеспечение использует многопоточность, я не хочу связываться с ними в своем тестовом приложении.
Я хотел бы получить самую быструю (с точки зрения производительности) и самую точную / наименьшую временную метку разрешения для вычисления дельт / необходимого времени выполнения, которое я могу использовать.
Возможность использования дельт в другой части программы еще не исчезла, поэтому я хотел бы получить ее в переменной на всякий случай. Вот почему я стараюсь делать измерения с помощью кода, а не с помощью внешних инструментов производительности.
Что я уже пробовал:
Я попробовал несколько подходов:
1)
time_t GetActualTime() { _tzset(); time_t myTime; time(&myTime); return myTime; }Я полагаю, что это самый быстрый вариант (во время выполнения), но он возвращает секунды. Для других частей моей программы этого более чем достаточно, но не для того, что я хочу проверить прямо сейчас.
2)
С FILETIME я должен быть в состоянии получить до 100x наносекунд, но проблема заключается в "обходном пути", который я использую, чтобы получить необходимую метку времени. С этим кодом:
ULARGE_INTEGER GetTimeFile100xNanoSec (int iNr) { FILETIME timeCreation; // Value in 100x NanoSecons ULARGE_INTEGER uli100xNanoSec; CString strFileName = _T(""); strFileName.Format(_T("D:\\Temp\\myDummyFile_%03d.txt"), iNr); // to avoid tunnelig effect if using same name CStringW strFileNameW(strFileName); LPCWSTR lpFileName = strFileNameW; HANDLE hFile = CreateFileW(lpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); GetFileTime(hFile, &timeCreation, NULL, NULL); CloseHandle(hFile); DeleteFileW(lpFileName); uli100xNanoSec.LowPart = timeCreation.dwLowDateTime; uli100xNanoSec.HighPart = timeCreation.dwHighDateTime; return uli100xNanoSec; }используя его в цикле, как:
ULARGE_INTEGER lluOld; ULARGE_INTEGER lluNew; lluOld = GetTimeFile100xNanoSec(999); for (int i=0; i<100; i++) { lluNew = GetTimeFile100xNanoSec(i); wprintf(_T("\nIn Loop [%d], New - old = %llu"), i, lluNew.QuadPart - lluOld.QuadPart); lluOld.QuadPart = lluNew.QuadPart; }
Я получаю значения от 10001 (1 мс) до 60006 (6 мс), среднее значение 100 попыток составляет почти 2,5 МС. Создание / удаление временных файлов влияет на производительность, делая ее настолько медленной, что допустимый диапазон достигает миллисекунд. Что заставляет маленькое решение быть напрасным.
3)
С системным временем я могу спуститься только до миллисекунд. Я еще не проверил скорость работы, но я сделаю это позже, если я смогу получить Шаг 1 мс стабильным способом, я полагаю, что буду использовать это, так как #2 недостаточно стабилен, чтобы быть надежным
Есть ли предложения, чтобы получить ниже отметки миллисекунд надежным и многоразовым способом? С многоразовым использованием я имею в виду получение значения в переменной, которое может быть оценено в другом месте.