- Contoh pengamatan perbedaan optimisasi GCC dan Clang saat mengompilasi fungsi penjumlahan bilangan bulat sederhana
- GCC melakukan optimisasi loop dalam bentuk
x*2 + 1 untuk menjumlahkan dua angka sekaligus di dalam loop
- Clang menghapus loop sepenuhnya dan menggantinya dengan rumus bentuk tertutup
v(v - 1)/2
- Transformasi ini mengubah kode dari O(n) menjadi O(1), dengan penyederhanaan matematis yang dilakukan secara otomatis
- Bahkan bagi penulis yang sudah lebih dari 20 tahun bekerja dengan kompiler, ini menjadi contoh yang menunjukkan tingkat optimisasi cerdas dari kompiler
Optimisasi loop di GCC
- Saat menulis fungsi penjumlahan bilangan bulat sederhana, GCC menghasilkan kode penjumlahan efisien berbasis loop
- Di dalam loop, digunakan instruksi
lea edx, [rdx+1+rax*2] untuk menjumlahkan dua angka sekaligus
- Ini adalah bentuk transformasi operasi penjumlahan
x dan x+1 menjadi x*2 + 1
- Jika level optimisasi dinaikkan ke
-O3, loop diproses lebih cepat melalui penjumlahan paralel (vectorization)
- Pendekatan seperti ini merupakan bentuk optimisasi tradisional yang mempertahankan loop sambil memaksimalkan efisiensi operasi
Optimisasi matematis di Clang
- Saat kode yang sama dikompilasi dengan Clang, loop menghilang sepenuhnya
- Setelah memeriksa apakah nilai input positif, Clang melakukan perhitungan melalui rangkaian instruksi
lea, imul, dan shr
- Hasilnya ditransformasikan menjadi
(v² - v)/2, yaitu rumus bentuk tertutup untuk jumlah bilangan bulat
- Transformasi ini menghapus loop dan menggantinya dengan perhitungan waktu konstan (O(1))
- Penulis menggambarkan hasil ini sebagai “menemukan sendiri solusi matematis untuk penjumlahan bilangan bulat”
Proses penguraian rumus
- Jika kode assembly yang dihasilkan Clang ditelusuri balik secara matematis, transformasi berikut terjadi
v + ((v - 1)(v - 2) / 2) - 1
- Jika dikembangkan dan disederhanakan, hasilnya menjadi
(v² - v)/2
- Pada akhirnya bentuknya menjadi
v(v - 1)/2, yang cocok dengan rumus jumlah dari 1 sampai v
- Proses ini ditunjukkan sebagai contoh kompiler mengenali pola matematis dan mengoptimalkannya
Perilaku cerdas kompiler
- Alasan Clang menggunakan rangkaian instruksi spesifik ini dijelaskan berkaitan dengan pencegahan overflow dan cara pelacakan induction variable
- Penyebab pasti dari cara kerja internalnya tidak sepenuhnya jelas, tetapi disebut sebagai hasil dari kombinasi logika optimisasi internal Clang
- Penulis menyebut hasil ini sebagai “pengalaman yang merendahkan hati dan memberi inspirasi”
Penutup dan konteks seri
- Artikel ini adalah tulisan ke-24 dalam seri ‘Advent of Compiler Optimisations 2025’
- Artikel ini mengeksplorasi bagaimana kompiler mencapai penyederhanaan matematis dan peningkatan performa melalui transformasi kode
- Penulis menekankan bahwa “kompiler masih terus mengejutkan saya”, menyoroti rasa takjub teknis yang tetap ada meski sudah berpengalaman lama
Belum ada komentar.