$ time foo
real 0m0.003s
user 0m0.000s
sys 0m0.004s
$
Apa arti 'nyata', 'pengguna' dan 'sistem' dalam output waktu?
Yang mana yang berarti ketika membandingkan aplikasi saya?
unix
time
benchmarking
rayryeng
sumber
sumber
time
, minta ia melakukan sesuatu yang akan memakan waktu setidaknya satu detik.time
adalah kata kunci bash. Jadi mengetikman time
ini tidak memberikan Anda halaman manual untuk bashtime
, melainkan memberikan halaman manual untuk/usr/bin/time
. Ini telah membuat saya tersandung.Jawaban:
Statistik waktu proses nyata, Pengguna dan Sys
salah satu dari benda ini tidak seperti yang lain. Real mengacu pada waktu aktual yang telah berlalu; Pengguna dan Sistem mengacu pada waktu CPU yang hanya digunakan oleh proses.
Real adalah jam dinding - waktu dari awal hingga akhir panggilan. Ini semua waktu yang telah berlalu termasuk irisan waktu yang digunakan oleh proses lain dan waktu proses yang dihabiskan diblokir (misalnya jika menunggu I / O untuk menyelesaikan).
Pengguna adalah jumlah waktu CPU yang dihabiskan dalam kode mode pengguna (di luar kernel) dalam proses. Ini hanya waktu CPU aktual yang digunakan dalam menjalankan proses. Proses dan waktu lain yang dihabiskan proses tidak termasuk dalam angka ini.
Sys adalah jumlah waktu CPU yang dihabiskan di kernel dalam proses. Ini berarti mengeksekusi waktu CPU yang dihabiskan dalam panggilan sistem di dalam kernel, sebagai lawan dari kode perpustakaan, yang masih berjalan di ruang pengguna. Seperti 'pengguna', ini hanya waktu CPU yang digunakan oleh proses. Lihat di bawah untuk penjelasan singkat tentang mode kernel (juga dikenal sebagai mode 'supervisor') dan mekanisme panggilan sistem.
User+Sys
akan memberi tahu Anda berapa sebenarnya waktu CPU yang digunakan proses Anda. Perhatikan bahwa ini ada di semua CPU, jadi jika prosesnya memiliki banyak utas (dan proses ini berjalan pada komputer dengan lebih dari satu prosesor) ini berpotensi melebihi waktu jam dinding yang dilaporkan olehReal
(yang biasanya terjadi). Perhatikan bahwa dalam output angka-angka ini termasuk waktuUser
danSys
semua proses anak (dan turunannya) serta kapan mereka bisa dikumpulkan, misalnya olehwait(2)
atauwaitpid(2)
, meskipun sistem yang mendasari panggilan mengembalikan statistik untuk proses dan anak-anaknya secara terpisah.Asal-usul statistik yang dilaporkan oleh
time (1)
Statistik yang dilaporkan
time
dikumpulkan dari berbagai panggilan sistem. 'Pengguna' dan 'Sistem' berasal dariwait (2)
( POSIX ) atautimes (2)
( POSIX ), tergantung pada sistem tertentu. 'Nyata' dihitung dari waktu mulai dan berakhir dikumpulkan darigettimeofday (2)
panggilan. Bergantung pada versi sistem, berbagai statistik lain seperti jumlah sakelar konteks juga dapat dikumpulkantime
.Pada mesin multi-prosesor, proses multi-utas atau proses forking anak dapat memiliki waktu yang berlalu lebih kecil dari total waktu CPU - karena berbagai utas atau proses dapat berjalan secara paralel. Juga, statistik waktu yang dilaporkan berasal dari asal yang berbeda, jadi waktu yang direkam untuk tugas yang berjalan sangat singkat dapat mengalami kesalahan pembulatan, seperti contoh yang diberikan oleh poster asli menunjukkan.
Primer singkat tentang mode Kernel vs. Pengguna
Pada Unix, atau sistem operasi memori terproteksi, mode 'Kernel' atau 'Supervisor' mengacu pada mode istimewa yang dapat dioperasikan CPU. Tindakan istimewa tertentu yang dapat memengaruhi keamanan atau stabilitas hanya dapat dilakukan ketika CPU beroperasi di mode ini; tindakan ini tidak tersedia untuk kode aplikasi. Contoh dari tindakan semacam itu mungkin adalah manipulasi MMU untuk mendapatkan akses ke ruang alamat proses lain. Biasanya, kode mode pengguna tidak dapat melakukan ini (dengan alasan yang baik), meskipun dapat meminta memori bersama dari kernel, yang bisadibaca atau ditulis oleh lebih dari satu proses. Dalam hal ini, memori bersama secara eksplisit diminta dari kernel melalui mekanisme aman dan kedua proses harus secara eksplisit melampirkan padanya untuk menggunakannya.
Mode istimewa biasanya disebut sebagai mode 'kernel' karena kernel dijalankan oleh CPU yang berjalan dalam mode ini. Untuk beralih ke mode kernel Anda harus mengeluarkan instruksi khusus (sering disebut jebakan ) yang mengalihkan CPU untuk berjalan dalam mode kernel dan menjalankan kode dari lokasi tertentu yang disimpan dalam tabel lompatan. Untuk alasan keamanan, Anda tidak dapat beralih ke mode kernel dan menjalankan kode arbitrer - jebakan dikelola melalui daftar alamat yang tidak dapat dituliskan kecuali CPU sedang berjalan dalam mode supervisor. Anda menjebak dengan nomor perangkap eksplisit dan alamatnya terlihat di tabel lompatan; kernel memiliki sejumlah titik masuk yang terkontrol.
Panggilan 'sistem' di pustaka C (khususnya yang dijelaskan dalam Bagian 2 halaman manual) memiliki komponen mode pengguna, yang sebenarnya Anda panggil dari program C Anda. Di belakang layar, mereka mungkin mengeluarkan satu atau lebih panggilan sistem ke kernel untuk melakukan layanan tertentu seperti I / O, tetapi mereka juga masih memiliki kode yang berjalan dalam mode pengguna. Dimungkinkan juga untuk secara langsung mengeluarkan jebakan ke mode kernel dari kode ruang pengguna mana pun jika diinginkan, walaupun Anda mungkin perlu menulis cuplikan bahasa rakitan untuk mengatur register dengan benar untuk panggilan tersebut.
Lebih lanjut tentang 'sys'
Ada beberapa hal yang tidak bisa dilakukan oleh kode Anda dari mode pengguna - hal-hal seperti mengalokasikan memori atau mengakses perangkat keras (HDD, jaringan, dll.). Ini berada di bawah pengawasan kernel, dan itu saja yang dapat melakukannya. Beberapa operasi seperti
malloc
ataufread
/fwrite
akan menjalankan fungsi-fungsi kernel ini dan itu akan dihitung sebagai waktu 'sys'. Sayangnya itu tidak sesederhana "setiap panggilan ke malloc akan dihitung dalam waktu 'sys'". Panggilan untukmalloc
akan melakukan pemrosesan sendiri (masih dihitung dalam waktu 'pengguna') dan kemudian di suatu tempat di sepanjang jalan itu dapat memanggil fungsi dalam kernel (dihitung dalam waktu 'sys'). Setelah kembali dari panggilan kernel, akan ada lebih banyak waktu di 'pengguna' dan kemudianmalloc
akan kembali ke kode Anda. Adapun ketika saklar terjadi, dan berapa banyak yang dihabiskan dalam mode kernel ... Anda tidak bisa mengatakannya. Itu tergantung pada implementasi perpustakaan. Juga, fungsi-fungsi lain yang tampaknya tidak bersalah juga dapat digunakanmalloc
dan sejenisnya di latar belakang, yang lagi-lagi akan memiliki waktu di 'sys'.sumber
Untuk memperluas jawaban yang diterima , saya hanya ingin memberikan alasan lain mengapa
real
≠user
+sys
.Ingatlah bahwa itu
real
mewakili waktu berlalu sebenarnya, sementarauser
dansys
nilai - nilai mewakili waktu eksekusi CPU. Akibatnya, pada sistem multicore, waktuuser
dan / atausys
waktu (serta jumlah mereka) benar-benar dapat melebihi waktu sebenarnya. Misalnya, pada aplikasi Java yang saya jalankan untuk kelas saya mendapatkan serangkaian nilai ini:sumber
real
melebihiuser
dansys
total? OS overhead seperti switching konteks konteks mungkin?• nyata : Waktu aktual yang dihabiskan dalam menjalankan proses dari awal hingga selesai, seolah-olah itu diukur oleh manusia dengan stopwatch
• pengguna : Waktu kumulatif yang dihabiskan oleh semua CPU selama perhitungan
• sys : Waktu kumulatif yang dihabiskan oleh semua CPU selama tugas yang berkaitan dengan sistem seperti alokasi memori.
sumber
sys
waktu CPU dihabiskan untuk panggilan sistem (dan penangan kesalahan halaman?)real
sering digambarkan sebagai waktu "jam dinding".Contoh POSIX C runnable minimal
Untuk membuat segalanya lebih konkret, saya ingin memberikan contoh beberapa kasus ekstrem
time
dengan beberapa program uji C minimal.Semua program dapat dikompilasi dan dijalankan dengan:
dan telah diuji di Ubuntu 18.10, GCC 8.2.0, glibc 2.28, kernel Linux 4.18, laptop ThinkPad P51, CPU Intel Core i7-7820HQ (4 core / 8 thread), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB).
tidur
Tidur yang tidak sibuk tidak dihitung dalam salah satu
user
atausys
, hanyareal
.Misalnya, program yang tidur sebentar:
GitHub hulu .
menghasilkan sesuatu seperti:
Hal yang sama berlaku untuk program yang diblokir pada IO menjadi tersedia.
Misalnya, program berikut menunggu pengguna untuk memasukkan karakter dan tekan enter:
GitHub hulu .
Dan jika Anda menunggu sekitar satu detik, itu output seperti contoh tidur seperti:
Untuk alasan ini
time
dapat membantu Anda membedakan antara program terikat CPU dan IO: Apa arti istilah "terikat CPU" dan "I / O terikat"?Beberapa utas
Contoh berikut melakukan
niters
iterasi dari pekerjaan CPU-murni yang tidak berguna padanthreads
utas:GitHub kode hulu + plot .
Kemudian kami memplot wall, user dan sys sebagai fungsi dari jumlah utas untuk iterasi 10 ^ 10 yang diperbaiki pada CPU 8 hyperthread saya:
Plot data .
Dari grafik, kita melihat bahwa:
untuk aplikasi inti tunggal CPU intensif, dinding dan pengguna hampir sama
untuk 2 core, pengguna sekitar 2x dinding, yang berarti bahwa waktu pengguna dihitung di semua utas.
pengguna pada dasarnya dua kali lipat, dan sementara dinding tetap sama.
ini berlanjut hingga 8 utas, yang cocok dengan jumlah hyperthreads saya di komputer saya.
Setelah 8, dinding mulai meningkat juga, karena kami tidak memiliki CPU tambahan untuk membuat lebih banyak pekerjaan dalam jumlah waktu tertentu!
Rasio dataran tinggi pada titik ini.
Perhatikan bahwa grafik ini hanya sangat jelas dan sederhana karena pekerjaan itu murni terikat CPU: jika itu terikat memori, maka kita akan mendapatkan penurunan kinerja jauh lebih awal dengan lebih sedikit core karena akses memori akan menjadi hambatan seperti yang ditunjukkan pada Apa arti dari istilah "CPU terikat" dan "I / O terikat"?
Sys kerja berat dengan
sendfile
Beban kerja sys terberat yang dapat saya lakukan adalah menggunakan
sendfile
, yang melakukan operasi penyalinan file pada ruang kernel: Menyalin file dengan cara yang waras, aman dan efisienJadi saya membayangkan bahwa in-kernel ini
memcpy
akan menjadi operasi intensif CPU.Pertama saya menginisialisasi file acak 10GiB besar dengan:
Kemudian jalankan kodenya:
GitHub hulu .
yang pada dasarnya memberi sebagian besar waktu sistem seperti yang diharapkan:
Saya juga ingin tahu apakah
time
akan membedakan antara syscall dari proses yang berbeda, jadi saya mencoba:Dan hasilnya adalah:
Waktu sistem hampir sama untuk keduanya seperti untuk satu proses tunggal, tetapi waktu dinding lebih besar karena proses bersaing kemungkinan untuk akses baca disk.
Jadi tampaknya itu memang menjelaskan proses yang memulai kerja kernel yang diberikan.
Kode sumber bash
Ketika Anda melakukannya hanya
time <cmd>
di Ubuntu, ia menggunakan kata kunci Bash seperti yang dapat dilihat dari:yang keluaran:
Jadi kami mengambil sumber dalam kode sumber Bash 4.19 untuk string keluaran:
yang mengarahkan kita ke fungsi execute_cmd.c
time_command
, yang menggunakan:gettimeofday()
dangetrusage()
jika keduanya tersediatimes()
jika tidaksemuanya adalah panggilan sistem Linux dan fungsi POSIX .
Kode sumber GNU Coreutils
Jika kita menyebutnya sebagai:
kemudian menggunakan implementasi GNU Coreutils.
Yang ini sedikit lebih rumit, tetapi sumber yang relevan tampaknya berada di resuse.c dan memang:
wait3
panggilan BSD non-POSIX jika tersediatimes
dangettimeofday
sebaliknyasumber
Real menunjukkan total waktu penyelesaian untuk suatu proses; sementara Pengguna menunjukkan waktu eksekusi untuk instruksi yang ditentukan pengguna dan Sys adalah waktu untuk mengeksekusi panggilan sistem!
Waktu nyata juga mencakup waktu tunggu (waktu tunggu untuk I / O dll.)
sumber