Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Средства для измерения времени выполнения кода

#время #cpp


Добрый день! Подскажите, пожалуйста, какие-нибудь библиотеки для измерения времени
выполнения участка кода на С++.  
    


Ответы

Ответ 1



Под Windows можно использовать QueryPerformanceCounter и QueryFrequencyCounter. Если необязательно нужен самый точный таймер, то можно использовать GetTickCount. Для измерения времени выполнения участка кода, сохраняй время до него и вычитай его из времени, полученном сразу после выполнения кода. Чтобы точнее вычислить время, желательно повторить код в цикле несколько раз, и результат поделить на это количество.

Ответ 2



Я меряю в миллисекундах. IMHO в реальности более мелким единицам доверять (при замерах производительности) нельзя. /* avp время в миллисекундах */ #include #include long long mtime() { struct timeval t; gettimeofday(&t, NULL); long long mt = (long long)t.tv_sec * 1000 + t.tv_usec / 1000; return mt; } Очень просто, работает и в Windows (использую MinGW) и в Linux.

Ответ 3



time.h - подключив библиотеку можно воспользоваться функцией получения времени time() - получить время перед выполнением блока кода, и после. Время выполнения блока, будет разницей полученных времен.

Ответ 4



достал из своих старых исходников такое решение без использования буст. немного длинно прошу извинить заголовок *profiler.h* #ifndef __unix #include #endif typedef unsigned __int64 uint64_t; typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; typedef __int64 int64_t; typedef signed int int32_t; typedef signed short int16_t; typedef signed char int8_t; union uint64x32_t { uint64_t m_ui64; struct ui32 { uint32_t m_uiLow; uint32_t m_uiHigh; } m_ui32; }; #define PROFILE_CALIBRATE 500 // 2 секунды namespace Profiler { // Класс, который снимает время выполнения участка кода class CPU { static int m_iFrequency; // частота процессора (КГц) uint64x32_t m_uiLastTick; // последний зарегстрированный отсчет uint32_t m_uiCountScale; // кол-во проверок uint64_t m_uiAccumulateTicks; // суммарное кол-во тиков процессорного времени uint64_t m_uiMinDelta, m_uiMaxDelta; // минимальный и максимальные отрезки static void Calibrate(int iProfilerCalibrate); public: CPU(int iProfilerCalibrate = PROFILE_CALIBRATE); virtual ~CPU(); void Reset(); void CheckIn(); void CheckOut(); inline uint32_t GetScaleCount(){return m_uiCountScale;} inline uint64_t GetAccumulateTicks(){return m_uiAccumulateTicks;} double GetAverageTime(){return ((double)m_uiAccumulateTicks)/(m_uiCountScale*m_iFrequency);} }; class ShotCPU : public CPU { public: ShotCPU(int iProfilerCalibrate = PROFILE_CALIBRATE): CPU(iProfilerCalibrate) { CheckIn(); } virtual ~ShotCPU(){ CheckOut(); fprintf(stdout, "\t%f", GetAverageTime()); } }; } #define SHOT_PROFILER_CPU Profiler::ShotCPU __s__p__ реализация *profiler.cpp* using namespace Profiler; #ifdef UNIX #include #define _rdtsc_(val) asm volatile ("rdtsc" : "=A" (val)) #else #define rdtsc __asm _emit 0x0f __asm _emit 0x31 #endif int CPU::m_iFrequency = 0; CPU::CPU(int iProfilerCalibrate){ Reset(); if(iProfilerCalibrate!=0 && m_iFrequency==0) Calibrate(iProfilerCalibrate); } CPU::~CPU() { } void CPU::Calibrate(int iProfilerCalibrate){ uint64x32_t FirstTick,LastTick; if(iProfilerCalibrate!=0){ #ifdef UNIX _rdtsc_(FirstTick.m_ui64); usleep(iProfilerCalibrate*1000); _rdtsc_(LastTick.m_ui64); #else rdtsc; __asm mov FirstTick.m_ui32.m_uiLow,eax __asm mov FirstTick.m_ui32.m_uiHigh,edx Sleep(iProfilerCalibrate); rdtsc; __asm mov LastTick.m_ui32.m_uiLow,eax __asm mov LastTick.m_ui32.m_uiHigh,edx #endif m_iFrequency = (int)((LastTick.m_ui64 - FirstTick.m_ui64)/iProfilerCalibrate); } } void CPU::Reset(){ m_uiCountScale = 0; m_uiAccumulateTicks = 0; m_uiMinDelta = 0; m_uiMaxDelta = 0; } void CPU::CheckIn(){ uint64x32_t uiCurrentTick; #ifdef UNIX _rdtsc_(uiCurrentTick.m_ui64); #else rdtsc; __asm mov uiCurrentTick.m_ui32.m_uiLow,eax __asm mov uiCurrentTick.m_ui32.m_uiHigh,edx #endif m_uiLastTick.m_ui64 = uiCurrentTick.m_ui64; } void CPU::CheckOut(){ uint64x32_t uiCurrentTick; #ifdef UNIX _rdtsc_(uiCurrentTick.m_ui64); #else rdtsc; __asm mov uiCurrentTick.m_ui32.m_uiLow,eax __asm mov uiCurrentTick.m_ui32.m_uiHigh,edx #endif uiCurrentTick.m_ui64 -= m_uiLastTick.m_ui64; m_uiCountScale++; m_uiAccumulateTicks += uiCurrentTick.m_ui64; m_uiMinDelta = m_uiMinDelta==0?uiCurrentTick.m_ui64:min(m_uiMinDelta,uiCurrentTick.m_ui64); m_uiMaxDelta = m_uiMaxDelta==0?uiCurrentTick.m_ui64:max(m_uiMaxDelta,uiCurrentTick.m_ui64); } самое простое использование - вставить SHOT_PROFILER_CPU в начало блока, скорость выполнения которого нужно замерить. { SHOT_PROFILER_CPU; // Какой то код }

