Berikut adalah beberapa penemuan terbaru meskipun sempit dari tambang dengan GCC 4.7.2 dan Dentang 3.2 untuk C ++.
UPDATE: GCC 4.8.1 v clang 3.3 perbandingan ditambahkan di bawah ini.
UPDATE: GCC 4.8.2 v clang 3.4 ditambahkan untuk itu.
Saya memelihara alat OSS yang dibangun untuk Linux dengan GCC dan Dentang, dan dengan kompiler Microsoft untuk Windows. Alat, coan, adalah preprocessor dan penganalisa file sumber C / C ++ dan kodelines seperti: jurusan profil komputasional pada penguraian dan penanganan file rekursi-keturunan. Cabang pengembangan (yang terkait dengan hasil ini) terdiri saat ini sekitar 11K LOC dalam sekitar 90 file. Ini dikodekan, sekarang, dalam C + + yang kaya akan polimorfisme dan templat dan tetapi masih terperosok dalam banyak tambalan oleh masa lalunya yang tidak terlalu jauh dalam peretasan bersama C. Semantik yang dipindahkan tidak dieksploitasi secara tegas. Ini single-threaded. Saya tidak mencurahkan upaya serius untuk mengoptimalkannya, sementara "arsitektur" sebagian besar tetap ToDo.
Saya menggunakan Clang sebelum 3.2 hanya sebagai kompiler eksperimental karena, terlepas dari kecepatan kompilasi yang superior dan diagnostik, dukungan standar C ++ 11 yang tertinggal versi GCC kontemporer dalam hal yang dilakukan oleh coan. Dengan 3.2, celah ini telah ditutup.
Linux harness test saya untuk proses pengembangan coan saat ini kira-kira 70K sumber file dalam campuran kasus parser satu-file, tes stres mengkonsumsi 1000-an file dan tes skenario mengkonsumsi <1K file. Selain melaporkan hasil pengujian, harness terakumulasi dan menampilkan total file yang dikonsumsi dan run time yang dikonsumsi dalam coan (itu hanya melewati setiap baris perintah coan ke time
perintah Linux dan menangkap dan menambahkan angka yang dilaporkan). Pengaturan waktu tersanjung oleh fakta bahwa sejumlah tes yang mengambil 0 waktu yang dapat diukur semuanya akan bertambah hingga 0, tetapi kontribusi tes tersebut dapat diabaikan. Statistik waktu ditampilkan di akhir make check
seperti ini:
coan_test_timer: info: coan processed 70844 input_files.
coan_test_timer: info: run time in coan: 16.4 secs.
coan_test_timer: info: Average processing time per input file: 0.000231 secs.
Saya membandingkan kinerja uji harness antara GCC 4.7.2 dan Dentang 3.2, semua hal sama kecuali kompiler. Pada Clang 3.2, saya tidak lagi memerlukan diferensiasi preprocessor antara traktat kode yang akan dikompilasi oleh GCC dan Clang alternatif. Saya membangun perpustakaan C ++ yang sama (GCC) di setiap kasus dan menjalankan semua perbandingan secara berurutan dalam sesi terminal yang sama.
Level optimalisasi standar untuk build rilis saya adalah -O2. Saya juga berhasil menguji build di -O3. Saya menguji setiap konfigurasi 3 kali back-to-back dan rata-rata 3 hasil, dengan hasil sebagai berikut. Angka dalam sel data adalah jumlah rata-rata mikrodetik yang dikonsumsi oleh coan yang dapat dieksekusi untuk memproses masing-masing file input ~ 70K (baca, parsing dan tulis output serta diagnostik).
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 231 | 237 |0.97 |
----------|-----|-----|-----|
Clang-3.2 | 234 | 186 |1.25 |
----------|-----|-----|------
GCC/Clang |0.99 | 1.27|
Setiap aplikasi tertentu sangat mungkin memiliki sifat-sifat yang bermain secara tidak adil terhadap kekuatan atau kelemahan kompiler. Benchmarking yang ketat menggunakan beragam aplikasi. Dengan mengingat hal itu, fitur penting dari data ini adalah:
- Optimasi -O3 sedikit merugikan GCC
- -O3 optimasi penting bermanfaat bagi Dentang
- Pada optimasi -O2, GCC lebih cepat daripada Dentang hanya dengan kumis
- Pada optimasi -O3, Dentang penting lebih cepat daripada GCC.
Perbandingan lebih lanjut yang menarik dari kedua penyusun muncul secara tidak sengaja setelah penemuan-penemuan itu. Coan secara bebas menggunakan pointer pintar dan satu seperti itu banyak dilakukan dalam penanganan file. Tipe smart-pointer khusus ini telah diketik dalam rilis sebelumnya demi diferensiasi kompiler, menjadi std::unique_ptr<X>
jika kompiler yang dikonfigurasi memiliki dukungan yang cukup matang untuk penggunaannya seperti itu, dan sebaliknya std::shared_ptr<X>
. Bias untuk std::unique_ptr
menjadi bodoh, karena pointer ini sebenarnya ditransfer sekitar, tetapi std::unique_ptr
tampak seperti opsi yang lebih bugar untuk mengganti
std::auto_ptr
pada titik ketika varian C ++ 11 baru bagi saya.
Dalam proses pembuatan eksperimental untuk mengukur kebutuhan Clang 3.2 yang terus-menerus untuk diferensiasi ini dan yang serupa, saya secara tidak sengaja membangun
std::shared_ptr<X>
ketika saya bermaksud membangun std::unique_ptr<X>
, dan terkejut melihat bahwa hasil yang dapat dieksekusi, dengan standar -O2 optimasi, adalah yang tercepat telah melihat, terkadang mencapai 184 msecs. per file input. Dengan satu perubahan pada kode sumber, hasil yang sesuai adalah ini;
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 234 | 234 |1.00 |
----------|-----|-----|-----|
Clang-3.2 | 188 | 187 |1.00 |
----------|-----|-----|------
GCC/Clang |1.24 |1.25 |
Poin-poin yang perlu diperhatikan di sini adalah:
- Kompiler sekarang tidak mendapat manfaat sama sekali dari -O3 optimasi.
- Dentang mengalahkan GCC sama pentingnya pada setiap tingkat optimasi.
- Kinerja GCC hanya sedikit terpengaruh oleh perubahan tipe smart-pointer.
- Kinerja-O2 dentang penting dipengaruhi oleh perubahan tipe smart-pointer.
Sebelum dan setelah perubahan tipe smart-pointer, Clang dapat membangun eksekusi yang jauh lebih cepat pada optimasi -O3, dan itu dapat membangun eksekusi yang sama cepatnya pada -O2 dan -O3 ketika pointer-type itu yang terbaik - std::shared_ptr<X>
- untuk pekerjaan.
Sebuah pertanyaan yang jelas bahwa saya tidak kompeten untuk mengomentari adalah mengapa
Dentang harus dapat menemukan 25% -O2 percepatan dalam aplikasi saya ketika tipe smart-pointer yang banyak digunakan berubah dari unik ke berbagi, sedangkan GCC acuh tak acuh untuk perubahan yang sama. Saya juga tidak tahu apakah saya harus menghibur atau mencemooh penemuan bahwa optimasi-O2 Clang memiliki sensitivitas yang sangat besar terhadap kebijaksanaan pilihan smart-pointer saya.
PEMBARUAN: GCC 4.8.1 v dentang 3.3
Hasil yang sesuai sekarang adalah:
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.1 | 442 | 443 |1.00 |
----------|-----|-----|-----|
Clang-3.3 | 374 | 370 |1.01 |
----------|-----|-----|------
GCC/Clang |1.18 |1.20 |
Fakta bahwa keempat executable sekarang mengambil waktu rata-rata yang jauh lebih besar daripada sebelumnya untuk memproses 1 file tidak mencerminkan kinerja kompiler terbaru. Hal ini disebabkan oleh fakta bahwa cabang pengembangan selanjutnya dari aplikasi pengujian telah mengambil banyak kecanggihan parsing sementara itu dan membayarnya dengan cepat. Hanya rasio yang signifikan.
Poin-poin penting sekarang bukan novel baru:
- GCC tidak peduli dengan optimasi -O3
- Dentang manfaat sangat sedikit dari optimasi -O3
- Dentang mengalahkan GCC dengan margin yang sama pentingnya pada setiap tingkat optimasi.
Membandingkan hasil ini dengan yang untuk GCC 4.7.2 dan clang 3.2, menonjol bahwa GCC telah mencabut kembali sekitar seperempat dari lead clang di setiap tingkat optimasi. Tetapi karena aplikasi pengujian telah banyak dikembangkan untuk sementara waktu, seseorang tidak dapat dengan yakin menghubungkan ini dengan ketertinggalan dalam pembuatan kode GCC. (Kali ini, saya telah mencatat snapshot aplikasi dari mana timing diperoleh dan dapat menggunakannya lagi.)
PEMBARUAN: GCC 4.8.2 v dentang 3.4
Saya menyelesaikan pembaruan untuk GCC 4.8.1 v Dentang 3.3 mengatakan bahwa saya akan tetap menggunakan coan snaphot yang sama untuk pembaruan lebih lanjut. Tetapi saya memutuskan untuk menguji snapshot itu (rev. 301) dan snapshot pengembangan terbaru yang saya miliki melewati test suite-nya (rev. 619). Ini memberikan hasil sedikit bujur, dan saya punya motif lain:
Posting asli saya mencatat bahwa saya tidak mencurahkan upaya untuk mengoptimalkan kecepatan untuk coan. Ini masih terjadi pada rev. 301. Namun, setelah saya membuat aparatus timing ke dalam harness test coan, setiap kali saya menjalankan test suite dampak kinerja dari perubahan terbaru menatap wajah saya. Saya melihat bahwa itu seringkali luar biasa besar dan trennya lebih negatif daripada yang saya rasakan layaknya keuntungan dalam fungsionalitas.
Oleh rev. 308 waktu pemrosesan rata-rata per file input dalam test suite telah lebih dari dua kali lipat sejak posting pertama di sini. Pada saat itu saya mengubah kebijakan 10 tahun saya yang tidak mengganggu kinerja. Dalam serangkaian revisi intensif hingga 619, kinerja selalu menjadi pertimbangan dan sebagian besar dari mereka murni untuk menulis ulang pembawa beban utama pada saluran yang secara fundamental lebih cepat (walaupun tanpa menggunakan fitur kompiler non-standar untuk melakukannya). Akan menarik untuk melihat reaksi masing-masing kompiler terhadap putaran U ini,
Ini adalah matriks timing yang sekarang sudah umum untuk versi build dua kompiler terbaru dari rev.301:
coan - rev.301 hasil
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 428 | 428 |1.00 |
----------|-----|-----|-----|
Clang-3.4 | 390 | 365 |1.07 |
----------|-----|-----|------
GCC/Clang | 1.1 | 1.17|
Kisah di sini hanya sedikit berubah dari GCC-4.8.1 dan Clang-3.3. Pertunjukan GCC sedikit lebih baik. Dentang sedikit lebih buruk. Kebisingan bisa menjelaskan ini. Dentang masih keluar di depan -O2
dan -O3
margin yang tidak penting di sebagian besar aplikasi tetapi akan penting bagi beberapa.
Dan di sini adalah matriks untuk rev. 619.
coan - rev.619 hasil
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 210 | 208 |1.01 |
----------|-----|-----|-----|
Clang-3.4 | 252 | 250 |1.01 |
----------|-----|-----|------
GCC/Clang |0.83 | 0.83|
Mengambil angka 301 dan 619 berdampingan, beberapa poin berbicara.
Saya bertujuan untuk menulis kode lebih cepat, dan kedua kompiler dengan tegas membenarkan upaya saya. Tapi:
GCC membayar upaya itu jauh lebih murah daripada Dentang. Pada -O2
optimasi, Clang 619 build adalah 46% lebih cepat daripada build 301: pada -O3
peningkatan Clang adalah 31%. Bagus, tetapi pada setiap level optimisasi GCC 619 build lebih dari dua kali lebih cepat dari 301.
GCC lebih dari membalikkan keunggulan mantan Clang. Dan pada setiap level optimasi, GCC sekarang mengalahkan Dentang sebesar 17%.
Kemampuan dentang di 301 membangun untuk mendapatkan lebih banyak leverage daripada GCC dari -O3
optimasi hilang di build 619. Tidak ada kompiler yang memperoleh manfaat dari -O3
.
Saya cukup terkejut dengan pembalikan nasib ini yang saya kira saya mungkin secara tidak sengaja membuat bangunan lamban dari dentang 3.4 itu sendiri (karena saya membangunnya dari sumber). Jadi saya menjalankan kembali tes 619 dengan stok distro saya, Dentang 3.3. Hasilnya praktis sama dengan untuk 3.4.
Jadi mengenai reaksi terhadap putar-U: Pada angka-angka di sini, Clang telah melakukan jauh lebih baik daripada GCC pada kecepatan perasutan dari kode C ++ saya ketika saya tidak memberikan bantuan. Ketika saya berusaha membantu, GCC melakukan pekerjaan yang jauh lebih baik daripada Dentang.
Saya tidak mengangkat pengamatan itu menjadi sebuah prinsip, tetapi saya mengambil pelajaran bahwa "Kompiler mana yang menghasilkan biner yang lebih baik?" adalah pertanyaan yang, bahkan jika Anda menentukan suite tes yang jawabannya relatif, masih bukan masalah yang jelas hanya menentukan waktu binari.
Apakah biner Anda yang lebih baik biner tercepat, atau apakah itu yang terbaik mengkompensasi kode yang dibuat murah? Atau kompensasi terbaik untuk
kode yang dibuat mahal yang memprioritaskan perawatan dan penggunaan kembali melebihi kecepatan? Tergantung pada sifat dan bobot relatif dari motif Anda untuk menghasilkan biner, dan kendala yang Anda gunakan.
Dan dalam hal apa pun, jika Anda sangat peduli dalam membangun biner "yang terbaik" maka Anda sebaiknya terus memeriksa bagaimana iterasi beruntun dari kompiler mewujudkan ide Anda tentang "yang terbaik" daripada iterasi berurutan dari kode Anda.