$ time foo
real 0m0.003s
user 0m0.000s
sys 0m0.004s
$
Что означает «реальный», «пользователь» и «sys» в выводе времени?
Какой из них имеет смысл при сравнении моего приложения?
unix
time
benchmarking
rayryeng
источник
источник
time
, сделайте так, чтобы она заняла не менее секунды.time
это ключевое слово bash. Так , набравman time
в не давая вам справочную страницу для Башаtime
, а это дает справочную страницу для/usr/bin/time
. Это сбило меня с толку.Ответы:
Real, User и Sys обрабатывают статистику времени
Одна из этих вещей не похожа на другую. Реальное относится к фактическому прошедшему времени; Пользователь и Sys ссылаются на процессорное время, используемое только процессом.
Реальное время настенные часы - время от начала до конца разговора. Это все прошедшее время, включая временные интервалы, используемые другими процессами, и время, которое процесс блокирует (например, если он ожидает завершения ввода-вывода).
Пользователь - это количество процессорного времени, потраченного в коде пользовательского режима (вне ядра) внутри процесса. Это только фактическое время процессора, используемое при выполнении процесса. Другие процессы и время, затраченное процессом заблокировано, не учитываются в этом показателе.
Sys - это количество процессорного времени, проведенного в ядре в процессе. Это означает выполнение процессорного времени, затраченного на системные вызовы в ядре, в отличие от библиотечного кода, который все еще выполняется в пользовательском пространстве. Как и «пользователь», это только время процессора, используемое процессом. Ниже приведено краткое описание режима ядра (также известного как режим 'supervisor') и механизма системных вызовов.
User+Sys
скажет вам сколько фактического процессорного времени ваш процесс использовал. Обратите внимание, что это относится ко всем процессорам, поэтому, если процесс имеет несколько потоков (и этот процесс выполняется на компьютере с более чем одним процессором), он может потенциально превысить время настенных часов, сообщаемоеReal
(что обычно происходит). Обратите внимание, что в выходных данных эти цифры включают в себяUser
иSys
время всех дочерних процессов (и их потомков), а также когда они могли быть собраны, например,wait(2)
илиwaitpid(2)
, хотя базовые системные вызовы возвращают статистику для процесса и его дочерних элементов отдельно.Происхождение статистики, представленной
time (1)
Статистические данные получены
time
из различных системных вызовов. «Пользователь» и «Sys» происходят изwait (2)
( POSIX ) илиtimes (2)
( POSIX ), в зависимости от конкретной системы. «Реальный» рассчитывается по времени начала и окончания, полученному отgettimeofday (2)
вызова. В зависимости от версии системы, различные другие статистические данные, такие как количество переключений контекста, также могут быть собраныtime
.На многопроцессорной машине многопоточный процесс или дочерний процесс может иметь истекшее время меньше, чем общее время ЦП, поскольку разные потоки или процессы могут выполняться параллельно. Кроме того, статистические данные о времени поступают из разных источников, поэтому время, записанное для очень коротких задач, может быть подвержено ошибкам округления, как показано в примере, приведенном в оригинальном постере.
Краткое руководство по режиму «Ядро против пользователя»
В Unix или любой другой операционной системе с защищенной памятью режим «Ядро» или «Супервизор» относится к привилегированному режиму , в котором может работать ЦП. Некоторые привилегированные действия, которые могут повлиять на безопасность или стабильность, могут выполняться только тогда, когда ЦП работает в этот режим; эти действия недоступны для кода приложения. Примером такого действия может быть манипулирование MMU для получения доступа к адресному пространству другого процесса. Обычно код пользовательского режима не может сделать это (по уважительной причине), хотя он может запрашивать общую память у ядра, что можетбыть прочитанным или написанным более чем одним процессом. В этом случае общая память запрашивается у ядра через безопасный механизм, и оба процесса должны явно подключаться к ней, чтобы использовать ее.
Привилегированный режим обычно называется режимом «ядро», поскольку ядро выполняется процессором, работающим в этом режиме. Чтобы переключиться в режим ядра, вы должны выполнить специальную инструкцию (часто называемую прерыванием ), которая переключает ЦП на работу в режиме ядра и запускает код из определенного места, содержащегося в таблице переходов. По соображениям безопасности вы не можете переключиться в режим ядра и выполнить произвольный код - управление ловушками осуществляется через таблицу адресов, в которую невозможно записать, если процессор не работает в режиме супервизора. Вы ловите с явным номером ловушки, и адрес ищется в таблице переходов; ядро имеет конечное число контролируемых точек входа.
«Системные» вызовы в библиотеке C (особенно те, которые описаны в Разделе 2 справочных страниц) содержат компонент пользовательского режима, который вы фактически вызываете из своей программы на C. За кулисами они могут отправлять ядру один или несколько системных вызовов для выполнения определенных услуг, таких как ввод-вывод, но у них все еще есть код, работающий в пользовательском режиме. При желании также вполне возможно напрямую выполнить прерывание в режиме ядра из любого кода пользовательского пространства, хотя вам может потребоваться написать фрагмент ассемблера, чтобы правильно настроить регистры для вызова.
Подробнее о 'sys'
Есть вещи, которые ваш код не может сделать из пользовательского режима - например, выделение памяти или доступ к оборудованию (жесткий диск, сеть и т. Д.). Они находятся под наблюдением ядра, и только он может сделать это. Некоторые операции, такие как
malloc
илиfread
/,fwrite
будут вызывать эти функции ядра, и тогда они будут считаться временем 'sys'. К сожалению, это не так просто, как «каждый вызов malloc будет учитываться во время 'sys'". Вызов tomalloc
будет выполнять некоторую собственную обработку (все еще учитывается во время «пользователя»), а затем где-то по пути он может вызывать функцию в ядре (считается во время «sys»). После возврата из вызова ядра будет еще некоторое время в 'user', а затемmalloc
вернусь к вашему коду. Что касается того, когда произойдет переключение, и сколько его будет потрачено в режиме ядра ... вы не можете сказать. Это зависит от реализации библиотеки. Кроме того, другие, казалось бы, невинные функции могут также использоватьmalloc
и тому подобное в фоновом режиме, что снова будет иметь некоторое время в 'sys'.источник
Чтобы расширить принятый ответ , я просто хотел привести еще одну причину, по которой
real
≠user
+sys
.Имейте в виду, что
real
представляет фактическое прошедшее время,user
аsys
значения и представляют время выполнения ЦП. В результате в многоядерной системе времяuser
и / илиsys
время (а также их сумма) могут фактически превышать реальное время. Например, в приложении Java, которое я запускаю для класса, я получаю этот набор значений:источник
real
превышенииuser
иsys
общем? Затраты ОС, такие как переключение контекста потока, могут быть?• реальное : фактическое время, потраченное на выполнение процесса от начала до конца, как если бы оно измерялось человеком с секундомером
• пользователь : совокупное время, потраченное всеми процессорами во время вычислений
• sys : совокупное время, потраченное всеми процессорами на системные задачи, такие как выделение памяти.
источник
sys
время ЦП затрачивается на системные вызовы (и обработчики сбоев страниц?)real
часто описывается как «настенные часы» время.Минимальные исполняемые примеры POSIX C
Чтобы сделать вещи более конкретными, я хочу привести в пример несколько крайних случаев
time
с некоторыми минимальными программами тестирования на Си.Все программы могут быть скомпилированы и запущены с:
и были протестированы в Ubuntu 18.10, GCC 8.2.0, glibc 2.28, ядре Linux 4.18, ноутбуке ThinkPad P51, процессоре Intel Core i7-7820HQ (4 ядра / 8 потоков), 2x оперативной памяти Samsung M471A2K43BB1-CRC (2x 16 ГБ).
спать
Незанятого сон не учитывается ни в одном
user
илиsys
толькоreal
.Например, программа, которая спит на секунду:
GitHub вверх по течению .
выводит что-то вроде:
То же самое относится и к программам, заблокированным на IO.
Например, следующая программа ждет, когда пользователь введет символ и нажмет ввод:
GitHub вверх по течению .
И если вы подождете около одной секунды, он выдаст как пример сна что-то вроде:
По этой причине
time
может помочь вам различать программы, связанные с процессором и вводом- выводом: что означают термины «привязка к процессору» и «привязка ввода-вывода»?Несколько потоков
В следующем примере выполняются
niters
итерации бесполезной, чисто связанной с ЦП, работы сnthreads
потоками:GitHub upstream + сюжетный код .
Затем мы рисуем wall, user и sys как функцию от числа потоков для фиксированных 10 ^ 10 итераций на моем 8-процессорном процессоре с гиперпотоками:
Сюжет данных .
Из графика мы видим, что:
для одноядерного приложения, интенсивно использующего процессор, стена и пользователь примерно одинаковы
для 2 ядер пользователь примерно в 2 раза больше стены, что означает, что пользовательское время учитывается во всех потоках.
Пользователь в основном удвоился, и при этом стена осталась прежней.
это продолжается до 8 потоков, что соответствует моему числу гиперпотоков на моем компьютере.
После 8 стена также начинает увеличиваться, потому что у нас нет лишних процессоров, чтобы выполнять больше работы за данный промежуток времени!
Соотношение плато на данный момент.
Обратите внимание, что этот график только настолько ясен и прост, потому что работа связана только с процессором: если бы он был связан с памятью, то мы бы получили падение производительности намного раньше с меньшим количеством ядер, потому что доступ к памяти был бы узким местом, как показано в разделе Что означают термины «привязка к процессору» и «привязка ввода / вывода»?
Sys тяжелая работа с
sendfile
Самая тяжелая рабочая нагрузка sys, которую я мог придумать, состояла в том
sendfile
, чтобы использовать функцию, которая выполняет операцию копирования файла в пространстве ядра: копирование файла разумным, безопасным и эффективным способом.Таким образом, я представлял, что это ядро
memcpy
будет загружать процессор.Сначала я инициализирую большой 10GiB случайный файл:
Затем запустите код:
GitHub вверх по течению .
что дает в основном системное время, как и ожидалось:
Мне также было любопытно посмотреть,
time
будут ли различаться системные вызовы разных процессов, поэтому я попытался:И результат был:
Время системы примерно одинаково для обоих процессов, но время задержки больше, поскольку процессы конкурируют за доступ к чтению с диска.
Таким образом, кажется, что он действительно учитывает, какой процесс начал работу с ядром.
Исходный код Bash
Когда вы используете только
time <cmd>
Ubuntu, он использует ключевое слово Bash, как видно из:какие выводы:
Итак, мы ищем исходный код в исходном коде Bash 4.19 для выходной строки:
что приводит нас к функции execute_cmd.c
time_command
, которая использует:gettimeofday()
иgetrusage()
если оба доступныtimes()
в противном случаевсе это системные вызовы Linux и функции POSIX .
Исходный код GNU Coreutils
Если мы называем это как:
затем он использует реализацию GNU Coreutils.
Это немного сложнее, но соответствующий источник, кажется, находится в resuse.c, и он делает:
wait3
вызов не POSIX BSD, если он доступенtimes
иgettimeofday
иначеисточник
Real показывает общее время оборота процесса; в то время как пользователь показывает время выполнения пользовательских инструкций, а Sys - время выполнения системных вызовов!
Реальное время также включает время ожидания (время ожидания ввода-вывода и т. Д.)
источник