Ответ 1
Вы упомянули clock()
и time()
- искали ли вы gettimeofday()
?
Это заполнит struct timeval
, который содержит секунды и микросекунды.
Конечно, фактическое разрешение зависит от аппаратного обеспечения.
Я пытаюсь найти способ получить время выполнения секции кода в C. Я уже пробовал как time(), так и clock() с time.h, но кажется, что time() возвращает секунды и часы(), кажется, дают мне миллисекунды (или centiseconds?). Мне хотелось бы что-то более точное. Есть ли способ захватить время с точностью не менее микросекунды?
Это нужно только для компиляции в Linux.
Вы упомянули clock()
и time()
- искали ли вы gettimeofday()
?
Это заполнит struct timeval
, который содержит секунды и микросекунды.
Конечно, фактическое разрешение зависит от аппаратного обеспечения.
Для чего это стоит, вот один из нескольких макросов:
#include <time.h>
clock_t startm, stopm;
#define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define PRINTTIME printf( "%6.3f seconds used by the processor.", ((double)stopm-startm)/CLOCKS_PER_SEC);
Затем просто используйте его с помощью:
main() {
START;
// Do stuff you want to time
STOP;
PRINTTIME;
}
Вам нужно приложение profiler.
Ключевые слова поиска в SO и поисковых системах: профилирование linux
Посмотрите gettimeofday, clock_ * или get/setitimer.
Попробуйте "bench.h" ; он позволяет установить START_TIMER; и STOP_TIMER ( "имя" ); в ваш код, позволяя вам произвольно оценивать любой раздел кода (обратите внимание: рекомендуется только для коротких разделов, а не для нескольких десятков миллисекунд или более). Его точность с тактовым циклом, хотя в некоторых редких случаях может изменить способ компрометации кода, и в этом случае вам лучше работать с профилировщиком (хотя для профилировщиков обычно больше усилий для использования для определенных разделов кода).
Он работает только на x86.
Возможно, вы захотите использовать Google для инструментария.
Вы не найдете вызов библиотеки, который позволит вам преодолеть временные рамки вашей платформы. Либо используйте профилировщик (man gprof), как предлагаемый другой плакат, либо - быстро и грязно - поместите цикл вокруг фрагмента кода, чтобы выполнить его много раз, и используйте clock().
gettimeofday()
предоставляет вам разрешение микросекунд, тогда как clock_gettime()
предоставляет вам разрешение наносекунд.
int clock_gettime(clockid_t clk_id, struct timespec *tp);
clk_id
обозначает часы, которые будут использоваться. Используйте CLOCK_REALTIME
, если вы хотите, чтобы все системные часы были видимыми для всех процессов. Используйте CLOCK_PROCESS_CPUTIME_ID
для таймера процесса и CLOCK_THREAD_CPUTIME_ID
для таймера, специфичного для потока.
Если вы разрабатываете на x86 или x64, почему бы не использовать счетчик временных меток: RDTSC.
Это будет более надежным, тогда Ansi C будет функционировать как time() или clock(), поскольку RDTSC является атомной функцией. Использование функций C для этой цели может привести к проблемам, поскольку у вас нет гарантии, что поток, который они выполняют, не будет отключен, и в результате возвращаемое им значение не будет точным описанием фактического времени выполнения, которое вы пытаетесь измерить.
С RDTSC вы можете лучше измерить это. Вам нужно будет пересчитать количество отсчетов обратно в человекообразное время H: M: S формат, который будет зависеть от тактовой частоты процессора, но google вокруг, и я уверен, что вы найдете примеры.
Однако даже с RDTSC вы будете включать время, когда ваш код был отключен от выполнения, в то время как лучшее решение, чем использование time()/clock(), если вам нужно точное измерение, вам придется обратиться к профилировщику, который будет инструмент ваш код и принимать во внимание, когда ваш код на самом деле не выполняется из-за переключений контекста или что-то еще.
Это зависит от условий. Профилиры хороши для общих глобальных взглядов, но если вам действительно нужно точное представление, то моя рекомендация - KISS. Просто запустите код в цикле, так что потребуется около минуты или около того. Затем вычислите простое среднее значение, основанное на общем времени выполнения и выполненных итерациях.
Этот подход позволяет вам:
Получить точные результаты с таймерами с низким разрешением.
Не срабатывают проблемы, когда аппаратура мешает высокоскоростным кэшам (l2, l1, branch..etc) близко к процессору. Однако запуск одного и того же кода в узком цикле также может обеспечить оптимистичные результаты, которые могут не отражать реальные условия в мире.
Не знаете, с какой средой/ОС вы работаете, но ваше время может быть неточным, если другой поток, задача или процесс вытесняют ваш временной код посередине. Я предлагаю изучить такие механизмы, как мьютексы или семафоры, чтобы предотвратить запуск других потоков.