What the Fork - रियल-टाइम C/C++/Rust build visualization tool
(danielchasehooper.com)- What the Fork एक cross-platform टूल है जो C/C++/Rust सहित विभिन्न build प्रक्रियाओं को रियल-टाइम में visualize करता है
- इससे मौजूदा build systems की parallel processing की कमी, inefficient processes जैसी संरचनात्मक समस्याओं को आसानी से पहचाना जा सकता है
- यह सभी build systems और programming languages पर काम करता है, और make, ninja, gradle, zig, cargo जैसे विभिन्न build tools को support कर सकता है
- system call monitoring के जरिए हर process का execution time, command, dependency relationship को box के रूप में visualize करता है
- build optimization, bottleneck analysis, और CI performance improvement के लिए यह बहुत उपयोगी टूल है
परिचय और पृष्ठभूमि
- What the Fork एक रियल-टाइम build visualization टूल है, जिसे build के धीमा होने के कारणों का visual diagnosis करने के लिए बनाया गया है
- LLVM project जैसे मामलों में codebase बहुत बड़ा होने के कारण compilation धीमा हो सकता है, लेकिन ज़्यादातर builds inefficient configuration की वजह से अनावश्यक रूप से ज़्यादा समय लेते हैं
- पहले build की समस्याओं को सीधे देखना या संरचनात्मक समस्याओं को एक नज़र में समझना मुश्किल था, इसलिए ऐसे टूल की ज़रूरत थी
- यह टूल cross-platform तरीके से डिज़ाइन किया गया है और सभी build systems और languages पर लागू किया जा सकता है
मुख्य फीचर्स और उपयोग
- What the Fork सिर्फ एक सामान्य system profiler नहीं है, बल्कि build-specific समस्याओं का diagnosis करने वाला टूल है
- उदाहरण के तौर पर make इस्तेमाल करते समय
-jflag का उपयोग न होना, किसी खास file या compilation step में समय का ज़रूरत से ज़्यादा लगना, या parallel processing संभव होने के बावजूद commands का sequentially चलना—इन सबका पता लगाया जा सकता है - खास तौर पर CI environment में clean build performance के analysis और optimization के लिए यह प्रभावी है
- उपयोग का तरीका है build command से पहले
wtfcommand जोड़कर चलाना (जैसे:wtf make,wtf cargo build,wtf npm run buildआदि) - build शुरू होते ही UI खुलता है और हर process की प्रगति को रियल-टाइम में update करता है
UI और visualization का तरीका
- हर build process को timeline पर box के रूप में दिखाया जाता है, और type के आधार पर रंगों से अलग किया जाता है
- process की parent-child relationship को nested structure में दिखाया जाता है
- नीचे वाले panel में चुने गए process का execution time, working directory, और पूरी command argument जानकारी दिखाई जाती है
काम करने का तरीका
- build कई processes (जैसे:
bash,clang,ld) के संयोजन से बनता है - बड़े build
cargo,make,bazel,gradle,xcodebuildजैसे विभिन्न build tools का उपयोग करते हैं, और ये वास्तव में कई commands, dependencies, cache, और scheduling tasks चलाते हैं - सिर्फ terminal output से nested processes (जैसे
clangद्वारा अंदर से call किया गयाld) और detailed timing structure को समझना संभव नहीं होता - इसके लिए OS के अनुसार process start और termination का पता लगाने वाले system calls का उपयोग किया जाता है (macOS: Endpoint Security API, Linux: ptrace(), Windows: Event Tracing for Windows आदि)
- इस तरीके से पूरे build process और timeline को reconstruct किया जा सकता है, और हर चरण का execution path और समय पहचाना जा सकता है
- build के अलावा भी इसे विभिन्न subprocess tracking में इस्तेमाल किया जा सकता है
वास्तविक उदाहरण और अवलोकन
- कई engineers (Delta, Mozilla, Apple से) ने इसे अपने प्रोजेक्ट्स में लागू करके अप्रत्याशित समस्याएँ खोजीं
- उदाहरण 1: Cargo का उपयोग करने वाले open source project में files sequentially compile हो रही थीं, जिससे parallelism की कमी सामने आई (10-core CPU पर 10x से अधिक speed improvement की संभावना मिली)
- उदाहरण 2: Ninja का उपयोग करने वाले LLVM build में सभी CPU cores कुशलतापूर्वक parallel काम कर रहे थे, जिससे आदर्श build efficiency हासिल हुई
- उदाहरण 3: CMake-आधारित project में cmake/make/clang की nested execution और Xcode/OS version की दोबारा जाँच 85 बार दोहराई जाने वाली inefficient structure पाई गई (वास्तविक काम बहुत कम था)
- उदाहरण 4: xcodebuild का उपयोग करने वाले बड़े Objective-C project में build के अंतिम हिस्से में parallel processing की कमी और build शुरू होने से पहले 6 सेकंड की inactivity मिली (तुलना में ninja सिर्फ 0.4 सेकंड बाद compilation शुरू कर देता है)
- उदाहरण 5: Zig जब Orca Project को compile करता है, तो dependency build order random तय होती है, जिससे parallel processing efficiency किस्मत पर निर्भर हो जाती है। कुछ dependencies आख़िर में चलने से parallelism घटता देखा गया
- उदाहरण 6: make/go का उपयोग करने वाले GitHub CLI project में dependency download समय बहुत अधिक था। dependencies कम करने पर build speed बेहतर होने की उम्मीद है
उपयोग के प्रभाव और सीमाएँ
- visual timeline analysis के जरिए अप्रत्याशित bottlenecks, dependencies की अनावश्यक पुनरावृत्ति, और कम parallelism वाले क्षेत्रों की पहचान की जा सकती है
- dependency issues, अनावश्यक rework, और किसी खास tool की inefficiency जैसी संरचनात्मक सुधार की जगहों को जल्दी समझकर build performance optimization में सीधे उपयोग किया जा सकता है
- process की पूरी command देखने से और अधिक सूक्ष्म analysis संभव होता है
बीटा प्रोग्राम
- What the Fork Windows, Linux, macOS पर काम करता है
- feedback देना चाहने वाले व्यक्ति और teams private beta के लिए apply कर सकते हैं (Google Form link उपलब्ध)
3 टिप्पणियां
कमांड का नाम बहुत मज़ेदार है lol,
wtfहै आखिर…उम्मीद है कि यह open source के रूप में आएगा।
Hacker News राय
मैं इस समय ऐसे माहौल में फंसा हूँ जहाँ सिर्फ CMake, GCC और Unix Make उपलब्ध हैं, इसलिए build धीमा क्यों है इस पर विस्तार से जानकारी पाना लगभग असंभव है। build भी काफ़ी बेतरतीब है—जैसे source से build folder में files copy करना, कई भाषाएँ (C, C++, Fortran, Python), custom CMake steps वगैरह। अगर यह tool ऐसे अव्यवस्थित माहौल में भी अच्छी तरह काम करता है, तो इससे सच में बहुत कुछ सीखा जा सकता है।
tsoding ने https://github.com/tsoding/nob.h में cross-platform builds के लिए single-header C library लिखी है। इसमें सिर्फ
ccचाहिए। GDB profiling tool का उपयोग करके build steps को देखा जा सकता है। मुझे यह शानदार विचार लगता है। शायद यह इस लेख के लेखक के लिए उपयुक्त न हो, लेकिन अगर आपको कई भाषाओं के साथ काम करना है, तो Nix एक बेहतरीन build tool है।मैंने खुद GCC plugin के रूप में compile-time tracing/profiling tool बनाया है। अगर दिलचस्पी हो तो देखें: https://github.com/royjacobson/externis
जब मैं अपने game engine का compile time घटाने की कोशिश कर रहा था, तब मैंने compiled output के size को एक proxy metric के रूप में इस्तेमाल किया था। wall-clock time इतना अस्थिर था कि हर build में, यहाँ तक कि अलग-अलग machines पर भी, identical binary size मापना ज़्यादा आसान था। यह 100% सटीक नहीं था, लेकिन व्यवहार में मददगार साबित हुआ।
मैं भी इसी तरह की समस्या से जूझ रहा हूँ। कई बार देखा है कि CMake उन files को भी दोबारा compile कर देता है जिन्हें बदला ही नहीं गया। उदाहरण के लिए, interface में बदलाव किए बिना सिर्फ
.cppमें हल्का-सा edit करने पर भी पूरी तरह unrelated objects फिर से compile हो जाते हैं। कभी-कभी सोचता हूँ कि शायद CMake वास्तविक files की तुलना में dependencies को ज़रूरत से ज़्यादा सख़्ती से जोड़ देता है, और इसी वजह से build time बेवजह बढ़ता है।मैं blog लेखक को सुझाव दूँगा कि macOS app build को रिकॉर्ड करने वाली gif image को page के सबसे ऊपर, header के ठीक नीचे दिखाएँ। पहले बनाया गया नतीजा दिखाना और उसके बाद उसकी व्याख्या देना देखने में बेहतर flow बनाता है।
यह project मुझे बहुत पसंद आया। 2018 में मैंने strace और dtruss, https://buildinfer.loopperfect.com/ का उपयोग करके BUCK files auto-generate करने जैसी मिलती-जुलती कोशिश की थी। graphviz, perfetto.dev आदि से visualization भी किया था। अफ़सोस है कि इसे formal product के रूप में package नहीं कर पाया, लेकिन consulting में root-cause diagnosis और BUCK/Bazel migration में इससे बहुत मदद मिली। हाल में भी मैं इसे फिर देख रहा हूँ कि इसे और व्यापक रूप से कैसे लागू किया जाए। इस approach में कुछ मूलभूत technical challenges भी हैं: अगर syscall logs को disk पर लिखा जाए तो उनका आकार दर्जनों से सैकड़ों GB तक पहुँच जाता है (उदाहरण: llvm के लिए 50GB, कुछ मामलों में 100GB से ज़्यादा), और https, IPC जैसी build steps को भी सही तरह से handle करना पड़ता है। एक बार एक ग्राहक Perl से Firebird DB से code खींचकर हर build में compile करता था। साथ ही, runtime analysis होने की वजह से हर build configuration के लिए analysis दोहराना भी पड़ता है।
मुझे यह शानदार लगा। ऐसा महसूस हुआ कि इस तरह के visualization के बिना बहुत-सी समस्याएँ छूट जाती हैं। 10 साल पहले जब मैं Mozilla build system को optimize कर रहा था, तब ऐसा tool बहुत काम आता। लेख में यह थोड़ा और बताया जाता कि वास्तव में किन समस्याओं का पता चला, तो और अच्छा होता।
CMake से managed C++ project में build performance visualization के लिए मैंने ninjatracing और Clang के
-ftime-traceका सफलतापूर्वक उपयोग किया है। इसके अलावा ClangBuildAnalyzer से यह और बारीकी से समझा जा सकता है कि compiler अपना समय कहाँ खर्च कर रहा है।यह सच में बहुत अच्छा है। क्या इसे open source करने की कोई योजना है? मैं भी कुछ ऐसा ही बना रहा हूँ, इसलिए साथ काम करना चाहूँगा।
अगर आप Windows पर Visual C++ compiler इस्तेमाल करते हैं, तो vcperf भी recommend करूँगा। यह VS2022 में default रूप से शामिल है, या GitHub से खुद build करके उपयोग किया जा सकता है। मैंने इसे UBT या CMake से generated projects पर भी लागू किया है। यह build parallelization की गुणवत्ता सीधे दिखाता है या नहीं, यह याद नहीं, लेकिन compiler frontend की जानकारी आसानी से दिखा देता है। खासकर बार-बार include होने वाले या मूल रूप से भारी header files को ढूँढना आसान हो जाता है।
आम तौर पर इसे नज़रअंदाज़ किया जाता है, लेकिन एक अहम बात यह है कि build system में “baked in” build logic यह बारीकी से track नहीं करता कि वास्तव में कौन-सा बदलाव किस चीज़ को प्रभावित करता है। उदाहरण के लिए, ninja में कुछ build logic पहले से feed की हुई होती है, इसलिए वह तेज़ है। मैंने Xerces-C++ का full-build benchmark ninja (CMake configuration के साथ) और build2 (एक ऐसा tool जो configuration और change tracking को build का हिस्सा मानता है) पर किया था। ninja ने 3.23 सेकंड लिए, build2 ने 3.54 सेकंड। CMake द्वारा generated कुछ files को बनाए रखते हुए repeat build करने पर समय 3.28 सेकंड तक आ गया। संदर्भ के लिए, सिर्फ CMake का configuration phase 4.83 सेकंड लेता है। पूरे stack का CMake+ninja build वास्तव में लगभग 8 सेकंड लेता है, और आम तौर पर library के रूप में इस्तेमाल करते समय उपयोगकर्ता इसी समय का अनुभव करते हैं।
मैंने भी एक मिलती-जुलती कोशिश की थी, जिसमें build के दौरान Instruments चलाकर देखा जाता था कि कौन-सा process कब क्या कर रहा है। कमी यह थी कि अगर build लंबा चले तो Instruments lag करने लगता था। process tree filtering न होने से भी असुविधा होती थी, लेकिन Twitter के iOS code का build time काफ़ी घटाने में इससे बहुत मदद मिली। हाल में Instruments का “All Processes” tracing टूट गया है, इसलिए यह तरीका अब काम नहीं करता।
यह बहुत बढ़िया लग रहा है। क्या कोई macOS version है जिसे अभी तुरंत test किया जा सके? मैं इसे Rust या C++/Swift कामों में आज़माना चाहूँगा।
bug fixes के बाद अगला beta-test user batch आएगा तो macOS version वितरित करने की योजना है। (article के नीचे) आवेदन करते समय इस comment का ज़िक्र कर दें, तो मैं आपको beta group में ज़रूर शामिल करूँगा।
अभी तक लगता है कि किसी भी OS के लिए public release नहीं है, सिर्फ early access के लिए आवेदन संभव है।