फ्रेम पॉइंटर की वापसी
(brendangregg.com)- Fedora और Ubuntu 24.04 LTS ने libc जैसे OS components को default रूप से frame pointers के साथ build करने की ओर वापस लौटाया है, जिससे Linux profiling और Flame Graph अब ज़्यादा complete stacks देख सकते हैं
- Frame pointer न होने पर profiler libc जैसी library layers में stack walking रोक सकता है या गलत frames follow कर सकता है, जिससे CPU और Off-CPU Flame Graph टूट सकते हैं
- 2004 में gcc का i386 change एक extra register हासिल करने का decision था, लेकिन यह x86-64 तक फैल गया और system profilers व eBPF-based observability पर लंबे समय की cost छोड़ गया
- Netflix के Java और libc adoption experience में cost आम तौर पर 1% से कम थी; कुछ reports में 1~2%, और खास microbenchmarks या abnormal workloads में 10% तक दिखी
- LBR, DWARF, eBPF stack walker, ORC, SFrames, Shadow Stacks जैसे alternatives हैं, लेकिन production में अभी performance improvements खोजने का सबसे practical तरीका frame pointers को default रूप से enable करना है
Flame Graph टूटने की वजह
- CPU Flame Graph ऊपर से normal दिख सकता है, लेकिन जिन systems में libc frame pointers के बिना compile हुई है, वहाँ कुछ samples गलत तरह से [unknown] के ऊपर जमा हो सकते हैं
- उदाहरण में बाईं ओर के 15% samples गलत जगह पर हैं और application frames missing हैं
- profiler kernel frames पार करके syscall और libc syscall wrapper तक पहुँचने के बाद अगले frame symbol को resolve करने में fail हो जाता है
- कारण यह है कि compiler optimization की वजह से frame pointer register stack frame के reference point के बजाय data storage के लिए इस्तेमाल होता है
- profiler यह नहीं जान सकता कि वह value सिर्फ एक number है, इसलिए उसे function address की तरह interpret करने की कोशिश करता है
- अगर value अगले frame की ओर point नहीं करती, तो stack walking रुक जाती है
- अगर संयोग से वह valid pointer जैसी दिखे, तो गलत junk frame बन सकता है
- अगर value खुद की ओर point करती है, तो perf की maximum frame limit तक junk frame tower बन सकता है
- Off-CPU Flame Graph में libc read/write और mutex functions बहुत आ सकते हैं, इसलिए frame pointers न होने पर यह ज़्यादा बुरी तरह टूटता है
- अगर application खुद भी frame pointers के बिना build है, तो सिर्फ libraries नहीं बल्कि पूरा stack trace अस्थिर हो जाता है
Frame pointer क्या जानकारी देता है
- x86-64 ABI define करता है कि
%rbpको stack frame के base pointer, यानी frame pointer के रूप में इस्तेमाल किया जा सकता है - Linux perf और eBPF जैसे external profilers/debuggers इस जानकारी का इस्तेमाल करके stack trace walk करते हैं और result को Flame Graph में visualize करते हैं
- x86-64 ABI में एक footnote है कि
%rbpका use optional है%rspसे stack frame को index करने पर prologue और epilogue में दो instructions कम की जा सकती हैं%rbpको extra general-purpose register के रूप में इस्तेमाल किया जा सकता है
2004 में हटाना और 20 साल का असर
- 2004 में gcc को i386 backend में default रूप से
-fomit-frame-pointer -ffixed-ebpके बराबर behavior करने के लिए बदला गया - i386 में केवल 4 general-purpose registers थे, इसलिए
%ebpको free करने से available registers काफी बढ़ जाते थे- change के reasons में Intel के
icccompiler से बेहतर performance पाने की इच्छा भी शामिल थी - उस समय यह भी माना गया कि debugger दूसरी stack walking techniques support करता है, इसलिए यह टूटेगा नहीं
- change के reasons में Intel के
- यह change x86-64 पर भी लागू हुआ
- x86-64 में 12 से अधिक registers हैं, इसलिए एक extra register पाने का benefit i386 जितना बड़ा नहीं है
- eBPF जैसे आज के system profilers तब मौजूद नहीं थे, और इस change से वे कुछ cases में टूट जाते हैं
- Eric Schrock ने 2004 में माना कि amd64 में 17वाँ general-purpose register पाने का benefit debugging capability के loss की तुलना में पर्याप्त नहीं था
- उन्होंने कहा था कि अगर
/usr/binको frame pointers के बिना compile करना शुरू किया गया तो चीजें control से बाहर हो जाएँगी - Linux में यही trend सिर्फ
/usr/binतक नहीं, बल्कि/usr/libऔर application code तक फैल गया
- उन्होंने कहा था कि अगर
Java, libc और Netflix में adoption experience
- 2014 में Netflix join करने के समय Java में frame pointer support की कमी के कारण application stacks पूरी तरह टूटे हुए थे
- JVM c2 compiler के लिए fix बनाया गया, और Oracle ने उसे rework करके JDK8u60 में
-XX:+PreserveFramePointeroption के रूप में जोड़ा - Java change से application code में कई performance improvements खोजी जा सकीं, लेकिन libc अब भी कुछ CPU samples और अधिकतर Off-CPU Flame Graphs को तोड़ रही थी
- बाद में production के लिए frame pointers वाली libc खुद compile की गई, और Canonical के साथ Ubuntu के लिए pre-built libc पर भी काम किया गया
- कुछ समय तक
libc6-profuse करने की सिफारिश की गई libc6-prof, frame pointers वालीlibc6थी
- कुछ समय तक
Performance overhead और exceptional cases
- Production adoption के दौरान libc और Java में frame pointers जोड़ने की cost आम तौर पर 1% से कम थी
- एक exception में 10% overhead वाला application था
- यह एक अजीब application था जो Groovy के जरिए 1000 से अधिक frames वाले stack traces generate करता था
- Linux perf भी इसे handle नहीं कर पाया, इसलिए Red Hat के Arnaldo Carvalho de Melo ने Netflix workload के लिए
kernel.perf_event_max_stacksysctl जोड़ा - वह environment low-level hardware profiling features के बिना virtual machine था, इसलिए यह confirm नहीं किया जा सका कि 10% overhead पूरी तरह frame pointers की वजह से था या नहीं
- दूसरी reports में लगभग 1% या 2% cost भी दिखी
- Microbenchmarks में performance 10% तक खराब हो सकती है
- loop में छोटी functions को बार-बार execute करते समय extra instructions L1 cache warmth या cache line boundaries को प्रभावित कर सकती हैं
- इस case में frame pointer खुद नहीं, बल्कि hot function में कुछ भी add करने से वैसा ही effect हो सकता है
- Python
scimark_sparse_mat_multbenchmark भी 10% तक पहुँच सकता था- Andrii Nakryiko के analysis में यह एक special case था, जहाँ बड़े function में gcc ने
%rspoffset के बजाय%rbprelative offset use किया, जिसके लिए ज्यादा bytes चाहिए थे और performance problem बनी - बाद में यह खबर भी आई कि Python में frame pointers को default रूप से फिर enable करने लायक fix हो गया
- Andrii Nakryiko के analysis में यह एक special case था, जहाँ बड़े function में gcc ने
- Frame pointers की मदद से मिली performance improvements 5% से 500% तक थीं, और आम तौर पर 1% से कम cost को justify किया जा सकता है
- अगर किसी device में profiling या debugging की संभावना नहीं है, तो frame pointers के बिना compile किया जा सकता है, लेकिन मुख्य target enterprise Linux और backend servers हैं
Fedora और Ubuntu में default enablement
- Meta, Google, Netflix जैसी बड़ी companies पहले से ही frame pointers वाली libc अपने स्तर पर use करके profiling capability हासिल कर रही थीं
- Fedora में default enablement को upstream करने की पहली कोशिश लंबी बहस में बदल गई
- Fedora discussion 116 posts वाली thread बन गई
- एक participant ने मांग की कि Meta या Netflix testing, benchmarking और code size measurement के लिए side repository infrastructure provide करें
- Jonathan Corbet ने इसे Fedora's tempest in a stack frame में summarize किया
- Fedora ने बाद में proposal पर दोबारा विचार कर उसे accept किया, और frame pointers को फिर enable करने वाला पहला distribution बना
- Ubuntu ने भी Ubuntu 24.04 LTS में frame pointers by default announce किया
- यह खबर भी जुड़ी कि Arch Linux भी frame pointers enable करने की प्रक्रिया में है
- OS library stack walking इस change से improve होती है, लेकिन application runtime के लिए अलग settings की जरूरत हो सकती है
- Java
-XX:+PreserveFramePointeroption provide करता है - Go में frame pointer support कुछ साल पहले default बन गया
- Java
Frame pointers के बाद stack walking के candidates
- LBR(Last Branch Record): Intel hardware feature है, जिसमें 16 या 32 frame limit होती है, इसलिए ज्यादातर application stacks के लिए insufficient है, लेकिन कुछ stack information पाने के last resort के रूप में use किया जा सकता है
- BTS(Branch Trace Store): Intel feature है, जिसमें stack depth limit कम समस्या है, लेकिन memory load/store और BTS buffer overflow interrupt handling की cost होती है
- AET(Architectural Event Trace): JTAG-based tracer है, जो low-level CPU, BIOS, device events trace कर सकता है और stack trace के लिए भी use किया जा सकता है लगता है, लेकिन इसे directly use करने का experience नहीं है
- DWARF: debugger में लंबे समय से use होने वाला binary debuginfo तरीका है
- यह point किया गया था कि JIT runtimes में JIT-to-DWARF work हुआ था
- busy production server पर लगातार c2 चलाने वाले Java JVM के लिए इसे practical होने की उम्मीद नहीं है
- DWARF stack walking की cost भी ज्यादा है
- eBPF stack walking: external tracer runtime support के बिना JVM जैसे runtimes के अंदर walk कर सकता है
- runtime internals को user space read से बहुत पढ़ना पड़ सकता है, इसलिए overhead ज्यादा हो सकता है
- यह runtime changes के प्रति fragile है, इसलिए language code base के साथ distribute और maintain किया जाना अधिक उचित है
- ORC(oops rewind capability): Linux kernel का lightweight stack unwinder है, जो नए kernel को frame pointers हटाते हुए भी stack walking बनाए रखने देता है
- SFrames(Stack Frames): ORC-based lightweight user stack unwinding method है
- Shadow Stacks: Intel और AMD का security feature है, जो function return address को अलग hardware stack में push करके return के समय verify कर सकता है, और stack trace में भी उपयोगी हो सकता है
अभी तुरंत क्या बदलता है
- 2004 में frame pointer omission के reasons—i386 performance benefit, उस समय की debugger compatibility assessment, और
iccसे competition—2024 की situation से मेल नहीं खाते - x86-64 पर लागू frame pointer removal के बारे में तब भी assessment था कि debugging capability के loss की तुलना में benefit पर्याप्त नहीं है
- Fedora और Ubuntu के frame pointers वापस लाने से 2024 releases इस्तेमाल करने वालों के लिए CPU Flame Graphs समझना आसान होगा और Off-CPU Flame Graphs पहली बार ठीक से इस्तेमाल किए जा सकेंगे
- Continuous profilers भी customers से OS change मांगने के बिना अधिक complete profiles पा सकेंगे
- भविष्य में SFrames या Shadow Stacks जैसे methods से शायद फिर frame pointers के बिना stack traces हो पाएँ, लेकिन अभी उपलब्ध improvement frame pointers को default रूप से enable करना है
1 टिप्पणियां
Hacker News की टिप्पणियाँ
मुझे 2000 के दशक की शुरुआत याद है, जब stack frame pointer omission फैलना शुरू हुआ था
उस समय मैं एक गरीब तीसरी दुनिया के देश की यूनिवर्सिटी में computer science पढ़ रहा था, और पुराने, धीमे कंप्यूटरों की वजह से ज़्यादातर असाइनमेंट्स में interpreter की बजाय compiler इस्तेमाल करता था
low-level data structures, compiler, assembly numeric routines, और Minix device driver तक implement कराने वाली कई दिलचस्प classes थीं, और जब प्रोग्राम अजीब तरह से काम करता था तो मैं gdb लगाकर assembly स्तर पर सीधे stack को follow करते हुए debug करता था
लेकिन फिर अचानक
-fomit-frame-pointerलोकप्रिय हो गया और stack trace का कोई मतलब ही नहीं रह गया, और segfault या illegal instruction को debug करना बहुत ज़्यादा मुश्किल हो गयाआखिरकार टूटी हुई debugging sessions से बचने के लिए मैंने लगभग हर काम में Python इस्तेमाल करना शुरू कर दिया, और भले ही performance में एक-दो अंकों का नुकसान हुआ, Python सीखना बाद में काम आया
-fno-omit-frame-pointerके बारे में पता नहीं थाFedora का ज़िक्र देखकर अच्छा लगा. पूरी distribution में frame pointer चालू रखे रखना काफ़ी थका देने वाली लड़ाई थी
उदाहरण: https://pagure.io/fesco/issue/3084
frame pointer overhead के बड़ा होने वाला मिथक अब भी बना हुआ है, और इसकी वजह Python के एक case में +10% slowdown था, जिसे अब ठीक किया जा चुका है
वास्तव में मापा गया overhead 1% से कम है, और कुछ applications में मिलने वाले फ़ायदे इससे कहीं ज़्यादा हैं
यह Linux kernel पक्ष के measurements से भी अच्छी तरह मेल नहीं खाता, जहाँ मैंने 5~10% रेंज देखी थी: https://lore.kernel.org/lkml/20170602104048.jkkzssljsompjdwy...
netperf, page allocator microbenchmark, pgbench, और sqlite जैसे अलग-अलग workloads में frame pointer चालू करने पर 5~10% overhead आया, और PostgreSQL व SQLite पर असर दिखना महत्वपूर्ण है
DBMS सिस्टम पर कड़ा दबाव डालने के अच्छे तरीकों में से एक है
OCaml 5, OCaml code और C code के लिए अलग-अलग stack इस्तेमाल करता है, और GDB, DWARF जानकारी से दोनों को जोड़ सकता है, लेकिन perf का DWARF call graph ऐसा नहीं कर सकता: https://github.com/ocaml/ocaml/issues/12563#issuecomment-193...
अगर आने वाले releases में भी frame pointer बनाए रखने के समर्थन में तर्क चाहिए, तो OCaml 5 एक उदाहरण हो सकता है
मुझे अभी पता चला कि Fedora 39 में default रूप से frame pointer पहले ही चालू है, और मैं आम तौर पर profiling अभी भी ऐसे systems पर कर रहा था जो CentOS 7 जैसे हैं, जहाँ
perf record --call-graph dwarf -F 47 -aइस्तेमाल होता हैframe pointer हटाने की वजह कोई मिथक नहीं थी, बल्कि pre-64-bit दौर की वास्तविकता थी, और यह इतना पुराना मामला भी नहीं है
आज भी पुराने 64-bit systems में नई जान डालनी हो तो ऐसी optimizations मायने रखती हैं
आदर्श रूप से security-critical systems में भी यह default होना चाहिए, और हर चीज़ को “observability” के लिए optimize करने की ज़रूरत नहीं है
Apple ने ARM पर एक काम बहुत अच्छा किया, वह यह कि x29 frame pointer हमेशा एक वैध frame record की ओर इशारा करे
leaf functions या tail call जैसे कुछ functions सूची में entry न बनाएँ, ऐसा हो सकता है, लेकिन नतीजा यह है कि debug information न होने पर भी stack trace हमेशा अर्थपूर्ण रहता है
https://developer.apple.com/documentation/xcode/writing-arm6...
2005 में मैं Google में दूसरी तरफ़ की स्थिति में था, और उस समय सोच सीधी थी
अगर
$BIG_COMPANYसब कुछ frame pointer के साथ compile करने का फ़ैसला भी कर ले, तब भी बाकी community ऐसा नहीं करेगी, इसलिए हमें कहीं बड़ी community के साथ एक ऐसी बहस लगातार लड़नी पड़ेगी जिसे जीता नहीं जा सकतानतीजे में वह बहस लगभग 20 साल लंबी बहस बन गई, और बाद में gperftools में libunwind को काम कराने के लिए patches लिखते-लिखते मैं कई साल तक libunwind maintain भी करता रहा
अब मैं computing के दूसरे क्षेत्र में चला गया हूँ और बस एक passive observer हूँ, लेकिन दूसरी तरफ़ के नज़रिए से इस इतिहास को पढ़ना दिलचस्प है
अगर RBP को frame pointer के रूप में देना ही है, तो दो stacks रखना भी संभव है
एक को RBP point करे और वह activation frames store करे, और दूसरे को RSP point करे और वह सिर्फ return addresses store करे
तब call stack सचमुच return addresses की एक flat array बन जाएगी, इसलिए “stack को walk” करने की भी ज़रूरत नहीं रहेगी
वैसे भी समझ नहीं आता कि return address को local variables के पास store करने की वजह क्या है, और इसके नुकसान बहुत ज़्यादा लगते हैं
प्रस्तावित तरीके में दो guard pages चाहिए, stack manipulation भी दोगुना हो जाता है, और cache miss की संभावना भी दोगुनी हो जाती है
कारण पता है, लेकिन कई चीज़ों की तरह यह शायद करीब 30 साल पहले आख़िरी बार वाजिब लगा होगा, और उसका असर दिलचस्प था
अजीब बात है कि Wikipedia का लेख इस बात को model की बड़ी खासियत के रूप में ठीक से सामने नहीं लाता कि Forth parameter stack और return stack दोनों को access कर सकता है
https://en.wikipedia.org/wiki/Forth_(programming_language)
यह दिखाना होगा कि अलग page पर ले जाकर दो pointers manage करने की लागत, सिर्फ वहीं protection देने वाले stack cookies/protectors से वास्तव में कम है जहाँ उनकी ज़रूरत पहले से है
मौजूदा stack protector की तुलना में कोई ठोस security लाभ भी नहीं है। अगर arbitrary read/write संभव है, तो अंततः control flow integrity को bypass किया जा सकता है
Virgil frame pointer का इस्तेमाल नहीं करता। अगर dynamic stack allocation नहीं है, तो किसी खास function का frame size fixed होता है और उसे एक साधारण binary search table lookup से पाया जा सकता है
Virgil की तकनीक page index-आधारित ranges का अतिरिक्त उपयोग करती है, जिससे औसतन सिर्फ कुछ comparisons में lookup को सीमित किया जा सकता है, और यह unwind info तथा GC के लिए stackmap को जोड़कर बहुत कम space इस्तेमाल करती है
मुख्य code https://github.com/titzer/virgil/blob/master/rt/native/Nativ... में है, और उसी directory का बाकी code metadata decoding implement करता है
frame size तभी मायने में dynamic होता है जब stack पर data allocate किया जाता है; यानी सिर्फ उसी स्थिति में frame pointer को अर्थपूर्ण माना जा सकता है
static mechanism काफ़ी है, फिर भी dynamic mechanism का इस्तेमाल होना अजीब है; शायद ऐसा इसलिए है क्योंकि metadata encoding ABI या unwind routines पर सहमति नहीं है
1~2% का measurement भरोसेमंद लगता है, और array bounds check की लागत के लगभग बराबर है
debugging और profiling के लिए 1% cost को खास अहमियत देना, लेकिन security layer जोड़ने पर हिचकिचाना, प्राथमिकताओं के लिहाज़ से बहुत अजीब है
C++ में
std::vectordefault रूप से bounds checks बंद रखता है, और मेरा मानना है कि ऐसा इसलिए है क्योंकि C++ को पूरी तरह पागल लोगों ने, और उन्हीं के लिए, डिज़ाइन किया हैइसके अलावा तुरंत कोई और ऐसी भाषा याद नहीं आती जिसमें bounds checks न हों
अच्छा लेख है। जब frame pointer गायब हुआ था, तब उसकी कमी महसूस हुई थी
दूसरे systems की तरह Linux में भी बहुत से लोग frame pointers की अनुपस्थिति की वजह से लंबे समय तक परेशान रहे, और वे इसे जितने ज़्यादा environments में संभव हो बनाए रखने की कोशिश करते रहे
mainstream Linux को इसे वापस लाते देखना एक तरह से मान्यता मिलने जैसा है, लेकिन साथ ही थोड़ा झुंझलाहट भरा भी
Debian परिवार में जो धीमापन है, वह license कारणों से है क्योंकि perf के साथ सिर्फ धीमा unwind path package किया जाता है; अगर tools ठीक हों तो फ़र्क़ शायद ही महसूस होता है
समझना चाहता हूँ कि मैं क्या मिस कर रहा हूँ
कुल मिलाकर मैं frame pointers के पक्ष में हूँ, लेकिन इस क्षेत्र में कुछ साल काम करते हुए एक बात महसूस हुई है
frame pointer-आधारित कई stack unwinding तरीके उन समस्याओं को ध्यान में नहीं रखते जो DWARF unwind जानकारी में नहीं होतीं। frame setup atomic नहीं होता और
push $rbpतथाmov $rsp $rbpजैसी दो instructions से बनता है, इसलिए अगर snapshotpushके दौरान लिया जाए तो parent frame छूट सकता हैहो सकता है code की जाँच करके इसे कम किया जा सके, लेकिन stack frame से असंबंधित
push %rbpभी हो सकते हैं, इसलिए यह heuristic के काफ़ी करीब लगता हैBrendan ने जिस BPF-आधारित तेज़ in-kernel unwinding समाधान का ज़िक्र किया, उसे भी विकसित किया गया है: https://web.archive.org/web/20231222054207/https://www.polar...
यह तरीका DWARF CFI को ज्यों का त्यों इस्तेमाल नहीं करता, बल्कि उसे BPF में उपयोग योग्य random-access format में बदल देता है
अभी यह सिर्फ frame pointer वाले JIT sections को support करता है, लेकिन JVM interpreter unwinding को native unwinding के साथ जोड़कर लागू करना संभव लगता है
आदर्श रूप से frame pointers को case-by-case आधार पर enable किया जाना चाहिए, और benchmarking सबसे अहम है
उद्योग और software की प्रकृति के अनुसार performance, observability और business metrics के बीच trade-off काफ़ी अलग हो सकता है
Fedora टीम ने यहाँ बहुत उत्कृष्ट और कठोर काम किया है
साथ ही, ऐसी build system जो dependencies सहित पूरे system में इस setting को बदल सके, वह सिर्फ testing ही नहीं बल्कि production rollout के लिए भी बहुत उपयोगी है
आखिर में, Indu जिस SFrame पर काम कर रहे हैं, उससे उम्मीद है। यह users को frame pointers के उपयोग का विकल्प देते हुए मौजूदा समस्याओं का बड़ा हिस्सा हल कर सकता है, लेकिन infrastructure तैयार होने और सबके upgrade करने में कुछ साल लग सकते हैं
वास्तव में क्या हो रहा है यह समझने के लिए system-wide analysis ज़रूरी है, और Fedora या Debian जैसी मौजूदा binary Linux distribution संरचना में कोई दूसरा विकल्प व्यावहारिक रूप से संभव नहीं है
ENTER N,0local variables के लिए N जितनी stack space reserve करता है और लगभगPUSH EBP,MOV ESP,ESP,SUB SP,Nके बराबर हैहालाँकि याद नहीं कि
ENTERx86-64 में है या नहींफिर भी
CALLऔर frame setup के बीच यह atomic नहीं है, इसलिए अगर snapshotCALLके बाद औरENTERसे पहले लिया जाए तो frame setup नहीं मिलेगाENTERका कम इस्तेमाल होने का कारण यह है कि इसे बहुत धीमा माना गयाLEAVEका उपयोग होता है क्योंकि यह उसे replace करने वाली instruction sequence जितना तेज़ या उससे तेज़ है, लेकिनENTERमें दूसरी operand performance खराब कर देती हैवह operand nested functions को ऊपरी stack frames तक पहुँच देने के लिए है, और इसकी लागत बहुत ज़्यादा है
अब समझ आया कि profile में दिखने वाले
[unknown]के पहाड़ क्यों बनते हैं, यह दिलचस्प हैलेकिन इसे सही ठहराना आसान नहीं है। 2% performance difference वास्तव में काफ़ी बड़ा अंतर है
अच्छा होगा अगर frame pointers को शामिल करने पर ज़्यादा बारीक control हो सके
अगर fine-grained profiling हो, तो शायद यह तय किया जा सके कि किन specific functions या compilation units में frame pointers ज़रूरी हैं
अगर यह नतीजा निकले कि frame pointers शामिल करने से नाटकीय रूप से धीमे होने वाले काम बहुत कम हैं और बाकी पर लगभग असर नहीं पड़ता, तो मुझे आश्चर्य नहीं होगा
__attribute__((optimize("no-omit-frame-pointer")))__attribute__((optimize("omit-frame-pointer")))ऐसे benchmarks कुछ हद तक कृत्रिम होते हैं, इसलिए उन पर पूरी तरह भरोसा नहीं करना चाहिए, और real-world applications में नतीजे अक्सर बहुत अलग होते हैं
profiling महत्वपूर्ण है, और code की सावधानी से profiling करके मैंने कई हिस्सों को 20% तक तेज़ बनाया है
अगर application performance loss के प्रति बहुत संवेदनशील है, तो lab में frame pointers enable करके profiling करें, और customers को भेजे जाने वाले version में उन्हें omit कर दें
अफ़सोस की बात है कि JIT code support अच्छा नहीं है, लेकिन LLVM में एक बेहतरीन hook है जो generated प्रत्येक method और address को रिकॉर्ड करता है
इसलिए एक साधारण mixed-mode stack unwinding बनाना तुलनात्मक रूप से आसान है, लेकिन ज़्यादातर यह process के अंदर ही संभव होता है
Intel की DNN श्रृंखला शायद जानकारी को ऐसे public file में dump करती है जिसे perf पढ़ सकता है, लेकिन oneDNN के kernels खुद RBP को लगातार reuse करते हैं, इसलिए यह लगभग बेकार हो जाता है
लेख में यह दावा कि “Java JVM जैसे JIT runtimes में DWARF जानकारी नहीं होती” भी चौंकाने वाला है
समझ नहीं आता कि यह default रूप से disabled है, या सचमुच इस्तेमाल ही नहीं की जा सकती
खोजने पर ज़्यादातर चर्चा इस पर जाती दिखती है कि लोग JVM stack में JNI/C पक्ष को भी शामिल करना चाहते हैं: https://github.com/async-profiler/async-profiler/issues/215