What the Fork - Gerçek Zamanlı C/C++/Rust Derleme Görselleştirme Aracı
(danielchasehooper.com)- What the Fork, C/C++/Rust dahil çeşitli derleme süreçlerini gerçek zamanlı görselleştiren çapraz platform bir araçtır
- Mevcut derleme sistemlerindeki yetersiz paralelleştirme, verimsiz süreçler gibi yapısal sorunları kolayca tespit etmeyi sağlar
- Tüm derleme sistemleri ve programlama dillerinde çalışır; make, ninja, gradle, zig, cargo gibi çeşitli derleme araçlarını destekleyebilir
- Sistem çağrısı izleme ile her sürecin çalışma süresini, komutunu ve bağımlılık ilişkilerini kutular halinde görselleştirir
- Derleme optimizasyonu, darboğaz analizi ve CI performansını iyileştirmek için çok kullanışlı bir araçtır
Giriş ve arka plan
- What the Fork, derlemelerin neden yavaşladığını görsel olarak teşhis etmek için geliştirilen gerçek zamanlı bir derleme görselleştirme aracıdır
- LLVM projesinde olduğu gibi kod tabanı büyük olduğu için derleme doğal olarak yavaş olabilir; ancak çoğu derleme, verimsiz yapılandırmalar yüzünden gereksiz yere uzun sürer
- Daha önce derlemedeki sorunları doğrudan görmek veya yapısal problemleri tek bakışta anlamak zordu; bu nedenle böyle bir araca ihtiyaç vardı
- Bu araç çapraz platform olarak tasarlanmıştır ve tüm derleme sistemleri ile dillere uygulanabilir
Başlıca özellikler ve kullanım
- What the Fork, basit bir sistem profilleyicisi değil, derlemeye özgü sorunları teşhis eden bir araçtır
- Örnekler arasında make kullanırken
-jbayrağının kullanılmaması, belirli dosya ya da derleme adımlarında zamanın yığılması ve paralel çalışması mümkünken sıralı yürütülen komutların tespiti yer alır - Özellikle CI ortamlarında clean build performansını analiz etmek ve optimize etmek için etkilidir
- Kullanım yöntemi,
wtfkomutunu derleme komutunun önüne ekleyerek çalıştırmaktır (ör.wtf make,wtf cargo build,wtf npm run build) - Derleme başladığında arayüz açılır ve her sürecin ilerleme durumu gerçek zamanlı olarak güncellenir
Arayüz ve görselleştirme yöntemi
- Her derleme süreci, zaman çizelgesi üzerinde kutu şeklinde gösterilir ve türüne göre renklendirilir
- Süreçlerin ebeveyn-çocuk ilişkileri iç içe geçmiş bir yapı ile ifade edilir
- Alt panelde seçilen sürecin çalışma süresi, çalışma dizini ve tam komut argümanları gösterilir
Çalışma prensibi
- Derleme, birden çok sürecin (ör.
bash,clang,ld) birleşiminden oluşur - Büyük ölçekli derlemelerde
cargo,make,bazel,gradle,xcodebuildgibi çeşitli derleme araçları kullanılır ve bunlar gerçekte çok sayıda komut, bağımlılık, önbellek ve zamanlama işlemi yürütür - Yalnızca terminal çıktısıyla iç içe süreçleri (ör.
clangın içeride çağırdığıldgibi) ve ayrıntılı zamanlama yapısını anlamak mümkün değildir - Bunun için işletim sistemine göre süreç başlatma ve sonlandırmayı algılayan sistem çağrıları kullanılır (macOS: Endpoint Security API, Linux:
ptrace(), Windows: Event Tracing for Windows) - Bu yöntemle tüm derleme süreci ve zaman çizelgesi yeniden oluşturulabilir; her adımın yürütme yolu ve süresi belirlenebilir
- Derleme dışında da çeşitli alt süreçleri izlemek için kullanılabilir
Gerçek örnekler ve gözlemler
- Çeşitli mühendisler (Delta, Mozilla, Apple) bunu gerçek projelerde kullandıktan sonra beklenmedik sorunlar buldu
- Örnek 1: Cargo kullanan bir açık kaynak projede dosyaların sıralı derlendiği görüldü ve paralellik eksikliği doğrulandı (10 çekirdekli CPU'da 10 kattan fazla hızlanma potansiyeli tespit edildi)
- Örnek 2: Ninja ile yapılan LLVM derlemesinde tüm CPU çekirdeklerinin verimli biçimde paralel çalıştığı ve ideal derleme verimliliğinin sağlandığı görüldü
- Örnek 3: CMake tabanlı bir projede cmake/make/clang'ın iç içe çalıştığı ve Xcode/OS sürümünün yeniden kontrol edilmesinin 85 kez tekrarlandığı verimsiz bir yapı keşfedildi (gerçek işin yalnızca çok küçük bir kısmı yapılıyordu)
- Örnek 4:
xcodebuildkullanan büyük bir Objective-C projesinde derlemenin son bölümünde paralellik eksikliği ve derleme başlamadan önce 6 saniyelik bir boşta kalma durumu görüldü (ninjaise yalnızca 0.4 saniye sonra derlemeye başlıyordu) - Örnek 5: Zig, Orca Project'i derlerken bağımlılıkların derleme sırasını rastgele belirlediği için paralelleştirme verimi şansa bağlı hale geliyor. Bazı bağımlılıkların en sonda çalışması nedeniyle paralelliğin düştüğü gözlemlendi
- Örnek 6: make/go kullanan GitHub CLI projesinde bağımlılık indirme süresinin büyük olduğu görüldü. Bağımlılıkların azaltılmasıyla derleme hızının artması bekleniyor
Kullanım etkisi ve sınırlamalar
- Görsel zaman çizelgesi analiziyle beklenmedik darboğazlar, gereksiz bağımlılık tekrarları ve yetersiz paralellik görülen alanlar tespit edilebilir
- Bağımlılık sorunları, gereksiz yeniden çalışma ve belirli araçlardaki verimsizlik gibi yapısal iyileştirme noktaları hızla belirlenebilir ve derleme performansını optimize etmek için doğrudan kullanılabilir
- Süreçlerin tam komutlarının görülebilmesi daha ayrıntılı analiz sağlar
Beta programı
- What the Fork, Windows, Linux ve macOS üzerinde çalışır
- Geri bildirim vermek isteyen bireyler ve ekipler private beta'ya başvurabilir (Google Form bağlantısı sağlanıyor)
3 yorum
Komut adı çok komikmiş lol,
wtfde neymiş öyle…Umarım açık kaynak olarak yayımlanır.
Hacker News görüşleri
Şu anda yalnızca CMake, GCC ve Unix Make kullanılabilen bir ortama sıkışıp kaldım; bu yüzden build’in neden yavaş olduğuna dair ayrıntılı bilgi almak neredeyse imkansız. Kaynaktan build klasörüne dosya kopyalama gibi karmaşık build adımları, birden fazla dil (C, C++, Fortran, Python), özel CMake adımları vb. yüzünden build tam bir karmaşa. Bu araç böyle kaotik bir ortamda da iyi çalışıyorsa gerçekten çok şey öğrenilebilir gibi görünüyor.
tsoding, https://github.com/tsoding/nob.h içinde çapraz platform build’ler için tek başlıklı bir C kütüphanesi yazdı; yalnızca
ccgerekiyor. GDB profiling aracıyla build adımlarına bakılabiliyor. Bence harika bir fikir. Belki bu yazının yazarına uymayabilir ama birden fazla dille uğraşıyorsanız Nix de harika bir build aracı.Ben de GCC eklentisi olarak bir derleme süresi tracing/profiling aracı yazdım, ilgilenirseniz bakın: https://github.com/royjacobson/externis
Oyun motorumun derleme süresini azaltmaya çalışırken, derlenen çıktının boyutunu dolaylı bir ölçü olarak kullanmıştım. Duvar saati süresi o kadar kararsızdı ki, build’ler arasında hatta farklı makinelerde bile aynı olan ikili dosya boyutunu ölçmek daha kolaydı. %100 birebir uyuşmuyor ama pratikte faydalı olmuştu.
Ben de benzer bir sorun yaşıyorum. Bazen CMake’in değiştirmediğim dosyaları bile yeniden derlediğini gördüm. Mesela arayüzü değiştirmeden bir
.cppdosyasında ufak bir düzenleme yapınca tamamen bağımsız nesneler bile yeniden derleniyor. CMake’in gerçek dosyalardan daha güçlü bağımlılıklar oluşturup oluşturmadığını bazen merak ediyorum; sanki build süreleri gereksiz yere uzuyor gibi.Blog yazarına bir önerim var: macOS uygulamasını build ederken kaydedilmiş gif görselini sayfanın üst kısmında, başlığın hemen altında göstermesi güzel olurdu. Önce ortaya çıkan şeyi gösterip sonra açıklamak daha iyi bir akış sağlar.
Bu projeyi gerçekten çok beğendim. 2018’de benzer bir şeyi
stracevedtruss, ayrıca https://buildinfer.loopperfect.com/ ile deneyip BUCK dosyalarını otomatik üretme gibi işler yapmıştım. Görselleştirme için graphviz, perfetto.dev vb. kullandım. Bunu tam anlamıyla bir ürüne dönüştürememiş olmam üzücü ama danışmanlık işlerinde kök neden analizi ve BUCK/Bazel geçişlerinde çok yardımcı oldu. Son zamanlarda daha geniş uygulanabilirlik için tekrar dönüp bakıyorum. Bu yaklaşımın bazı temel teknik zorlukları da var: sistem çağrısı logları diske yazıldığında boyut onlarca hatta yüzlerce GB’a çıkabiliyor (ör. llvm 50GB, bazı durumlarda 100GB+), https ve IPC gibi build adımlarını da düzgün ele almak gerekiyor (bir keresinde bir müşteri her build’de Firebird DB’den Perl ile kod çekiyordu), bir de çalışma zamanı analizi olduğu için her build yapılandırmasında analizi yeniden yapmak gerekiyor.LD_PRELOADgibi bir numara mı, yoksa eBPF filtreleme mi kullandınız?Bence çok havalı. Bu tür görselleştirmeler olmadığı için gözden kaçan çok fazla sorun var. 10 yıl önce Mozilla build sistemini optimize ederken böyle bir araç olsaydı inanılmaz yardımcı olurdu. Yazıda gerçekte hangi sorunların bulunduğuna dair biraz daha fazla bilgi olsa daha da iyi olurmuş.
CMake ile yönetilen bir C++ projesinde build performansını görselleştirmek için ninjatracing ve Clang’in
-ftime-traceseçeneğini başarıyla kullandım. Ek olarak ClangBuildAnalyzer kullanılırsa derleyicinin zamanı tam olarak nerede harcadığı daha ayrıntılı analiz edilebiliyor.Gerçekten çok havalı görünüyor; bunu open source yapma planı var mı merak ediyorum. Ben de benzer bir şey üzerinde çalışıyorum, iş birliği yapmak isterim.
Windows’ta Visual C++ derleyicisi kullanıyorsanız vcperf de öneririm. VS2022 ile birlikte geliyor ya da GitHub’dan derleyip kullanabilirsiniz. Bunu UBT veya CMake ile oluşturulmuş projelerde de kullandım. Build paralelleştirmesinin kalitesini doğrudan gösterip göstermediğini hatırlamıyorum ama derleyici frontend bilgilerini görmek çok kolay; özellikle sık include edilen ya da doğası gereği ağır header dosyalarını bulmakta çok işe yarıyor.
Genelde gözden kaçıyor ama önemli bir gözlem şu: build sistemine “baked in” olarak gömülmüş, yani önceden hesaplanmış build mantığının hangi değişikliklerden etkilendiği ayrıntılı biçimde izlenmiyor. Örneğin ninja’da build mantığının bir kısmı önceden giriş olarak verildiği için hızlı çalışıyor. Ben Xerces-C++ üzerinde ninja (CMake ile yapılandırılmış) ve build2’yi (yapılandırma ve değişiklik takibini build içinde ele alan bir araç) kullanarak tam build benchmark’ı yaptım; ninja 3,23 saniye, build2 ise 3,54 saniye sürdü. CMake’in ürettiği dosyaların bir kısmını koruyarak aynı build’i tekrar çalıştırınca bu süre 3,28 saniyeye düştü. Sadece CMake’in yapılandırma aşaması ise 4,83 saniye sürüyor. Yani tam yığın CMake+ninja build’i pratikte yaklaşık 8 saniye tutuyor; çoğu kullanıcının bir kütüphane olarak kullanırken gerçekten yaşadığı süre de bu.
kbuild, CFLAGS gibi seçenekler değiştiğinde bunun doğru yansıması için Make’te her hedefi sahte bir dosyaya bağımlı hale getiriyor. Make’i ninja gibi kullanabilmek için de tüm build grafiğini her Make sürecine vermeyecek şekilde tasarlanmış. Gerçekte nasıl karşılaştırılacağını merak ediyorum.Build sırasında Instruments çalıştırıp hangi sürecin ne zaman ne yaptığını anlamaya çalışarak benzer bir yaklaşım denedim. Dezavantajı, build uzun sürerse Instruments’ın takılmaya başlaması. Süreç ağacını filtreleyememek de can sıkıcıydı ama Twitter’ın iOS kodunun build süresini ciddi biçimde azaltırken çok yardımcı olmuştu. Son zamanlarda Instruments’ın “All Processes” tracing’i bozulduğu için artık bu yöntem de kullanılamıyor.
Gerçekten harika görünüyor. Şu anda deneyebileceğimiz bir macOS sürümü var mı merak ediyorum; Rust ya da C++/Swift çalışmalarımda denemek isterim.
Hata düzeltmelerinden sonra bir sonraki beta test kullanıcıları için macOS sürümünü dağıtacağız. (Yazının altında) başvuru yaparken bu yorumu anarsanız sizi beta grubuna mutlaka eklerim.
Henüz hiçbir OS için herkese açık bir sürüm yok gibi görünüyor; sadece erken erişim başvurusu yapılabiliyor.