Saya hanya menggunakan ~ 1 miliar sebagai hitungan untuk z-index
dalam CSS, dan sedang memikirkan perbandingan yang harus dilakukan. Apakah ada perbedaan kinerja pada tingkat ALU dalam perbandingan antara jumlah yang sangat besar vs yang sangat kecil?
Misalnya, apakah salah satu dari dua cuplikan ini lebih mahal daripada yang lain?
snippet 1
for (int i = 0; i < 10000000; i++){
if (i < 10000000000000) {
//do nothing
}
}
snippet 2
for (int i = 0; i < 10000000; i++){
if (i < 1000) {
//do nothing
}
}
performance
cpu
Viziionary
sumber
sumber
CMP
instruksi mesin individual akan lebih lambat jikai
lebih besar.Jawaban:
Setiap prosesor yang saya kerjakan melakukan perbandingan dengan mengurangi salah satu operan dari yang lain, membuang hasilnya dan meninggalkan bendera prosesor (nol, negatif, dll.) Sendirian. Karena pengurangan dilakukan sebagai operasi tunggal, isi operan tidak penting.
Cara terbaik untuk menjawab pertanyaan dengan pasti adalah mengkompilasi kode Anda ke dalam perakitan dan berkonsultasi dengan dokumentasi prosesor target untuk instruksi yang dihasilkan. Untuk CPU Intel saat ini, itu akan menjadi Panduan Pengembang Perangkat Lunak Arsitektur Intel 64 dan IA-32 .
Deskripsi
CMP
instruksi ("bandingkan") ada di volume 2A, halaman 3-126, atau halaman 618 dari PDF, dan menjelaskan operasinya sebagai:Ini berarti operan kedua diperpanjang jika perlu, dikurangi dari operan pertama dan hasilnya ditempatkan di area sementara dalam prosesor. Kemudian bendera status diatur dengan cara yang sama seperti untuk
SUB
instruksi ("kurangi") (halaman 1492 dari PDF).Tidak ada disebutkan dalam
CMP
atauSUB
dokumentasi bahwa nilai operan memiliki kaitan dengan latensi, sehingga nilai apa pun yang Anda gunakan aman.sumber
Ini sangat tidak mungkin, kecuali beralih dari angka kecil ke angka besar mengubah tipe numerik Anda, katakanlah dari a
int
ke along
. Meski begitu, perbedaannya mungkin tidak signifikan. Anda lebih mungkin melihat perbedaan jika bahasa pemrograman Anda secara diam-diam beralih ke aritmatika presisi sewenang - wenang di bawah penutup.Meskipun demikian, kompiler khusus Anda mungkin melakukan beberapa optimasi pintar yang tidak Anda sadari. Cara Anda mengetahuinya adalah dengan mengukur. Jalankan profiler pada kode Anda; lihat perbandingan mana yang paling lama. Atau cukup memulai dan menghentikan timer.
sumber
Banyak prosesor memiliki instruksi "kecil" yang dapat melakukan operasi aritmatika, termasuk perbandingan, pada operan tertentu yang segera ditentukan. Operand selain nilai-nilai khusus tersebut harus menggunakan format instruksi yang lebih besar atau, dalam beberapa kasus, harus menggunakan instruksi "load value from memory". Dalam set instruksi ARM Cortex-M3, misalnya, setidaknya ada lima cara nilai dapat dibandingkan dengan konstanta:
Bentuk pertama adalah yang terkecil; bentuk kedua dan ketiga mungkin atau tidak mungkin dijalankan dengan cepat, tergantung pada kecepatan memori dari mana kode diambil. Bentuk keempat bentuk hampir pasti akan lebih lambat dari tiga yang pertama, dan bentuk kelima bahkan lebih lambat, tetapi yang terakhir dapat digunakan dengan nilai 32-bit.
Pada prosesor x86 yang lebih lama, instruksi membandingkan formulir pendek akan mengeksekusi lebih cepat daripada yang panjang, tetapi banyak prosesor yang lebih baru akan mengonversi bentuk panjang dan pendek ke representasi yang sama ketika mereka pertama kali diambil, dan menyimpan representasi seragam dalam cache. Jadi, sementara pengontrol yang tertanam (seperti yang ditemukan pada banyak platform seluler) akan memiliki perbedaan kecepatan, banyak komputer berbasis x86 tidak akan melakukannya.
Perhatikan juga bahwa dalam banyak kasus di mana konstanta banyak digunakan dalam satu loop, kompiler hanya perlu memuat konstanta ke register sekali - sebelum loop dimulai - rendering perbedaan waktu diperdebatkan. Di sisi lain, ada beberapa situasi, bahkan dalam loop kecil, di mana itu tidak akan selalu terjadi; jika loop kecil tetapi banyak dieksekusi, kadang-kadang mungkin ada kinerja besar antara perbandingan yang melibatkan nilai langsung pendek dan yang melibatkan yang lebih lama.
sumber
Jawaban singkat untuk pertanyaan ini adalah, tidak , tidak ada perbedaan waktu untuk membandingkan dua angka berdasarkan besarnya angka-angka itu dengan asumsi mereka disimpan dalam tipe data yang sama (mis. Baik int 32-bit atau keduanya panjang 64-bit.)
Selain itu, hingga ukuran kata ALU , sangat tidak mungkin bahwa membandingkan dua bilangan bulat satu sama lain akan memakan waktu lebih dari 1 siklus clock, karena ini adalah operasi sepele yang setara dengan pengurangan. Saya pikir setiap arsitektur yang pernah saya tangani memiliki perbandingan integer siklus tunggal.
Satu-satunya kasus yang dapat saya pikirkan yang saya temui di mana perbandingan dua angka bukanlah operasi satu siklus adalah sebagai berikut:
sumber
@ RobertHarvey jawabannya bagus; pertimbangkan jawaban ini sebagai pelengkap untuknya.
Anda juga harus mempertimbangkan Prediksi Cabang :
Pada dasarnya, dalam contoh Anda, jika
if
pernyataan di dalam loop selalu mengembalikan jawaban yang sama, maka sistem dapat mengoptimalkannya dengan menebak dengan benar ke mana ia akan bercabang. Dalam contoh Anda, karenaif
pernyataan dalam kasus pertama selalu mengembalikan hasil yang sama, itu akan berjalan sedikit lebih cepat daripada kasus kedua.Pertanyaan Stack Overflow luar biasa pada subjek
sumber
Itu tergantung pada implementasinya, tetapi itu akan sangat, sangat tidak mungkin .
Saya akui bahwa saya belum membaca detail implementasi dari berbagai mesin browser, dan CSS tidak menentukan tipe penyimpanan tertentu untuk angka. Tapi saya percaya bahwa aman untuk berasumsi bahwa semua browser utama menggunakan angka floating-point 64-bit double-precision ("doubles", untuk meminjam istilah dari C / C ++) untuk menangani sebagian besar kebutuhan numerik mereka di CSS , karena inilah yang digunakan JavaScript untuk angka, dan dengan menggunakan tipe yang sama membuat integrasi menjadi lebih mudah.
Dari sudut pandang komputer, semua ganda membawa jumlah data yang sama: 64 bit, apakah nilainya 1 atau -3,14 atau 1000000 atau 1e100 . Jumlah waktu yang diperlukan untuk melakukan operasi pada angka-angka ini tidak tergantung pada nilai aktual dari angka-angka itu, karena selalu bekerja pada jumlah data yang sama. Ada tradeoff dalam melakukan hal-hal seperti ini, di mana ganda tidak dapat secara akurat mewakili semua angka (atau bahkan semua angka dalam kisaran mereka), tetapi mereka bisa cukup dekat untuk sebagian besar masalah, dan hal-hal yang dilakukan CSS tidak secara numerik -menuntut cukup untuk membutuhkan lebih banyak presisi dari itu. Kombinasikan ini dengan manfaat kompatibilitas langsung dengan JavaScript, dan Anda memiliki kasus yang cukup kuat untuk ganda.
Bukan tidak mungkin seseorang dapat mengimplementasikan CSS menggunakan pengodean panjang variabel untuk angka. Jika seseorang menggunakan pengkodean panjang variabel, maka membandingkan dengan angka kecil akan lebih murah daripada membandingkan dengan angka besar, karena angka besar memiliki lebih banyak data untuk dikelompokkan . Jenis-jenis pengkodean ini bisa lebih tepat daripada biner, tetapi mereka juga jauh lebih lambat, dan untuk CSS khususnya, perolehan presisi mungkin tidak cukup untuk menjadi layak untuk hit kinerja. Saya akan sangat terkejut mengetahui bahwa browser apa pun melakukan hal seperti ini.
Sekarang, secara teori, ada satu pengecualian yang mungkin untuk semua yang saya katakan di atas: membandingkan dengan nol sering lebih cepat daripada membandingkan dengan angka lainnya . Ini bukan karena nol pendek (jika itu alasannya, maka saya harusnya sama cepatnya, tetapi bukan itu). Itu karena nol memungkinkan Anda menipu. Ini adalah satu-satunya angka di mana semua bit mati, jadi jika Anda tahu bahwa salah satu nilainya adalah nol, Anda bahkan tidak perlu melihat nilai lainnya sebagai angka: jika ada bit yang dihidupkan maka itu tidak sama dengan nol, dan kemudian Anda hanya perlu melihat satu bit untuk melihat apakah itu lebih besar atau kurang dari nol.
sumber
Jika kode ini ditafsirkan setiap kali dijalankan, akan ada perbedaan karena lebih lama untuk tokenise dan ditafsirkan
10000000000000
dibandingkan1000
. Namun, ini adalah optimasi pertama yang jelas dari penerjemah dalam kasus ini: tokenise sekali dan menafsirkan token.sumber