Переопределение CLOCKS_PER_SEC на большее число в Windows 10 - PullRequest
0 голосов
/ 21 марта 2019

Компилятор GNU C ++ в Windows 10 возвращает CLOCKS_PER_SEC = 1000, но мне нужно измерить время компиляции для алгоритма с интервалом менее миллисекунды (это школьный проект). Есть ли способ переопределить CLOCKS_PER_SEC, скажем, до миллиона (как ОС на основе UNIX)? С другой стороны, #define CLOCKS_PER_SEC ((clock_t)(1000000)), похоже, тоже не работает.

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Что ж, для этого задания абсолютно необходимо использовать только time.h и time.h

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

Кстати, обратите внимание, что использование clock() немного проблематично, так как по стандарту измеряет пользовательское процессорное время текущего процесса (поэтому время ядра и ожидание ввода-вывода исключаются), хотя в Windows оно измеряет время настенных часов. По сути, это то же самое, если ваш алгоритм связан с процессором и может работать практически непрерывно, но вы можете столкнуться с большими различиями, если он связан с вводом-выводом или работает в загруженной системе

Если вас интересует время на настенных часах, и вы ограничены time.h, лучшим вариантом будет старый time(); в этом случае я точно синхронизируюсь с изменением секунды с занятым ожиданием, а затем измерю количество итераций за несколько секунд, как было сказано ранее.

time_t start = time(nullptr);
while(start == time(nullptr));
start = time(nullptr);
int i = 0;
while(time(nullptr) - start < 5) {
    // your algorithm
    ++i;
}
int elapsed = time(nullptr) - start;
double time_per_iteration = double(elapsed) / i;
2 голосов
/ 21 марта 2019

Краткий ответ: нет .

Длинный ответ: нет , но вы можете использовать функцию QueryPerformanceCounter , вот пример отключения MSDN:

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

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

...