Saya ingin mencari tahu berapa banyak waktu yang dibutuhkan fungsi tertentu dalam program C ++ saya untuk dijalankan di Linux . Setelah itu, saya ingin membuat perbandingan kecepatan. Saya melihat beberapa fungsi waktu tetapi akhirnya dengan dorongan ini. Chrono:
process_user_cpu_clock, captures user-CPU time spent by the current process
Sekarang, saya tidak jelas jika saya menggunakan fungsi di atas, apakah saya akan mendapatkan satu-satunya waktu yang dihabiskan CPU untuk fungsi itu?
Kedua, saya tidak dapat menemukan contoh penggunaan fungsi di atas. Adakah yang bisa membantu saya bagaimana menggunakan fungsi di atas?
PS: Saat ini, saya menggunakan std::chrono::system_clock::now()
untuk mendapatkan waktu dalam hitungan detik tetapi ini memberi saya hasil yang berbeda karena beban CPU yang berbeda setiap waktu.
c++
optimization
profiling
Xara
sumber
sumber
clock_gettime
.. gcc mendefinisikan jam lain sebagai:typedef system_clock steady_clock; typedef system_clock high_resolution_clock;
pada Windows, gunakanQueryPerformanceCounter
.Jawaban:
Ini adalah metode yang sangat mudah digunakan dalam C ++ 11. Anda harus menggunakan
std::chrono::high_resolution_clock
dari<chrono>
header.Gunakan seperti ini:
Ini akan mengukur durasi fungsi.
CATATAN: Anda tidak akan selalu mendapatkan penghitungan waktu yang sama untuk suatu fungsi. Ini karena CPU mesin Anda bisa kurang atau lebih digunakan oleh proses lain yang berjalan di komputer Anda, sama seperti pikiran Anda dapat lebih atau kurang terkonsentrasi ketika Anda menyelesaikan latihan matematika. Dalam pikiran manusia, kita dapat mengingat solusi dari masalah matematika, tetapi untuk komputer proses yang sama akan selalu menjadi sesuatu yang baru; dengan demikian, seperti yang saya katakan, Anda tidak akan selalu mendapatkan hasil yang sama!
sumber
high_resolution_clock
akan memberi Anda waktu fisik dan waktu nyata yang diperlukan fungsi Anda untuk dijalankan. Jadi, dalam menjalankan pertama Anda, CPU Anda digunakan kurang dari pada menjalankan berikutnya. Maksud "bekas" yang saya maksud adalah pekerjaan aplikasi lain menggunakan CPU.steady_clock
? Mungkinkahhigh_resolution_clock
jam non-monoton?Berikut adalah fungsi yang akan mengukur waktu eksekusi dari setiap fungsi yang dilewatkan sebagai argumen:
Contoh penggunaan:
Keluaran:
sumber
high_resolution_clock
mungkin aliassystem_clock
(jam dinding),steady_clock
atau jam independen ketiga. Lihat detailnya di sini . Untuk jam cpu,std::clock
dapat digunakanwindows.h
dalam proyek c ++ non-sepele. Mengenaiassert
pertama-tama: "quod licet iovi non licet bovi";). Kedua, tidak semua keputusan di perpustakaan standar (kadang-kadang sejak dekade kembali) sebenarnya dianggap ide yang baik oleh standar modern. Ada alasannya, mengapa perancang modul c ++ berusaha sangat keras untuk tidak mengekspor makro secara default.program sederhana untuk menemukan waktu pelaksanaan fungsi yang diambil.
sumber
Dalam buku Scott Meyers saya menemukan contoh ekspresi lambda generik universal yang dapat digunakan untuk mengukur waktu eksekusi fungsi. (C ++ 14)
Masalahnya adalah Anda hanya mengukur satu eksekusi sehingga hasilnya bisa sangat berbeda. Untuk mendapatkan hasil yang andal, Anda harus mengukur sejumlah besar eksekusi. Menurut Andrei Alexandrescu kuliah di code :: dive 2015 conference - Writing Fast Code I:
Waktu yang diukur: tm = t + tq + tn + hingga
dimana:
tm - waktu diukur (diamati)
t - waktu aktual bunga
tq - waktu ditambahkan oleh noise kuantisasi
Waktu ditambahkan oleh berbagai sumber kebisingan
ke - waktu overhead (fungsi pengukuran, perulangan, panggilan)
Menurut apa yang dia katakan nanti dalam perkuliahan, Anda harus mengambil minimal eksekusi dalam jumlah besar ini sebagai hasilnya. Saya mendorong Anda untuk melihat ceramah di mana dia menjelaskan mengapa.
Juga ada perpustakaan yang sangat bagus dari google - https://github.com/google/benchmark . Perpustakaan ini sangat mudah digunakan dan kuat. Anda dapat checkout beberapa ceramah Chandler Carruth di youtube di mana dia menggunakan perpustakaan ini dalam praktek. Misalnya CppCon 2017: Chandler Carruth “Going Nowhere Faster”;
Contoh penggunaan:
EDIT: Tentu saja Anda selalu perlu mengingat bahwa kompiler Anda dapat mengoptimalkan sesuatu atau tidak. Alat seperti perf dapat berguna dalam kasus seperti itu.
sumber
Cara mudah untuk C ++ yang lebih lama, atau C:
Ketepatan waktu dalam hitungan detik adalah
1.0/CLOCKS_PER_SEC
sumber
Misalnya, untuk menemukan semua bilangan prima antara 1 dan 100 juta, dibutuhkan sekitar 1 menit dan 40 detik. Jadi waktu eksekusi dapat dicetak sebagai:
Kode di sini:
sumber
Berikut adalah templat kelas hanya header yang sangat baik untuk mengukur waktu yang berlalu dari suatu fungsi atau blok kode apa pun:
Berikut beberapa kegunaannya:
Karena kelas adalah templat, kami dapat menentukan dengan mudah bagaimana kami ingin waktu kami diukur & ditampilkan. Ini adalah templat kelas utilitas yang sangat berguna untuk melakukan penandaan bangku dan sangat mudah digunakan.
sumber
stop()
fungsi anggota tidak diperlukan karena destruktor menghentikan timer untuk Anda.test code
memulai timer. Kemudian setelah Anda,test code
Anda secara eksplisit menggunakan objek timer dan memanggil metode berhenti. Anda harus menjalankannya secara manual ketika Anda inginstop
timer. Kelas tidak mengambil parameter apa pun. Juga jika Anda menggunakan kelas ini seperti yang saya tunjukkan, Anda akan melihat bahwa ada sedikit waktu berlalu antara panggilan keobj.stop
dandestructor
.<chrono>
?Saya sarankan menggunakan
steady_clock
yang dijamin monoton, tidak sepertihigh_resolution_clock
.Keluaran:
sumber
Anda dapat memiliki kelas sederhana yang dapat digunakan untuk pengukuran semacam ini.
Satu-satunya hal yang perlu dilakukan adalah membuat objek di fungsi Anda di awal fungsi itu
dan hanya itu. Kelas dapat dimodifikasi agar sesuai dengan kebutuhan Anda.
sumber
Karena tidak ada jawaban yang diberikan yang sangat akurat atau memberikan hasil yang dapat direproduksi, saya memutuskan untuk menambahkan tautan ke kode saya yang memiliki ketepatan sub-nanosecond dan statistik ilmiah.
Perhatikan bahwa ini hanya akan berfungsi untuk mengukur kode yang membutuhkan waktu (sangat) singkat untuk dijalankan (alias, beberapa siklus clock hingga beberapa ribu): jika mereka berjalan sangat lama sehingga mereka kemungkinan akan terganggu oleh beberapa -heh- interupsi , maka jelas tidak mungkin untuk memberikan hasil yang dapat direproduksi dan akurat; konsekuensi yang adalah bahwa pengukuran tidak pernah selesai: yaitu, ia terus mengukur sampai secara statistik 99,9% yakin itu memiliki jawaban yang benar yang tidak pernah terjadi pada mesin yang memiliki proses lain yang berjalan ketika kode terlalu lama.
https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40
sumber
Jika Anda ingin menghemat waktu dan baris kode, Anda dapat mengukur waktu pelaksanaan fungsi makro satu baris:
a) Menerapkan kelas pengukur waktu seperti yang telah disarankan di atas (berikut ini adalah implementasi saya untuk android):
b) Tambahkan makro nyaman yang menggunakan nama fungsi saat ini sebagai TAG (menggunakan makro di sini adalah penting, yang lain
__FUNCTION__
akan mengevaluasi untukMeasureExecutionTime
bukannya fungsi yang Anda ingin ukurc) Tulis makro Anda di awal fungsi yang ingin Anda ukur. Contoh:
Yang akan menghasilkan int berikut output:
Perhatikan bahwa ini (seperti semua solusi yang disarankan lainnya) akan mengukur waktu antara kapan fungsi Anda dipanggil dan ketika itu kembali, tidak perlu waktu CPU Anda menjalankan fungsi. Namun, jika Anda tidak memberikan perubahan pada penjadwal untuk menangguhkan kode berjalan Anda dengan memanggil sleep () atau yang serupa, tidak ada perbedaan di antara keduanya.
sumber