2008-10-06 6 views
16

Я пытаюсь найти способ получить время выполнения секции кода в C. Я уже пробовал как time(), так и clock() от time.h, но кажется, что time() возвращает секунды и clock(), кажется, дает мне миллисекунды (или centiseconds?). Мне хотелось бы что-то более точное. Есть ли способ, чтобы я мог захватить время с точностью не менее микросекунды?Как найти время выполнения раздела моей программы в C?

Этого нужно только для компиляции на Linux.

ответ

15

Вы упомянули clock() и time() - искали ли вы gettimeofday()? Это заполнит struct timeval, который содержит секунды и микросекунды.

Конечно, фактическое разрешение зависит от оборудования.

1

Возможно, вы захотите обратиться к инструменту инструмент.

11

Вы хотите использовать приложение profiler.

поиск ключевых слов на SO и поисковые системы: Linux профилирование

+2

Профилятор предоставляет статистическую информацию, которая не совпадает с фактическим измерением. – 2010-10-22 18:40:53

2

Try "bench.h"; он позволяет установить START_TIMER; и STOP_TIMER («имя»); в ваш код, позволяя вам произвольно оценивать любой раздел кода (обратите внимание: рекомендуется только для коротких разделов, а не для нескольких десятков миллисекунд или более). Его точность с тактовым циклом, хотя в некоторых редких случаях может изменить способ компрометации кода, и в этом случае вам лучше работать с профилировщиком (хотя для профилировщиков обычно больше усилий для использования для определенных разделов кода).

Он работает только на x86.

+0

Хороший, у нас есть аналогичный, с полезным дополнением, PERF_MARK. Это позволит отметить точку умножения, сохраненную в статическом массиве. У нас есть версия, которая может сохранить строку для легкого чтения результатов, массив содержит по 100 записей по умолчанию, но может быть изменен. PERF_STOP сбрасывает результаты. – Ilya 2008-10-06 07:35:31

1

Вы не найдете вызова библиотеки, который позволит вам преодолеть временные рамки вашей платформы. Либо используйте профилировщик (man gprof), как предложил другой плакат, либо - быстро & грязный - поместите цикл вокруг фрагмента кода, чтобы выполнить его много раз, и используйте clock().

0

Если вы разрабатываете x86 или x64, почему бы не использовать счетчик штампов времени: RDTSC.

Он будет более надежным, чем функция Ansi C, такая как time() или clock(), поскольку RDTSC является атомной функцией. Использование функций C для этой цели может привести к проблемам, поскольку у вас нет гарантии, что поток, который они выполняют, не будет отключен, и в результате возвращаемое им значение не будет точным описанием фактического времени выполнения, которое вы пытаетесь измерить ,

С RDTSC вы можете лучше измерить это. Вам нужно будет преобразовать количество отсчетов обратно в человекообразное время H: M: S формат, который будет зависеть от тактовой частоты процессора, но google вокруг, и я уверен, что вы найдете примеры.

Однако даже при использовании RDTSC вы будете включать время, когда ваш код был отключен от исполнения, в то время как лучшее решение, чем использование времени()/clock(), если вам нужно точное измерение, вам придется обратиться к профилировщику, который будет обрабатывать ваш код и принимать во внимание, когда ваш код на самом деле не выполняется из-за переключений контекста или чего-то еще.

12

Для чего это стоит, вот тот, который только несколько макросов:

#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; 
} 

От http://ctips.pbwiki.com/Timer

0

Это зависит от условий .. Профилиры хороши для общих глобальных взглядов, однако, если вам действительно нужно точное представление, моя рекомендация - KISS. Просто запустите код в цикле, так что потребуется около минуты или около того. Затем вычислите простое среднее значение, основанное на общем времени выполнения и выполненных итерациях.

Такой подход позволяет:

  1. Получить точные результаты с таймерами низким разрешением.

  2. Неисправность в проблемах, когда аппаратура мешает высокоскоростным кэшам (l2, l1, branch..etc) близко к процессору. Однако запуск одного и того же кода в узком цикле также может обеспечить оптимистичные результаты, которые могут не отражать реальные условия.

0

Не знаю, какой окружающую среда/OS вы работаете, но ваше время может быть неточным, если другой поток, задача или процесс вытесняет ваш приуроченный код в середине. Я предлагаю изучить такие механизмы, как мьютексы или семафоры, чтобы предотвратить прохождение других потоков из вашего процесса.

1

gettimeofday() дает вам разрешение микросекунд, тогда как clock_gettime() предоставляет вам разрешение наносекунд.

int clock_gettime(clockid_t clk_id, struct timespec *tp); 

The clk_id идентифицирует часы, которые будут использоваться. Используйте CLOCK_REALTIME, если вы хотите, чтобы все системные часы были видимыми для всех процессов. Используйте CLOCK_PROCESS_CPUTIME_ID для каждого таймера процесса и CLOCK_THREAD_CPUTIME_ID для таймера, специфичного для потока.