Точное измерение времени
Я использую time.h в С++ для измерения времени функции.
clock_t t = clock();
someFunction();
printf("\nTime taken: %.4fs\n", (float)(clock() - t)/CLOCKS_PER_SEC);
однако, я всегда получаю время, принятое за 0,0000. clock() и t при печати отдельно, имеют одинаковое значение. Я хотел бы знать, есть ли способ точно измерить время (возможно, в порядке наносекунд) на С++. Я использую VS2010.
Ответы
Ответ 1
Обычно я использую функцию QueryPerformanceCounter
.
Пример:
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER t1, t2; // ticks
double elapsedTime;
// get ticks per second
QueryPerformanceFrequency(&frequency);
// start timer
QueryPerformanceCounter(&t1);
// do something
...
// stop timer
QueryPerformanceCounter(&t2);
// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
Ответ 2
С++ 11 представил chrono API, который вы можете использовать для получения наносекунд:
auto begin = std::chrono::high_resolution_clock::now();
// code to benchmark
auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count() << "ns" << std::endl;
Для более релевантного значения полезно запустить функцию несколько раз и вычислить среднее значение:
auto begin = std::chrono::high_resolution_clock::now();
uint32_t iterations = 10000;
for(uint32_t i = 0; i < iterations; ++i)
{
// code to benchmark
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count();
std::cout << duration << "ns total, average : " << duration / iterations << "ns." << std::endl;
Но помните, что цикл for
и назначение begin
и end
var также используют некоторое время процессора.
Ответ 3
Следующий текст, с которым я полностью согласен, указан из Оптимизация программного обеспечения на С++ (хорошее чтение для любого программиста на С++) -
Измерения времени могут потребовать очень высокого разрешения, если время интервалы короткие. В Windows вы можете использовать GetTickCount
или QueryPerformanceCounter
для миллисекундного разрешения. Много более высокое разрешение может быть получено с помощью счетчика времени в CPU, который рассчитывается на частоте процессора.
Существует проблема, что "тактовая частота может варьироваться динамически и что
измерения нестабильны из-за прерываний и переключателей задач.
Ответ 4
В C или С++ я обычно делаю, как показано ниже. Если он все еще не работает, вы можете использовать функции rtdsc
struct timeval time;
gettimeofday(&time, NULL); // Start Time
long totalTime = (time.tv_sec * 1000) + (time.tv_usec / 1000);
//........ call your functions here
gettimeofday(&time, NULL); //END-TIME
totalTime = (((time.tv_sec * 1000) + (time.tv_usec / 1000)) - totalTime);