- Sifat waktu konstan (constant-time) yang penting dalam kode kriptografi bisa rusak hanya oleh optimisasi kompiler, sehingga sedang dilakukan eksperimen menambahkan patch peringatan di dalam LLVM untuk mencari pola berbahaya
- “Optimisasi” kompiler memang bisa membuat sebagian benchmark lebih cepat, tetapi jalur inti yang sesungguhnya sering bergantung pada intrinsics dan assembly, sementara biaya bug yang lahir dari optimisasi terus menumpuk secara terpisah
- Pada Juni 2024, Antoon Purnal mengonfirmasi bahwa kode referensi Kyber pada Clang 15 ke atas, dengan sebagian opsi optimisasi tertentu, berubah menjadi percabangan kondisional berbasis nilai rahasia yang dapat membuka jalan bagi serangan timing
- TIMECOP 2 memeriksa hasil kompilasi yang dideklarasikan waktu konstan di dalam SUPERCOP, tetapi ada keterbatasan pada perintah yang didukung Valgrind dan pada aliran data yang benar-benar muncul saat pengujian dijalankan
- Respons praktis di lapangan adalah memakai fungsi seperti
crypto_{int,uint}{8,16,32,64}.h agar kompiler tidak melihat hasil 1-bit sebagai bool, atau berpindah ke assembly yang sudah diverifikasi, bahasa yang berorientasi keamanan, atau kompiler khusus
Kekosongan tanggung jawab yang diciptakan “optimisasi” kompiler
- Dalam riwayat perubahan LLVM dan GCC modern, “optimisasi”, pengujian “optimisasi”, perbaikan pengujian, dan perbaikan bug “optimisasi” terus bermunculan
- Walaupun kode bekerja baik sebelum dikompilasi, jika perilakunya berubah setelah perubahan kompiler, dalam banyak kasus tanggung jawabnya justru dibebankan kepada programmer yang dianggap menyentuh “undefined behavior”
- “Language standards” seperti ini dibuat oleh para penulis kompiler, dan hasilnya adalah struktur di mana perubahan dari kelompok kecil pembuat kompiler membebankan tanggung jawab yang lebih besar kepada kode milik jutaan programmer
- Sebagai contoh kode kriptografi, pada berbagai benchmark CPU, implementasi
avx2 dari kyber768 sekitar 4 kali lebih cepat daripada kode portabel yang dikompilasi dengan kompiler “optimisasi”
Batas pengukuran kinerja optimisasi
- Pada 2000, Todd A. Proebsting dalam Proebsting's Law menyatakan bahwa “kemajuan kompiler menggandakan daya komputasi setiap 18 tahun”, dan menyimpulkan kontribusi optimisasi kompiler hanya bersifat pinggiran
- Arseny Kapoulkine dalam benchmark tahun 2022 merangkum bahwa LLVM 11 membutuhkan waktu 2 kali lebih lama untuk kompilasi teroptimisasi dibanding LLVM 2.7, sementara kode hasil eksekusinya umumnya hanya 10~20% lebih cepat
- Kedua pembahasan itu sama-sama meleset dari pengukuran kinerja yang benar-benar dirasakan pengguna
- Hotspot tempat kinerja terkonsentrasi sering berisi intrinsics dan assembly
- FFmpeg memiliki 160.000 baris assembly berdasarkan file
.asm dan .S
- Semakin banyak data yang diproses komputer dan jaringan, semakin besar pula porsi waktu CPU nyata yang tertumpu pada hotspot semacam ini
- Biaya keamanan juga tumbuh terpisah dari diskusi optimisasi
- Deloitte melaporkan anggaran keamanan TI pada 2023 sebesar 0,5% dari pendapatan perusahaan
- Jika dilihat bersama angka total pendapatan perusahaan global pada 2022 yang melebihi 48 triliun dolar, skala keseluruhannya bisa mencapai ratusan miliar dolar
- Namun ada catatan bahwa angka 0,5% Deloitte bisa jadi hanya rata-rata sederhana per perusahaan, dan tidak semua perusahaan menjawab survei
Kebocoran timing dan kasus Kyber
- Masalah keamanan yang dibuat kompiler “optimisasi” bukan hanya bug tradisional, tetapi juga kebocoran timing di mana informasi rahasia bocor lewat waktu eksekusi
- Makalah EuroS&P 2018 oleh Laurent Simon, David Chisnall, dan Ross Anderson memperingatkan bahwa upgrade kompiler dapat diam-diam membuka kanal timing pada kode yang sebelumnya aman
- Contoh yang ditekankan dalam makalah 2018 adalah kode yang memilih salah satu dari dua nilai menggunakan
bool, dan bool memicu kompiler membuat lompatan kondisional
- Dalam implementasi kriptografi, ada praktik menghindari hal ini dengan membuang
bool dari kode penting dan menyediakan fungsi pembanding waktu konstan tersendiri
- OpenSSL dikutip mendeklarasikan 37 fungsi untuk tujuan ini
- Kasus 2015 pada
curve25519-donna dan MSVC 2015 dijelaskan sebagai kesalahpahaman dalam artikel ini
- Yang sebenarnya terjadi, saat dikompilasi untuk x86 32-bit, operasi
int64 diubah menjadi panggilan ke library int64 32-bit Microsoft, llmul.asm
- Kebocoran timing muncul dari percabangan bergantung data di
llmul.asm, dan library ini juga dinilai harus masuk dalam konsep yang wajar tentang kode sumber
- Pada Juni 2024, Antoon Purnal mengonfirmasi bahwa kode referensi Kyber dapat membuka peluang serangan timing pada Clang 15 ke atas dengan opsi optimisasi tertentu
- Bentuk masalahnya adalah
(-((x>>j)&1))&y, yaitu perhitungan yang menghasilkan y jika bit ke-j dari x aktif, dan 0 jika tidak
- Clang mengubah bit tersebut menjadi
bool lewat instruksi bit-test, lalu menghasilkan percabangan kondisional berdasarkan bool itu
- Di dalam LLVM, “optimisasi” ini ditangani oleh
combineShiftAnd1ToBitTest di lib/CodeGen/SelectionDAG/DAGCombiner.cpp
- Fungsi ini ditambahkan oleh Sanjay Patel pada September 2019 dan kemudian diubah oleh beberapa orang lain
- Ada juga contoh pelanggaran batas serupa di GCC
- Patch GCC dari ARM pada November 2021 mengubah
(-x)>>31 menjadi -(x>0)
- Pada April 2024, peringatan mengenai hal ini muncul
TIMECOP dan pemeriksaan waktu konstan
- TIMECOP 2 terintegrasi ke dalam framework pengujian kriptografi SUPERCOP dan secara otomatis memeriksa percabangan kondisional yang diturunkan dari nilai rahasia pada kode hasil kompilasi yang dideklarasikan waktu konstan
- Objek pemeriksaan tidak hanya percabangan kondisional, tetapi juga indeks array yang diturunkan dari nilai rahasia
- Makalah KyberSlash juga menjelaskan patch yang memeriksa pembagian yang diturunkan dari nilai rahasia
- TIMECOP 1 adalah alat yang dibuat Moritz Neikes dengan memodifikasi SUPERCOP, dan mengotomatisasi pendekatan ctgrind dari Adam Langley
- TIMECOP 2 memperluas metode sebelumnya dalam beberapa hal
- Menandai keluaran RNG secara otomatis sebagai nilai rahasia
- Mendukung “declassification”
- Mendukung penetapan “public inputs”
- Berjalan di banyak core
- TIMECOP memiliki keterbatasan yang jelas
- Hanya bisa menangani instruksi yang didukung Valgrind, sehingga akan berhenti pada instruksi seperti AMD XOP
- Hanya memeriksa aliran data yang benar-benar terlihat saat pengujian dijalankan
- Pengembangan alat pemeriksa perilaku waktu konstan masih terus berjalan, dan daftar alat terkait tersedia di ct-tools
- Pemeriksaan yang setara dengan TIMECOP telah masuk ke test suite libmceliece, dan bisa menyebar ke library lain
Pendekatan penulisan ulang waktu konstan
- Setelah menemukan potongan kode berdurasi variabel, dibutuhkan cara untuk menulis ulang menjadi waktu konstan tanpa bug
- Presentasi Juli 2024 memperkenalkan sebagian fungsi waktu konstan yang disediakan oleh libmceliece dan SUPERCOP
- Nama filenya
crypto_{int,uint}{8,16,32,64}.h
- File-file ini bisa disalin dan dipakai di proyek lain
- Fungsi contoh
crypto_uint32_bitmod_mask(x,j) memiliki efek yang sama seperti -((x>>(j&31))&1), tetapi membuat kompiler tidak bisa melihat hasil 1-bit
- Contoh yang lebih kompleks adalah
crypto_uint32_max(x,y)
- Makalah 2018 membahas tweak untuk menambahkan fungsi waktu konstan
__builtin_ct_choose(bool cond, x, y) ke Clang/LLVM
- Makalah itu secara keliru mengusulkan bahwa satu fungsi ini sudah cukup
- Fungsi ini mungkin suatu hari masuk ke kompiler, tetapi bisa butuh waktu lama sebelum proyek dapat mengandalkannya
- Cara implementasinya dinilai tampak lebih rapuh daripada
crypto_{int,uint}{8,16,32,64}.h
Cara menghindari masalah sejak awal
- Jika pengujian sebelum distribusi library hasil kompilasi berhasil menangkap kebocoran timing yang diperkenalkan kompiler, versi kompiler sebelumnya bisa tetap dipakai untuk distribusi selama kode sedang ditulis ulang
- Pendekatan ini adalah respons sementara untuk terus menjaga pengguna tetap aman
- Salah satu solusi adalah mendistribusikan library dalam bentuk assembly
- Presentasi RWC 2024 Adoption of high-assurance and highly performant cryptographic algorithms at AWS memperkenalkan perangkat lunak X25519 cepat yang telah dibuktikan menghitung X25519 dengan benar untuk semua input
- Implementasinya ditulis dalam assembly untuk 2 versi CPU Intel/AMD 64-bit dan 2 versi CPU ARM 64-bit
- Pernyataan kebenarannya adalah teorema tentang kode mesin yang benar-benar dijalankan pengguna, dan pembuktiannya diverifikasi dengan prover teorema HOL Light
- Namun, untuk perangkat lunak kriptografi yang belum mencapai tingkat ini, masalah sulitnya audit assembly tetap ada
- Juga sedang dieksplorasi cara cepat menyuntikkan “vaksin” pencegah kebocoran timing ke kode yang ditulis dalam C, C++, dan sebagainya
Eksperimen patch clang-vs-clang
- Kesamaan antara
x&1 dan x>>31 adalah hasilnya hanya punya dua kemungkinan
x&1 adalah 0 atau 1
x>>31 untuk uint32 adalah 0 atau 1
x>>31 untuk int32 adalah 0 atau -1
- Bentuk seperti ini memudahkan penulis “optimisasi” kompiler untuk memasukkan hasil 1-bit ke dalam
bool
- Ada rekomendasi untuk selalu mengompilasi dengan
-fwrapv agar GCC dan Clang mengasumsikan aritmetika komplemen dua
- Memindai source untuk
&1, 1&, >>31, dan sebagainya memang menghasilkan banyak contoh, tetapi pemindaian juga dilakukan dengan memasukkan patch langsung ke “optimizer” LLVM
- Patch itu dimulai dari commit LLVM
68df06a0b2998765cb0a41353fcf0919bbf57ddb, mencari &1 dan >>31, lalu mengeluarkan peringatan berikut
please take this away before clang does something bad
- Contoh perintah kompilasinya adalah
clang -Rpass-analysis=clang-vs-clang -O -c x.c
- Fungsi uji yang dipakai adalah sebagai berikut
int sra31(int x)
{
x >>= 31;
return x;
}
- Tidak mengejutkan jika peringatan yang sama muncul berulang kali
- Kompiler terus mencoba menerapkan “optimisasi” sampai tidak ada lagi kemajuan
- Keluaran
clang-vs-clang membedakan signed dan unsigned pada shift
- Perbedaan ini penting untuk penulisan ulang manual atau otomatis berbasis
crypto_{int,uint}{8,16,32,64}.h
- Salah satu cara mengotomatisasi transformasi source adalah
clang-tidy
- Kode yang terlewat oleh
#ifdef atau dihapus sebelum tahap “optimisasi” ini tidak akan memunculkan peringatan clang-vs-clang
Hasil eksekusi SUPERCOP dan kasus yang ditemukan
- SUPERCOP 20240716 dijalankan di dual EPYC 7742 dengan
./data-do-biglittle
- Overclocking dinonaktifkan
- Daftar kompiler SUPERCOP disesuaikan agar memakai
clang-vs-clang dengan menambahkan -Rpass-analysis=clang-vs-clang ke baris clang di okcompilers/{c,cpp}
- Hasilnya siap setelah 3 jam
- Keluaran Clang berjumlah 675.752 baris
- Ukuran aslinya 210.786.494 byte
- Hasil kompresinya adalah
20240803-fromclang.txt.gz sebesar 3.595.199 byte
- Keluaran itu mengandung banyak noise dari percabangan source berbasis data publik yang di dalam Clang menghasilkan
&1
- Contoh yang jelas layak diubah lebih awal adalah sebagai berikut
a0 += (a0>>15)&106;
- Contoh yang perlu upaya parsing C bila dicari dengan pemindaian source sederhana adalah sebagai berikut
- Makro
ONE8 didefinisikan sebagai ((uint8_t)1)
*pk2^=(((* pk_cp)>>ir)&ONE8)<<jr;
- Contoh yang lebih sulit lagi muncul dalam makro berbasis intrinsic AVX2
signmask_x16(x) didefinisikan sebagai _mm256_srai_epi16((x),15)
- Ini menggeser ke kanan 15 bit setiap potongan signed 16-bit di dalam vektor 256-bit
mask = signmask_x16(sub_x16(x,const_x16((q+1)/2)));
- Kasus AVX2 ini belum menjadi prioritas tinggi
- Agar operasi vektor berubah menjadi percabangan kondisional, kode harus dikompilasi dengan AVX-512, dan kompiler harus mengambil keputusan aneh dengan mengubah
bool tervektorisasi menjadi percabangan kondisional bool serial
- TIMECOP memakai Valgrind, dan Valgrind tidak mendukung AVX-512
- Untuk saat ini, kompilasi AVX-512 tidak direkomendasikan
int128 dan arah respons yang lebih luas
- Temuan paling menarik adalah kasus di mana shift kanan 64-bit pada
int128 memicu peringatan >>
- Implementasi
int128 secara internal bisa memakai shift kanan 63 bit untuk mengetahui tanda dari word 64-bit bagian atas
- Jika Clang menambahkan dukungan seperti GCC untuk mengubah shift kanan 63 bit menjadi
bool, lalu menjadi percabangan kondisional, banyak kode int128 bisa mendadak menjadi waktu variabel
- Dalam kasus ini, situasinya mirip dengan yang diklaim judul makalah 2015, tetapi kali ini benar-benar bisa terjadi walaupun source tidak memiliki
bool
- Perlindungan termudah di tingkat source adalah menghindari implementasi
int128 bawaan kompiler dan memakai fungsi crypto_int128
- Tidak seperti
int128 milik GCC dan Clang, crypto_int128 dapat bekerja juga pada platform 32-bit yang kecil
- Gagasan menambahkan tipe data rahasia ke GCC dan Clang tampak bagus, tetapi dari struktur kedua kompiler itu sendiri belum terlihat cara membuatnya kokoh
- Harapan lebih besar diletakkan pada kompiler yang sejak awal dirancang untuk keamanan
- Ada kompiler berfokus keamanan yang membutuhkan bahasa input baru seperti FaCT dan Jasmin yang sedang aktif dikembangkan
- Ada kekhawatiran soal waktu penulisan ulang kode, tetapi melihat cara kompiler saat ini menangani kode lama, tindakan dalam bentuk apa pun tampaknya memang diperlukan
1 komentar
Pendapat di Hacker News
Tidak tepat menyebutnya bug compiler ketika kode yang memiliki perilaku tak terdefinisi tidak berjalan sesuai keinginan
Ini mirip seperti menjalankan
dddengan argumen yang salah lalu menghapus data, kemudian mengatakanddpunya bugSulit menyebut source code atau compiler sebagai bug; lebih tepat melihatnya sebagai standar C yang, menurut kriteria penulis, terlalu kurang terspesifikasi sehingga menimbulkan bug keamanan pada sebagian target
Pada akhirnya para penyusun standar C tidak bisa mendefinisikan sampai perilaku hardware, hanya semantik bahasa, jadi bidang kriptografi mau tidak mau harus bergelut dengan bug yang bersumber dari hardware
Salah satu kelebihan Rust adalah membatasi potensi perilaku tak terdefinisi ke dalam blok
unsafe. Meski begitu, walaupun Rust telah mendefinisikan banyak hal yang di C merupakan perilaku tak terdefinisi, begitu masuk ke kodeunsafe, sangat mudah secara tidak sengaja menginjak perilaku tak terdefinisi yang subtilModel ketiga, yaitu gagal diam-diam sambil menghasilkan kode yang tidak dapat diprediksi, hanya berguna bagi penulis compiler. Bersembunyi di balik spesifikasi tidak memberi manfaat bagi pengguna nyata
Optimasi itu merusak kode yang sebelumnya berjalan baik. Para penulis compiler bisa saja memprioritaskan kompatibilitas mundur, tetapi mereka tidak melakukannya
Selain itu, optimasi semacam ini juga tidak secara berarti meningkatkan performa kode nyata, jadi mereka perlu membantah argumen bahwa kompromi yang merusak kode itu tidak sepadan
Saya menyukai Bernstein, tetapi kadang ia salah arah dan menjadi terlalu ekstrem, dan tulisan ini adalah contoh yang baik. Di akhir tulisan, ia sendiri juga setengah mengakuinya
Bagian besar tulisan itu adalah poin sampingan tentang seberapa bagus keuntungan optimasi, dan meski ada datanya, penilaiannya akan bergantung pada use case
Keluhan utamanya adalah compiler C tidak mempertimbangkan semantik yang tidak bisa diekspresikan oleh bahasa tersebut, dan itu bukan hal yang mengejutkan
Di bagian akhir ia mengatakan, “pakailah bahasa yang bisa mengekspresikan semantik yang dibutuhkan,” dan seluruh tulisan itu sebenarnya bisa digantikan oleh satu kalimat tersebut
Banyak di antaranya landasannya meragukan, dan membuat penulisan program yang benar menjadi lebih sulit
C dan C++ tidak cocok untuk menulis algoritma yang memiliki jaminan waktu konstan
Di standar hampir tidak ada konsep real-time, dan compiler juga tidak menyediakan jaminan tambahan lewat ekstensi
Namun menyalahkan pengembang compiler untuk hal ini adalah arah yang keliru
Pada CPU Intel,
clangataupun yang lain tidak bisa menghasilkan kode yang benar di mode pengguna. Karena sejak awal tidak ada kode yang benarhttps://www.intel.com/content/www/us/en/developer/articles/t...
Jika melihat
DOITMdi dokumen tersebut, library kriptografi di user space sama sekali tidak mungkin menyetel bit yang diperlukanSetelah dinyalakan, mode itu berjalan baik bahkan di user space, jadi misalnya bisa dibuat sebagai flag per proses yang diaktifkan lewat system call
prctl, lalu scheduler menyesuaikanMSRsaat perpindahan taskKalimat “setiap kali memungkinkan, para penulis compiler menolak bertanggung jawab atas bug yang mereka buat” saja sudah menunjukkan kasus yang jarang terjadi, ketika kredibilitas sebuah tulisan blog runtuh secepat ini
Kalau mengikuti tautannya pun, itu hanya hal C yang sangat mendasar: perilaku tak terdefinisi bukan berarti menghasilkan “nilai sembarang”
Meski ada perilaku tak terdefinisi, kode sumbernya memang bug, tetapi program yang dihasilkan sering kali tetap benar. Ketika belakangan penulis compiler memasukkan optimisasi baru dan, berdasarkan perilaku tak terdefinisi itu, menghasilkan program yang bermasalah, perdebatan soal tanggung jawab pun dimulai
Bagian yang enggan diakui adalah bahwa tanggung jawab terhadap pengguna terbagi di semua pihak. Jika baterai terbakar hanya karena sebuah aplikasi CRUD melakukan dereference
NULL, orang waras tidak akan hanya menyalahkan penulis aplikasi karena lupa memeriksaNULLCompiler, sistem operasi, dan vendor perangkat keras juga harus bertanggung jawab atas produk yang dirancang secara tidak bertanggung jawab; ini tidak selesai hanya dengan mengatakan “perilaku tak terdefinisi” menurut standar ISO. Semua anggota rantai pasok berbagi tanggung jawab untuk mengantisipasi bagaimana produk dapat disalahgunakan dan menanganinya secara wajar
Perilaku tak terdefinisi ada untuk memberikan nilai. Bahasa bisa dibuat tanpanya, tetapi alasan ia tetap ada adalah portabilitas dan fleksibilitas yang diberikan kepada penulis compiler
Inti tulisannya adalah apakah fleksibilitas itu memang bernilai jika dibandingkan dengan sulitnya menulis program tanpa perilaku tak terdefinisi
Menurut penulis, uang yang hilang karena bug tampaknya lebih besar daripada uang yang dihemat lewat bytecode yang lebih cepat, dan karena penulis compiler punya pengaruh besar dalam menentukan isi standar bahasa, kemauan untuk memperbaiki hal ini lemah
Sebagai catatan,
clangmemiliki atributclang::optnoneuntuk mematikan semua optimisasi per fungsi, dan GCC memiliki atributgnu::optimizeyang bagus, yang bisa menambah atau menghapus optimisasi berdasarkan nama, atau menetapkan level optimisasi terlepas dari flag compilergnu::optimize(0)mirip dengan flagclangitu.clangjuga memilikiclang::no_builtins, khusus untuk mematikan optimisasimemcpydanmemsetoptimizehanya boleh digunakan untuk tujuan debugging, dan tidak cocok untuk kode produksi”https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute...
Saya cukup memahami tujuan yang diinginkan orang-orang kriptografi, misalnya evaluasi waktu konstan dan penyembunyian nilai rahasia
Namun compiler serbaguna tidak memikirkan hal seperti itu hampir sepanjang waktu, jadi tampaknya sulit menjadi lebih dari sekadar hack yang umumnya bekerja
Kalau ingin serius, sepertinya perlu compiler khusus sendiri, atau harus terus memakai assembly
Suatu saat nanti kita mungkin akan menganggap masa sekarang sebagai masa lalu yang buruk, dan sudah beranjak dari C ke bahasa dengan perilaku tak terdefinisi yang jauh lebih sedikit
Di C, terlalu mudah menulis ekspresi yang bisa dikompilasi, tetapi niatnya sama sekali tidak bisa dipahami compiler
Misalnya di Python, kita bisa menulis kode seperti
result = [something(value) for value in set_object]. Karena objeksettidak memiliki urutan, jelas bahwa urutan pemrosesan item dan urutan hasil tidak penting, dan ini membuka banyak peluang optimasi di tingkat bahasa tanpa compiler harus menebak niat penulisKode serupa dalam bahasa lain dengan data immutable melangkah lebih jauh: karena
something(value1)tidak dapat memengaruhisomething(value2), ia bisa dijalankan paralel, baik dengan thread maupun prosesSebagian besar optimasi compiler C adalah melihat pola kode lalu mencari cara mempercepat hal yang mungkin dimaksud penulis. Dibanding bahasa-bahasa modern, C kurang mampu mengekspresikan niat sehingga compiler memang punya kebebasan untuk menebak, tetapi untuk menghasilkan performa yang decent, inferensi semacam itu harus dilakukan
Meski begitu, ini mungkin juga berkah terselubung, seperti ketika teleskop Hubble membutuhkan kacamata. Untuk mengatasi keterbatasan, teknik-teknik hebat dibuat, dan setelah masalahnya diperbaiki, teknik-teknik itu menghasilkan performa jauh lebih tinggi daripada perkiraan awal. Jika optimasi compiler C diterapkan ke bahasa non-C, mungkin ia akan bekerja seperti kekuatan super
Pada dasarnya ini mirip perilaku tak terdefinisi, tetapi alih-alih langsung menjadi masalah keamanan, ia bisa muncul sebagai hasil yang salah. Tentu saja hasil yang salah nantinya bisa berujung pada masalah keamanan
Berbeda dari perilaku tak terdefinisi, praktis mustahil membuat “sanitizer” yang memeriksa apakah kode bekerja untuk semua kemungkinan urutan
setgccdanclangpunya banyak hint level rendah yang sering tidak ada di bahasa lain. Ada__builtin_expect/__builtin_unpredictable,__builtin_unreachable/__builtin_assume,#pragma clang loop vectorize(assume_safety)/#pragma GCC ivdep, pragma untuk mematikan loop unrolling atau vektorisasi, atau memilih nilai tertentu, dan sebagainyaMenurut saya yang paling besar hilang adalah optimization barrier yang secara eksplisit mencegah compiler membuat inferensi berdasarkan asal-usul nilai.
__asm__sampai batas tertentu bisa, tetapi punya efek samping yang tidak diinginkan dan memerlukan nama jenis register yang spesifik platformPotensi optimasi tingkat tinggi berbasis niat juga jelas ada. Misalnya, memesan ruang array list sebelum melakukan
pushsebanyaknkali dalam loop, menggabungkan lookup hashmap yang melakukancontains→get→putdengan kunci yang sama, atau secara lokal menginferensi perilaku alokasi global untuk menghilangkan objek dan alokasiC cukup dekat dengan hardware nyata sehingga programmer bisa langsung mengatakan apa yang harus dilakukan, jadi compiler tidak perlu menebak niat programmer
Bahasa yang mengimplementasikan optimasi memori semacam itu umumnya sejenis Java, dan sejak awal sudah ada pre-pessimization yang agresif, sehingga muncul motivasi untuk melakukan optimasi tersebut. Namun bahkan optimasi itu pun tidak mampu menutup kerugiannya
Intinya, C memang kurang bagus, tetapi sisi lain lebih buruk
Jika tidak suka semantik C, jangan marah kepada engineer compiler; pakailah bahasa pemrograman lain
qhasmmiliknya sendiri. Bahkan Zig sekalipun. Penilaian kali ini tidak terlalu mengejutkan darinyaTulisan yang menyegarkan karena menyampaikan sudut pandang yang jarang terdengar. Layak dibaca bersama: https://gavinhoward.com/2023/08/the-scourge-of-00ub/