Как я могу узнать время выполнения раздела моей программы на C?

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

Это нужно только для возможности компиляции в Linux.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
0
16 638
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

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

Вам нужно приложение профайлер.

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

Профилировщик предоставляет статистическую информацию, которая отличается от фактического измерения.

Lee-Man 22.10.2010 22:40

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

Работает только на x86.

Хороший, у нас есть похожий, с полезным дополнением, PERF_MARK. Это позволит отметить точку умножения, хранящуюся в статическом массиве. У нас есть версия, которая может сохранять строку для удобного чтения результатов, по умолчанию массив содержит 100 записей, но может быть изменен. PERF_STOP выводит результаты.

Ilya 06.10.2008 11:35

Тем, кто добавил примечание об этом сбое в многоядерных системах: я удалил его, потому что это просто неверно. Макрос автоматически обрабатывает переключение контекста и другие внезапные изменения значений RDTSC, поэтому такой проблемы не существует. Я использую его исключительно на многоядерных машинах, и он отлично работает.

Dark Shikari 06.10.2008 13:32

Темный Шикари: Это не может быть правильным, этот макрос не может обрабатывать такие вещи, как упреждающее переключение контекста. Просто косяк. Это даст результаты, но они не будут точными. Кроме того, время возврата откалибровано для процессора Core2 (из-за #define NOP_CYCLES), и его необходимо изменить в соответствии с требованиями.

QAZ 06.10.2008 14:04
Ответ принят как подходящий

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

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

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

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

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

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

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

Как бы то ни было, вот один из нескольких макросов:

#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

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

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

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

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

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

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 для таймера, зависящего от потока.

Другие вопросы по теме