У меня есть программа на C, которая предназначена для параллельного запуска на нескольких процессорах. Мне нужно иметь возможность записывать время выполнения (которое может быть от 1 секунды до нескольких минут). Я искал ответы, но все они, кажется, предлагают использовать clock()
функцию, которая затем включает в себя подсчет количества часов, которые программа взяла, деленных на Clocks_per_second
значение.
Я не уверен, как Clocks_per_second
рассчитывается значение?
В Java я просто беру текущее время в миллисекундах до и после выполнения.
Есть ли подобное в C? Я посмотрел, но я не могу найти способ получить что-то лучше, чем второе разрешение.
Я также знаю, что вариант был бы вариант, но я пытаюсь реализовать таймер сам.
Спасибо
c
benchmarking
Роджер
источник
источник
Ответы:
CLOCKS_PER_SEC
константа, которая объявлена в<time.h>
. Чтобы получить процессорное время, используемое задачей в приложении C, используйте:Обратите внимание, что это возвращает время как тип с плавающей запятой. Это может быть более точным, чем секунда (например, вы измеряете 4,52 секунды). Точность зависит от архитектуры; в современных системах вы легко получаете 10 мс или меньше, но на старых машинах Windows (из эпохи Win98) оно было ближе к 60 мс.
clock()
является стандартным C; это работает "везде". Есть системные функции, такие какgetrusage()
Unix-подобных системах.Java
System.currentTimeMillis()
не измеряет одно и то же. Это «настенные часы»: они могут помочь вам измерить, сколько времени потребовалось для выполнения программы, но они не сообщают вам, сколько процессорного времени было использовано. В многозадачных системах (то есть во всех) они могут сильно различаться.источник
clock()
возвращает время в некотором внутреннем масштабе, называемом «часами», иCLOCKS_PER_SEC
представляет собой количество часов в секунду, поэтому деление наCLOCKS_PER_SEC
дает время в секундах. В приведенном выше коде значение являетсяdouble
таким, что вы можете масштабировать его по своему желанию.CLOCKS_PER_SEC
этоlong int
значение1000000
, которое дает время в микросекундах, когда оно не разделено; не тактовые частоты процессора. Поэтому не нужно учитывать динамическую частоту, так как здесь тактовая частота в микросекундах (может быть тактовая частота для процессора 1 МГц?) Я сделал короткую программу на C, напечатав это значение, и это было 1000000 на моем ноутбуке i7-2640M, с динамической частотой от 800 МГц до 2,8 ГГц, даже при использовании Turbo Boost до 3,5 ГГц.Если вы используете оболочку Unix для запуска, вы можете использовать команду времени.
дела
при условии, что a.out в качестве исполняемого файла даст вам время, необходимое для запуска этого
источник
perf stat ./a.out
для получения счетчиков производительности HW при пропадании кэша и филиал ошибается, и IPC.В простой ванили C:
источник
Вы функционально хотите это:
Обратите внимание, что это измеряется в микросекундах, а не в секундах.
источник
gettimeofday
устарел и не рекомендуется для нового кода. Его справочная страница POSIX рекомендует вместо этого clock_gettime , которая позволяет вам спрашиватьCLOCK_MONOTONIC
, не влияет ли изменение системных часов, и, следовательно, оно лучше как интервал времени. (См . Ответ JohnSll ). Например, в современных системах Linux gettimeofday - это оболочка для clock_gettime, которая преобразует наносекунды в микросекунды.Большинство простых программ имеют время вычисления в миллисекундах. Итак, я полагаю, вы найдете это полезным.
Если вы хотите вычислить время выполнения всей программы и находитесь в системе Unix, запустите вашу программу с помощью команды time, подобной этой
time ./a.out
источник
Много ответов было предложено,
clock()
а затемCLOCKS_PER_SEC
отtime.h
. Вероятно, это плохая идея, потому что это то, что/bits/time.h
говорит мой файл:Таким образом,
CLOCKS_PER_SEC
может быть определено как 1000000, в зависимости от того, какие опции вы используете для компиляции, и, таким образом, это не кажется хорошим решением.источник
CLOCK_PER_SEC==1000000
, но в то же время все они используют точность в 1 мкс для своей реализации clock (); кстати, у него есть приятное свойство уменьшать проблемы с совместным использованием. Если вы хотите измерить потенциально очень быстрые события, скажем, менее 1 мс, то вам следует сначала позаботиться о точности (или разрешающей способности) функции clock (), которая обязательно грубее, чем 1 мкс в Posix, но также часто намного грубее; обычное решение - запустить тест много раз; вопрос в том виде, в котором он задавался, похоже, не требовал этого.clock()
, если вы делите это значение сCLOCK_PER_SEC
гарантией получения времени в секундах, затраченного процессором. Ответственность за измерение фактической тактовой частоты лежит наclock()
функции, а не на вас.Томас Порнин ответил как макрос:
Используйте это так:
Вывод:
источник
Вы должны принять во внимание, что измерение времени, которое потребовалось для выполнения программы, во многом зависит от нагрузки, которую машина имеет в данный конкретный момент.
Зная, что способ получения текущего времени в C может быть достигнут различными способами, более простой:
Надеюсь, поможет.
С уважением!
источник
(Все ответы здесь отсутствуют, если ваш системный администратор меняет системное время или ваш часовой пояс отличается от зимнего и летнего времени. Поэтому ...)
При использовании Linux:
clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable);
это не влияет, если системный администратор меняет время или вы живете в стране, где зима отличается от летней и т. Д.man clock_gettime
состояния:источник
(end.tv_nsec - begin.tv_nsec) / 1000000000.0
результат0
всегда?double
буквальных триггера INT илиlong
дляdouble
преобразования до разделения. Конечно, вы можете просто придерживаться целого числа и печататьtv_sec
часть, а затем дробную часть с нулевым значением%ld.%09ld
, но преобразование в двойное легко, и 53 бита точности обычно достаточно для эталонного времени.timespec_subtract
чтоtimeval_subtract
предложено в руководстве по glibc : gnu.org/software/libc/manual/html_node/Elapsed-Time.html )ANSI C определяет только функции времени второй точности. Однако, если вы работаете в среде POSIX, вы можете использовать gettimeofday () которая обеспечивает разрешение микросекунд времени, прошедшего с начала эпохи UNIX.
В качестве примечания, я бы не рекомендовал использовать clock (), поскольку он плохо реализован во многих (если не во всех?) Системах и не точен, кроме того, что он относится только к тому, сколько времени ваша программа провела на процессоре и не общее время жизни программы, которое, как я полагаю, вы хотели бы измерить в соответствии с вашим вопросом.
источник
Каждое решение не работает в моей системе.
Я могу использовать
источник
time_t
значениями в двойном размере. Посколькуtime_t
значения имеют точность только с точностью до секунды, они имеют ограниченную ценность при распечатке времени, затрачиваемого короткими программами, хотя это может быть полезно для программ, работающих в течение длительных периодов времени.clock_t
s to,difftime
кажется, работает для меня с точностью до одной сотой секунды. Это на Linux x86. Я также не могу получить вычитаниеstop
иstart
работать.difftime()
clock() / CLOCKS_PER_SEC
, как он ожидает, секунды.источник
Я обнаружил, что обычные часы (), которые все здесь рекомендуют, по какой-то причине сильно отклоняются от запуска к запуску, даже для статического кода без каких-либо побочных эффектов, таких как рисование на экране или чтение файлов. Это может быть связано с тем, что процессор меняет режимы энергопотребления, ОС выделяет разные приоритеты и т. Д.
Таким образом, единственный способ надежно получать один и тот же результат каждый раз с помощью clock () - это запускать измеренный код в цикле несколько раз (в течение нескольких минут), принимая меры предосторожности, чтобы не допустить его оптимизации компилятором: современные компиляторы могут предварительно вычислять код без побочных эффектов, работающих в цикле, и выведите его из цикла, например, используя случайный ввод для каждой итерации.
После того, как достаточное количество образцов собрано в массив, один сортирует этот массив и берет средний элемент, называемый медианой. Медиана лучше, чем в среднем, потому что она отбрасывает крайние отклонения, как, например, антивирус загружает весь процессор или ОС делает некоторые обновления.
Вот простая утилита для измерения производительности выполнения кода C / C ++ с усреднением значений около медианы: https://github.com/saniv/gauge
Я сам все еще ищу более надежный и быстрый способ измерения кода. Вероятно, можно попробовать запустить код в контролируемых условиях на голом железе без какой-либо ОС, но это даст нереальный результат, потому что в действительности ОС действительно вмешивается.
В x86 есть эти аппаратные счетчики производительности, которые включают фактическое количество выполненных инструкций, но их сложно получить без помощи ОС, сложно интерпретировать и у них есть свои проблемы ( http://archive.gamedev.net/archive/reference/articles /article213.html ). Тем не менее, они могут быть полезны при изучении природы горлышка бутылки (доступ к данным или фактические вычисления на этих данных).
источник
performance
) или многие десятки миллисекунд. en.wikipedia.org/wiki/Dynamic_frequency_scaling . И да, средняя производительность, как правило, хороший выбор; у высокого конца обычно есть некоторые шипы от вмешательства.main
который принимает аргумент и возвращает результат, и не использует оптимизацию во время компоновки. Тогда компилятор не может вставить его в вызывающую программу. Работает только в том случае, если функция уже содержит какой-то цикл, в противном случае издержки call / ret слишком велики.Некоторые могут посчитать полезными другие виды ввода: мне дали этот метод измерения времени в рамках университетского курса по программированию GPGPU с NVidia CUDA ( описание курса ). Он сочетает в себе методы, описанные в предыдущих публикациях, и я просто публикую его, потому что требования придают ему достоверность:
Я полагаю, вы могли бы умножить на, например,
1.0 / 1000.0
чтобы получить единицу измерения, которая соответствует вашим потребностям.источник
clock_gettime
Вместо этого рекомендуется его справочная страница POSIX , которая позволяет вам спрашиватьCLOCK_MONOTONIC
, не влияют ли изменения системных часов, и, следовательно, лучше в качестве интервального таймера. Например, в современных системах Linuxgettimeofday
это оболочка,clock_gettime
которая преобразует наносекунды в микросекунды. (См. Ответ JohnSll).timeval_subtract
.Сравнение времени выполнения сортировки и выделения пузырьков У меня есть программа, которая сравнивает время выполнения сортировки и выделения пузырьков. Чтобы узнать время выполнения блока кода, рассчитайте время до и после блока
Пример кода:
источник