Masalahnya adalah ada beberapa fungsi waktu berbeda yang tersedia di C dan C++, dan beberapa di antaranya memiliki perilaku yang berbeda di antara implementasi. Ada juga banyak jawaban setengah-setengah yang beredar. Menyusun daftar fungsi jam beserta propertinya akan menjawab pertanyaan dengan benar. Sebagai permulaan, mari kita tanyakan properti apa yang relevan yang kita cari. Melihat postingan Anda, saya sarankan:
- Waktu apa yang diukur dengan jam? (nyata, pengguna, sistem, atau, semoga bukan, jam dinding?)
- Berapa presisi jamnya? (s, ms, µs, atau lebih cepat?)
- Setelah berapa lama jam berputar? Atau apakah ada mekanisme untuk menghindari hal ini?
- Apakah jam monoton, atau akan berubah dengan perubahan waktu sistem (melalui NTP, zona waktu, waktu musim panas, oleh pengguna, dll.)?
- Bagaimana perbedaan di atas di antara implementasi?
- Apakah fungsi tertentu sudah usang, tidak standar, dll.?
Sebelum memulai daftar, saya ingin menunjukkan bahwa waktu jam dinding jarang menjadi waktu yang tepat untuk digunakan, karena waktu berubah dengan perubahan zona waktu, perubahan waktu musim panas, atau jika jam dinding disinkronkan oleh NTP. Semua hal ini tidak baik jika Anda menggunakan waktu untuk menjadwalkan acara atau untuk mengukur kinerja. Ini hanya bagus untuk apa namanya, jam di dinding (atau desktop).
Inilah yang saya temukan sejauh ini untuk jam di Linux dan OS X:
time()
mengembalikan waktu jam dinding dari OS, dengan presisi dalam hitungan detik.clock()
tampaknya mengembalikan jumlah pengguna dan waktu sistem. Ini hadir di C89 dan yang lebih baru. Pada suatu waktu ini seharusnya menjadi waktu CPU dalam siklus, tetapi standar modern seperti POSIX membutuhkan CLOCKS_PER_SEC menjadi 1000000, memberikan kemungkinan presisi maksimum 1 µs. Presisi pada sistem saya memang 1 µs. Jam ini berputar setelah mencapai puncak (ini biasanya terjadi setelah ~ 2 ^ 32 kutu, yang tidak terlalu lama untuk jam 1 MHz).man clock
mengatakan bahwa sejak glibc 2.18 diimplementasikan denganclock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
di Linux.clock_gettime(CLOCK_MONOTONIC, ...)
memberikan resolusi nanodetik, bersifat monoton. Saya yakin 'detik' dan 'nanodetik' disimpan secara terpisah, masing-masing dalam penghitung 32-bit. Dengan demikian, penutupan apa pun akan terjadi setelah puluhan tahun waktu aktif. Ini terlihat seperti jam yang sangat bagus, tetapi sayangnya belum tersedia di OS X. POSIX 7 menjelaskanCLOCK_MONOTONIC
sebagai ekstensi opsional.getrusage()
ternyata menjadi pilihan terbaik untuk situasi saya. Ini melaporkan waktu pengguna dan sistem secara terpisah dan tidak membungkus. Presisi pada sistem saya adalah 1 µs, tetapi saya juga mengujinya pada sistem Linux (Red Hat 4.1.2-48 dengan GCC 4.1.2) dan presisinya hanya 1 ms.gettimeofday()
mengembalikan waktu jam dinding dengan presisi (nominal) µs. Di sistem saya, jam ini tampaknya memiliki presisi µs, tetapi ini tidak dijamin, karena "resolusi jam sistem bergantung pada perangkat keras". POSIX.1-2008 mengatakan itu. "Aplikasi harus menggunakanclock_gettime()
fungsi alih-alihgettimeofday()
yang usang function", jadi Anda harus menjauhinya. Linux x86 dan mengimplementasikannya sebagai panggilan sistem.mach_absolute_time()
adalah opsi untuk pengaturan waktu resolusi sangat tinggi (ns) di OS X. Di sistem saya, ini memang memberikan resolusi ns. Pada prinsipnya jam ini berputar, namun menyimpan ns menggunakan bilangan bulat 64-bit unsigned, jadi dalam praktiknya pembungkusan seharusnya tidak menjadi masalah. Portabilitas dipertanyakan.- Saya menulis fungsi hibrid berdasarkan cuplikan ini yang menggunakan clock_gettime saat dikompilasi di Linux, atau pengatur waktu Mach saat dikompilasi di OS X, untuk mendapatkan presisi ns di Linux dan OS X.
Semua hal di atas ada di Linux dan OS X kecuali ditentukan lain. "Sistem saya" di atas adalah Apple yang menjalankan OS X 10.8.3 dengan GCC 4.7.2 dari MacPorts.
Terakhir, berikut adalah daftar referensi yang menurut saya berguna selain tautan di atas:
- http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
- Bagaimana cara mengukur waktu eksekusi SEBENARNYA dari program C di Linux?
- http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
- http://www.unix.com/hp-ux/38937-getrusage.html
Perbarui :untuk OS X, clock_gettime
telah diterapkan pada 10.12 (Sierra). Selain itu, platform berbasis POSIX dan BSD (seperti OS X) berbagi rusage.ru_utime
bidang struct.
C11 timespec_get
Contoh penggunaan di:https://stackoverflow.com/a/36095407/895245
Presisi maksimum yang mungkin dikembalikan adalah nanodetik, tetapi presisi sebenarnya ditentukan oleh implementasi dan bisa lebih kecil.
Ini mengembalikan waktu dinding, bukan penggunaan CPU.
glibc 2.21 mengimplementasikannya di bawah sysdeps/posix/timespec_get.c
dan diteruskan langsung ke:
clock_gettime (CLOCK_REALTIME, ts) < 0)
clock_gettime
dan CLOCK_REALTIME
adalah POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html, dan man clock_gettime
mengatakan bahwa tindakan ini mungkin memiliki diskontinuitas jika Anda mengubah beberapa pengaturan waktu sistem saat program Anda berjalan.
krono C++11
Karena kita sedang melakukannya, mari kita bahas juga:http://en.cppreference.com/w/cpp/chrono
GCC 5.3.0 (C++ stdlib ada di dalam sumber GCC):
high_resolution_clock
adalah alias untuksystem_clock
system_clock
meneruskan ke yang pertama dari berikut ini yang tersedia:clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
meneruskan ke yang pertama dari berikut ini yang tersedia:clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
Ditanyakan di:Perbedaan antara std::system_clock dan std::steady_clock?
CLOCK_REALTIME
vs CLOCK_MONOTONIC
:Perbedaan antara CLOCK_REALTIME dan CLOCK_MONOTONIC?