Как я могу найти время выполнения раздела моей программы в C?
Вопрос
Я пытаюсь найти способ получить время выполнения фрагмента кода на C. Я уже пробовал time () и clock () из time.h, но кажется, что time () возвращает Секунды и часы (), кажется, дают мне миллисекунды (или центсекунды?) Я хотел бы что-то более точное, хотя. Есть ли способ, которым я могу захватить время с точностью до микросекунды?
Это нужно только для возможности компиляции в 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;
}
Вам необходимо приложение для профилирования . Р>
Ключевые слова для поиска в SO и поисковых системах: профилирование в Linux
Ознакомьтесь с gettimeofday , clock_ * или get / setitimer .
Попробуйте " bench.h " ; это позволяет вам поставить START_TIMER; и STOP_TIMER (" имя "); в ваш код, что позволяет вам произвольно тестировать любой раздел кода (примечание: рекомендуется только для коротких разделов, а не для вещей, занимающих десятки миллисекунд или более). Он точен в тактовом цикле, хотя в некоторых редких случаях он может изменить способ компиляции промежуточного кода, и в этом случае вам лучше использовать профилировщик (хотя профилировщики, как правило, требуют больше усилий для конкретных разделов кода). р>
Это работает только на x86.
Возможно, вы захотите поискать инструмент инструментарий в Google.
Вы не найдете библиотечного вызова, который позволит вам преодолеть разрешение часов вашей платформы. Либо используйте профилировщик (man gprof), как предложил другой автор, либо - quick & amp; «грязный» - поместите цикл вокруг неправильной части кода, чтобы выполнить его много раз, и используйте clock (). Р>
gettimeofday ()
предоставляет вам разрешение в микросекундах, тогда как < code> clock_gettime () предоставляет вам разрешение наносекунд. Р>
int clock_gettime(clockid_t clk_id, struct timespec *tp);
clk_id
определяет часы, которые будут использоваться. Используйте CLOCK_REALTIME
, если вы хотите, чтобы часы всей системы были видны всем процессам. Используйте CLOCK_PROCESS_CPUTIME_ID
для таймера для каждого процесса и CLOCK_THREAD_CPUTIME_ID
для таймера, специфичного для потока.
Это зависит от условий. Профилировщики хороши для общих глобальных представлений, однако, если вам действительно нужно точное представление, я рекомендую KISS. Просто запустите код в цикле, так что это займет минуту или около того, чтобы завершить. Затем вычислите простое среднее на основе общего времени выполнения и выполненных итераций.
Этот подход позволяет вам:
<Ол>Получайте точные результаты с таймерами низкого разрешения.
Не возникайте проблем, когда инструментарий мешает работе высокоскоростных кэшей (l2, l1, branch..etc) рядом с процессором. Однако выполнение одного и того же кода в узком цикле также может дать оптимистичные результаты, которые могут не отражать реальных условий.
Не знаю, в какой среде / ОС вы работаете, но ваше время может быть неточным, если другой поток, задача или процесс вытесняет ваш синхронизированный код посередине. Я предлагаю исследовать механизмы, такие как мьютексы или семафоры, чтобы другие потоки не могли предопределить ваш процесс.
Если вы разрабатываете на x86 или x64, почему бы не использовать счетчик меток времени: RDTSC . р>
Это будет более надежным, чем функции Ansi C, такие как time () или clock (), поскольку RDTSC является атомарной функцией. Использование функций C для этой цели может создать проблемы, поскольку у вас нет гарантии, что поток, в котором они выполняются, не будет переключен, и в результате возвращаемое ими значение не будет точным описанием фактического времени выполнения, которое вы пытаетесь измерить. . р>
С помощью RDTSC вы можете лучше измерить это. Вам нужно будет преобразовать счетчик тиков обратно в читаемый человеком формат времени H: M: S, который будет зависеть от тактовой частоты процессоров, но Google будет вокруг, и я уверен, что вы найдете примеры.
Однако даже с помощью RDTSC вы будете учитывать время, в течение которого ваш код был выключен, а лучшее решение, чем использование time () / clock (), если вам нужно точное измерение, вам придется обратиться к профилировщику, который будет инструмент вашего кода и учитывать, когда ваш код на самом деле не выполняется из-за переключений контекста или чего-то еще.