Ответ 5



boost::timer timer: Измерение затраченного времени. progress_timer: Измерение затраченного времени (с использованием таймера), воспроизведение при уничтожении. progress_display: Отображение информации о прогрессе в направлении заданной цели.

Ответ 6



#include #include #include using namespace std; int main() { long t1 = clock(); long t2 = clock(); // какой-то код cout << t2 - t1 << endl; // это измерит время в миллисекундах // без загрузки выдаст 0 } Ещё очень часто удобно просто компилировать с опцией -fopenmp (g++ -fopenmp ...), подключать omp.h и использовать double omp_get_wtime(), которая возвращает время в секундах, но имеет тип double, т.е. покажет затраченное время, как, например, 12.3452 (12,3452 секунды): #ifdef _OPENMP #include #endif int main() { #ifdef _OPENMP double t1 = omp_get_wtime(); // ... double t2 = omp_get_wtime(); #endif } Удобно в связи с форматом (double) и тем, что почти все имеют поддержку openmp (gcc, компилятор в Microsoft Visual Studio, насколько я знаю, тоже, и др).

Ответ 7



С появлением C++11, появились дополнительные кроссплатформенные решения по измерению скорости выполнения кода стандартными средствами. В С++11 имеется библиотека времени chrono. В мире компьютера существует два типа часов: REALTIME(измеряет реальное время в системе) MONOTONIC(измеряет время начиная с некоторого времени в прошлом и всегда увеличивается) Вкратце, чтобы показать разницу между типами: если взять и перевести в системе часы назад, то значение MONOTONIC часов по-прежнему будет увеличиваться, а значение REALTIME часов станут меньше, так как системные часы переведены назад. Чем отличаются эти два типа часов более подробно рассказано в английском SO. Для измерения времени выполнения кода предпочтительнее использовать MONOTONIC часы. В библиотеке chrono классом, реализующего MONOTONIC часы, является класс steady_clock. Он гарантирует реальное измерение времени с максимально высокой точностью. С помощью него измерить разницу можно очень просто #include #include int main() { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); std::cout << "Diff(ms) = " << std::chrono::duration_cast(end - begin).count() << std::endl; std::cout << "Diff(ns) = " << std::chrono::duration_cast (end - begin).count() << std::endl; }

Комментариев нет:

Отправить комментарий