Frame pointer'ların geri dönüşü
(brendangregg.com)- Fedora ve Ubuntu 24.04 LTS, libc gibi OS bileşenlerini varsayılan olarak frame pointer'lar dahil edilerek derlenmiş hale geri döndürürken, Linux profiling ve Flame Graph'ların daha eksiksiz stack'ler görmesini sağlıyor
- Frame pointer'lar yoksa profiler, libc gibi kütüphane katmanlarında stack walking işlemini durdurabilir veya yanlış frame'leri izleyebilir; bu da CPU ve Off-CPU Flame Graph'ların bozulmasına yol açabilir
- gcc'nin 2004'te i386 için yaptığı değişiklik, bir register daha kazanma tercihiydi; ancak x86-64'e de yayılarak sistem profiler'ları ve eBPF tabanlı gözlemlenebilirlik için uzun vadeli bir maliyet bıraktı
- Netflix'in Java ve libc uygulama deneyiminde maliyet genelde %1'in altındaydı; bazı raporlarda %1~2, özel microbenchmark'larda veya sıra dışı workload'larda ise %10'a kadar çıktı
- LBR, DWARF, eBPF stack walker, ORC, SFrames, Shadow Stacks gibi alternatifler var; ancak bugün production'da performans iyileştirmeleri bulmanın en pratik yolu, frame pointer'ları varsayılan olarak etkinleştirmek
Flame Graph'lar neden bozulur?
- CPU Flame Graph, görünüşte normal olsa bile libc'nin frame pointer'sız derlendiği sistemlerde bazı örnekleri yanlış biçimde [unknown] altında toplayabilir
- Örnekte soldaki %15'lik örnekler yanlış konumdadır ve application frame'leri eksiktir
- profiler, kernel frame'lerini geçip syscall ve libc syscall wrapper'a ulaştıktan sonra bir sonraki frame'in sembol çözümlemesinde başarısız olur
- Bunun nedeni, derleyici optimizasyonuyla frame pointer register'ının stack frame için referans noktası olmak yerine veri depolamak için kullanılmasıdır
- profiler bunun sıradan bir sayı mı olduğunu bilemez ve bunu function address olarak yorumlamaya çalışır
- Değer bir sonraki frame'i göstermiyorsa stack walking durur
- Tesadüfen geçerli bir pointer gibi görünürse yanlış junk frame oluşabilir
- Değer kendisini gösteriyorsa perf'in azami frame sınırına ulaşana kadar bir junk frame yığını oluşabilir
- Off-CPU Flame Graph, libc read/write ve mutex function'ları sık göründüğü için frame pointer olmadığında daha ciddi biçimde bozulabilir
- Application'ın kendisi de frame pointer'sız derlendiyse, yalnızca kütüphaneler değil tüm stack trace de güvensiz hale gelir
Frame pointer'ların sağladığı bilgi
- x86-64 ABI,
%rbp'nin stack frame'in base pointer'ı, yani frame pointer olarak kullanılabileceğini tanımlar - Linux perf ve eBPF gibi harici profiler/debugger'lar bu bilgiyi kullanarak stack trace'leri yürür ve sonucu Flame Graph olarak görselleştirir
- x86-64 ABI içinde
%rbpkullanımının isteğe bağlı olduğuna dair bir dipnot bulunur- Stack frame'i
%rspile indekslemek, prologue ve epilogue içinde iki komutu azaltabilir %rbpek bir genel amaçlı register olarak kullanılabilir
- Stack frame'i
2004'te kaldırılması ve 20 yıllık etkisi
- 2004'te gcc, i386 backend'de varsayılan olarak
-fomit-frame-pointer -ffixed-ebpeşdeğeri davranışa geçecek şekilde değiştirildi - i386'da yalnızca 4 genel amaçlı register bulunduğundan,
%ebp'yi serbest bırakmak kullanılabilir register sayısını ciddi biçimde artırıyordu- Değişiklik gerekçeleri arasında Intel'in
iccderleyicisinden daha iyi performans elde etme isteği de vardı - O dönemde debugger'ların farklı stack walking tekniklerini desteklediği için bozulmayacağı düşünülüyordu
- Değişiklik gerekçeleri arasında Intel'in
- Bu değişiklik x86-64'e de uygulandı
- x86-64'te 12'den fazla register bulunduğu için, bir register daha kazanmanın faydası i386'daki kadar büyük değildi
- eBPF gibi günümüz sistem profiler'ları o zamanlar mevcut değildi ve bu değişiklik onların bazı durumlarda bozulmasına yol açıyor
- Eric Schrock, 2004'te amd64'te 17. genel amaçlı register'ı kazanmanın, debug edilebilirlik kaybına değecek kadar büyük bir avantaj olmadığını düşünüyordu
/usr/bin'i frame pointer'sız derlemeye başlarsanız bunun kontrolden çıkacağını söylemişti- Linux'ta bu eğilim yalnızca
/usr/binile sınırlı kalmayıp/usr/libve application code'a da yayıldı
Java, libc ve Netflix'teki uygulama deneyimi
- 2014'te Netflix'e katıldığında, Java'nın frame pointer desteği eksik olduğu için application stack'lerinin tamamı bozuk durumdaydı
- JVM c2 compiler için bir düzeltme geliştirildi ve Oracle bunu yeniden işleyerek JDK8u60'a
-XX:+PreserveFramePointerseçeneği olarak ekledi - Java tarafındaki değişiklikle application code içinde birçok performans iyileştirmesi bulunabildi; ancak libc hâlâ bazı CPU örneklerini ve Off-CPU Flame Graph'ların çoğunu bozuyordu
- Sonrasında production için frame pointer içeren özel bir libc derlendi ve Canonical ile birlikte Ubuntu için önceden derlenmiş libc üzerinde de çalışıldı
- Bir süre
libc6-profkullanımı önerildi libc6-prof, frame pointer içerenlibc6idi
- Bir süre
Performans overhead'i ve istisna durumları
- Production'a geçiş sürecinde libc ve Java'ya frame pointer eklemenin maliyeti genellikle %1'in altındaydı
- İstisna olarak %10 overhead görülen bir application vardı
- Groovy üzerinden 1000 frame'den uzun stack trace'ler üreten sıra dışı bir application'dı
- Linux perf de bunu işleyemediği için Red Hat'ten Arnaldo Carvalho de Melo, Netflix workload'u için
kernel.perf_event_max_stacksysctl'ini ekledi - Söz konusu ortam, düşük seviyeli donanım profiling özelliği olmayan bir sanal makineydi; bu yüzden %10'luk etkinin tamamının frame pointer'lardan kaynaklanıp kaynaklanmadığı doğrulanamadı
- Diğer raporlarda maliyet yaklaşık %1 veya %2 düzeyindeydi
- Microbenchmark'larda bozulma %10'a kadar çıkabiliyor
- Küçük function'lar döngü içinde tekrar tekrar çalıştırıldığında, ek komutlar L1 cache sıcaklığını veya cache line sınırlarını etkileyebilir
- Bu durumda aynı etkiyi frame pointer'dan bağımsız olarak hot function'a herhangi bir şey eklemek de yaratabilir
- Python
scimark_sparse_mat_multbenchmark'ı da %10'a ulaşabiliyordu- Andrii Nakryiko'nun analizine göre bu, büyük bir function içinde gcc'nin
%rspoffset'i yerine%rbprelative offset kullanıp daha fazla byte gerektirmesi nedeniyle oluşan özel bir durumdu - Sonrasında Python'ın varsayılan olarak frame pointer'ları yeniden etkinleştirebilmesi için düzeltme yapıldığı da bildirildi
- Andrii Nakryiko'nun analizine göre bu, büyük bir function içinde gcc'nin
- Frame pointer sayesinde bulunan performans iyileştirmeleri %5 ile %500 arasında değişiyordu; bu nedenle çoğu durumda %1'den düşük maliyetin makul olduğu düşünülüyor
- Eğer bir cihazda profiling veya debugging imkânı gerekmiyorsa frame pointer'sız derleme yapılabilir; ancak asıl hedef enterprise Linux ve backend server'lar
Fedora ve Ubuntu'da varsayılan etkinleştirme
- Meta, Google ve Netflix gibi büyük şirketler, profiling kabiliyeti elde etmek için zaten kendi frame pointer'lı libc sürümlerini kullanıyordu
- Fedora'da bunu upstream'e taşıma yönündeki ilk girişim uzun bir tartışmaya dönüştü
- Fedora tartışması 116 mesajlık bir başlığa dönüştü
- Katılımcılardan biri, Meta veya Netflix'in test, benchmark ve code size ölçümleri için side repository altyapısı sağlaması gerektiğini savundu
- Jonathan Corbet bunu Fedora's tempest in a stack frame yazısında özetledi
- Fedora daha sonra öneriyi yeniden değerlendirip kabul etti ve frame pointer'ları yeniden etkinleştiren ilk dağıtım oldu
- Ubuntu da Ubuntu 24.04 LTS'te varsayılan olarak frame pointer'lar duyurusunu yaptı
- Arch Linux'un da frame pointer etkinleştirme sürecinde olduğuna dair bilgi eklendi
- Bu değişiklik OS kütüphane stack walking'ini iyileştirir; ancak application runtime'ları için ayrıca ayar gerekebilir
- Java,
-XX:+PreserveFramePointerseçeneğini sunuyor - Go'da frame pointer desteği birkaç yıl önce varsayılan hale geldi
- Java,
Frame pointer sonrası stack walking adayları
- LBR(Last Branch Record): 16 veya 32 frame sınırına sahip Intel donanım özelliği; çoğu application stack'i için yetersiz olsa da, biraz stack bilgisi elde etmek için son çare olarak kullanılabilir
- BTS(Branch Trace Store): Intel özelliği; stack derinliği sınırı daha az sorun olsa da bellek load/store ve BTS buffer overflow interrupt işleme maliyeti vardır
- AET(Architectural Event Trace): JTAG tabanlı bir tracer; düşük seviyeli CPU, BIOS ve device event'lerini izleyebilir, ayrıca stack trace için de kullanılabilir gibi görünüyor, ancak doğrudan kullanım deneyimi yok
- DWARF: debugger'larda uzun süredir kullanılan bir binary debuginfo yöntemidir
- JIT runtime'larda JIT-to-DWARF çalışmaları olduğuna dikkat çekildi
- Yoğun production server'larda c2'nin sürekli çalıştığı Java JVM'ler için pratik olması beklenmiyor
- DWARF stack walking'in kendi maliyeti de yüksek
- eBPF stack walking: harici tracer, runtime desteği olmadan JVM gibi runtime'ların içini yürüyebilir
- Runtime içinden user space read ile çok fazla veri okumak gerekebileceği için overhead yüksek olabilir
- Runtime değişikliklerine hassastır; bu yüzden language code base ile birlikte dağıtılıp sürdürülmesi daha uygundur
- ORC(oops rewind capability): Linux kernel'in hafif stack unwinder'ı; yeni kernel'lerin frame pointer'ı kaldırırken stack walking'i koruyabilmesini sağlar
- SFrames(Stack Frames): ORC tabanlı hafif bir user stack unwinding yöntemi
- Shadow Stacks: Intel ve AMD'nin güvenlik özelliği; function return address'lerini ayrı bir donanım stack'ine push edip return anında doğrulayabilir ve stack trace için de kullanılabilir gibi görünüyor
Şu anda ne değişiyor?
- 2004'te frame pointer'ları atlama gerekçeleri olan i386 performans kazancı, dönemin debugger uyumluluğu değerlendirmesi ve
iccile rekabet, 2024 koşullarına artık uymuyor - x86-64'e uygulanan frame pointer kaldırma kararı, o dönemde bile debug edilebilirlik kaybına göre yeterli avantaj sağlamadığı yönünde değerlendirilmişti
- Fedora ve Ubuntu'nun frame pointer'ları geri getirmesiyle, 2024 sürümlerini kullananlar CPU Flame Graph'ları daha kolay anlayabilecek ve Off-CPU Flame Graph'lardan ilk kez gerçekten yararlanabilecek
- Continuous profiler'lar da müşterilerden OS değişikliği istemeden daha eksiksiz profiler elde etmeyi kolaylaştıracak
- Gelecekte SFrames veya Shadow Stacks gibi yöntemlerle yeniden frame pointer'sız stack trace mümkün olabilir; ancak bugün yapılabilecek en somut iyileştirme, frame pointer'ları varsayılan olarak açmak
1 yorum
Hacker News yorumları
2000’lerin başında stack frame pointer’ı atlama uygulamasının yaygınlaşmaya başladığı zamanı hatırlıyorum
O dönemde yoksul bir üçüncü dünya ülkesindeki bir üniversitede bilgisayar bilimi okuyordum ve eski, yavaş bilgisayarlar yüzünden ödevlerin çoğunda interpreter yerine compiler kullanıyorduk
Düşük seviyeli veri yapıları, compiler’lar, assembly sayısal rutinleri, Minix aygıt sürücüleri gibi şeyleri implemente ettiğimiz çok ilginç dersler vardı ve bir program garip davranınca gdb’ye bağlanıp assembly seviyesinde doğrudan stack’i takip ederek debug ediyorduk
Ama birden
-fomit-frame-pointermoda olunca stack trace almak anlamsız hale gelmeye başladı ve segfault ya da illegal instruction debug etmek çok daha zorlaştıSonunda bozuk debug oturumlarından kaçınmak için neredeyse her şeyde Python kullanmaya başladım; performansta bir iki basamak kaybettim ama Python öğrenmiş olmam sonradan işime yaradı
-fno-omit-frame-pointerseçeneğini bilmiyor muydun diye merak ettimFedora’nın anılmasına sevindim. Dağıtımın tamamında frame pointer’ı açık tutmak epey yorucu bir mücadeleydi
Örn: https://pagure.io/fesco/issue/3084
Frame pointer ek yükünün büyük olduğu efsanesi hâlâ sürüyor; bunun nedeni bir Python örneğinde +%10 yavaşlama görülmesiydi ve bu artık düzeltildi
Gerçekte ölçülen ek yük %1’in altında ve belirli uygulamalarda elde edilen fayda çok daha büyük
Linux kernel tarafındaki ölçümlerle de pek uyuşmuyor; orada bunun %5–10 aralığında olduğunu görmüştüm: https://lore.kernel.org/lkml/20170602104048.jkkzssljsompjdwy...
netperf, page allocator microbenchmark’ları, pgbench, sqlite gibi çeşitli iş yüklerinde frame pointer açıkken %5–10 ek yük görüldü ve PostgreSQL ile SQLite üzerinde etkisinin görülmüş olması önemli
DBMS, sistemi ciddi biçimde zorlamanın iyi yollarından biridir
OCaml 5, OCaml kodu ile C kodu için ayrı stack’ler kullanıyor ve GDB bunları DWARF bilgisiyle birleştirebiliyor, ama perf’in DWARF call graph özelliği bunu yapamıyor: https://github.com/ocaml/ocaml/issues/12563#issuecomment-193...
Gelecek sürümlerde de frame pointer’ı korumak için gerekçe lazımsa, OCaml 5 iyi bir örnek olabilir
Fedora 39’da frame pointer’ın zaten varsayılan olarak açıldığını şimdi öğrenmiş oldum; ben ise günlük profiling işlerinde hâlâ çoğunlukla
perf record --call-graph dwarf -F 47 -akullanan, CentOS 7 benzeri sistemlerde çalışıyordumFrame pointer’ın kaldırılmasının nedeni bir efsane değil, 64 bit öncesi dönemin gerçekleriydi ve bu da o kadar eski bir mesele sayılmaz
Bugün bile eski 64 bit sistemlere yeni bir hayat vermeye çalışıyorsanız bu tür optimizasyonlar anlamlı olabilir
İdeal olarak güvenlik açısından kritik sistemlerde de varsayılan olmalı, ama her şeyin “gözlemlenebilirlik” için optimize edilmesi gerekmiyor
Apple’ın ARM tarafında doğru yaptığı şeylerden biri, x29 frame pointer’ın her zaman geçerli bir frame record’a işaret etmesini sağlaması
leaf function ya da tail call gibi bazı fonksiyonlar listede bir kayıt oluşturmayabilir, ama bunun sonucu olarak debug bilgisi olmasa bile stack trace her zaman anlamlı kalıyor
https://developer.apple.com/documentation/xcode/writing-arm6...
2005’te Google’da karşı taraftaydım ve o zamanki düşünce basitti
$BIG_COMPANYher şeyi frame pointer ile derlemeye karar verse bile, topluluğun geri kalanı bunu yapmayacağı için çok daha büyük bir toplulukla kazanılamayacak bir tartışmayı sürdürmüş oluyorsunuz diye düşünüyordumSonuçta bu tartışma neredeyse 20 yıllık bir tartışmaya dönüştü ve sonrasında gperftools içinde libunwind’i çalıştırmak için patch yazarken kendimi birkaç yıl boyunca libunwind’i maintain ederken buldum
Şimdi başka bir bilişim alanına geçtim ve daha pasif bir gözlemciyim, ama tarihe karşı taraftan bakarak okumak ilginç geliyor
Eğer
RBPçerçeve işaretçisi olarak ayrılacaksa, iki ayrı stack kullanmak da mümkünBiri
RBPtarafından işaret edilip etkin frame’leri tutar, diğeriRSPtarafından işaret edilip yalnızca dönüş adreslerini tutarBöylece çağrı stack’i kelimenin tam anlamıyla dönüş adreslerinden oluşan düz bir dizi olur ve artık “stack yürümek” gerekmez
Zaten dönüş adreslerini yerel değişkenlerin yakınına kaydetmenin neden gerekli olduğunu bilmiyorum; çok fazla dezavantajı var gibi görünüyor
Önerdiğiniz yaklaşımda iki guard page gerekir, stack işlemleri iki katına çıkar ve cache miss olasılığı da iki katına çıkar
Sebebini biliyorum ama birçok şey gibi bu da en son yaklaşık 30 yıl önce anlamlıydı ve etkileri ilginç oldu
İlginç biçimde Wikipedia’daki yazı, Forth’un hem parametre stack’ine hem de dönüş stack’ine erişebilmesini modelin önemli bir özelliği olarak pek vurgulamıyor gibi görünüyor
https://en.wikipedia.org/wiki/Forth_(programming_language)
Ayrı bir sayfaya taşımak ve iki işaretçi yönetmek için ödenecek bedelin, zaten gereken noktalarda koruma sağlayan stack cookie/protector yaklaşımından gerçekten daha ucuz olduğunu göstermek gerekir
Mevcut stack protector’lara göre de somut bir güvenlik avantajı yok. Rastgele okuma/yazma mümkünse, sonuçta bu yine kontrol akışı bütünlüğünü aşmaya kadar gidebilir
Virgil frame pointer kullanmıyor. Dinamik stack tahsisi yoksa, belirli bir fonksiyonun frame boyutu sabittir ve basit bir ikili arama tablosu sorgusuyla bulunabilir
Virgil’in tekniği buna ek olarak sayfa indeksi tabanlı aralıklar kullanarak sorguyu ortalama birkaç karşılaştırmaya indiriyor; unwind bilgisini GC için stackmap ile birleştiriyor ve çok az yer kaplıyor
Ana kod https://github.com/titzer/virgil/blob/master/rt/native/Nativ... adresinde, aynı dizindeki diğer kodlar ise metadata çözümlemeyi gerçekleştiriyor
Frame pointer ancak frame boyutu dinamik olduğunda, yani stack üzerinde veri tahsis edildiğinde anlamlı
Statik mekanizma yeterliyken dinamik mekanizma kullanmak tuhaf; bunun başlıca sebebi muhtemelen metadata kodlama ABI’si ya da unwind rutinleri üzerinde ortak bir uzlaşının olmaması
%1–2 ölçümü makul görünüyor; dizi sınır denetimi maliyetiyle benzer düzeyde
Hata ayıklama ve profilleme için %1 maliyete özel muamele yapıp güvenlik katmanı eklemeye direnmek, öncelikler açısından çok garip
C++’ta
std::vectorvarsayılan olarak sınır denetimini kapatır; bence bunun nedeni C++’ın tamamen çılgın insanlar tarafından ve onlar için tasarlanmış olmasıBunun dışında sınır denetimi olmayan başka bir dil hemen aklıma gelmiyor
Güzel yazı. Frame pointer ortadan kaybolduğunda üzülmüştüm
Linux dahil olmak üzere pek çok kişi, farklı sistemlerde frame pointer yokluğu yüzünden uzun süre sıkıntı çekti ve bunu olabildiğince çok ortamda korumaya çalıştı
Ana akım Linux’un bunu geri getirdiğini görmek bir yandan doğrulanmış gibi hissettiriyor ama bir yandan da biraz sinir bozucu
Debian türevlerinde yavaş olmasının nedeni, lisans gerekçeleriyle perf için yalnızca yavaş unwind yolunun paketlenmesi; araçlar düzgün olduğunda farkı neredeyse hiç hissetmiyorum
Acaba benim gözden kaçırdığım şey ne?
Genel olarak frame pointer lehindeyim, ancak bu alanda birkaç yıl çalışınca fark ettiğim bazı noktalar var
Frame pointer tabanlı stack unwind yöntemlerinin çoğu, DWARF unwind bilgisinde olmayan sorunları hesaba katmıyor. Frame kurulumu atomik değil;
push $rbpvemov $rsp $rbpolmak üzere iki komuttan oluşuyor ve snapshotpushsırasında alınırsa üst çerçeve kaçırılabilirKod incelenerek bunun etkisi azaltılabilir belki, ancak stack frame ile ilgisiz
push %rbpkullanımları da olabileceğinden bu daha çok sezgisel bir yaklaşım gibi görünüyorBrendan’ın sözünü ettiği BPF tabanlı hızlı çekirdek içi unwind çözümünü de geliştirdim: https://web.archive.org/web/20231222054207/https://www.polar...
Bu yaklaşım, DWARF CFI’yi doğrudan kullanmak yerine onu BPF içinde kullanılabilecek rastgele erişimli bir biçime dönüştürüyor
Şu anda yalnızca frame pointer içeren JIT bölümlerini destekliyor, ancak JVM yorumlayıcı unwind’ini native unwind ile iç içe çalışacak şekilde uygulamanın mümkün olduğunu düşünüyorum
İdeal olarak frame pointer etkinleştirme kullanım senaryosuna göre yapılmalı ve burada benchmarking kritik önemde
Sektöre ve yazılımın niteliğine göre performans, gözlemlenebilirlik ve iş metrikleri arasındaki ödünleşim büyük ölçüde değişebilir
Fedora tarafı burada son derece iyi ve titiz bir iş çıkarmış
Ayrıca bağımlı kütüphaneler de dahil olmak üzere tüm sistem genelinde bu ayarı değiştirebilen bir build sistemi, yalnızca test için değil üretim ortamında kullanım için de çok faydalı
Son olarak, Indu’nun üzerinde çalıştığı SFrame umut verici görünüyor. Kullanıcının frame pointer kullanıp kullanmamayı seçmesine imkân verirken mevcut sorunların çoğunu çözebilir gibi duruyor, ancak altyapının hazır olması ve herkesin yükseltme yapması birkaç yıl alabilir
Gerçekte neler olduğunu anlamak için sistem genelinde analiz gerekli ve Fedora ya da Debian gibi bugünkü ikili Linux dağıtımı yapısında başka bir seçenek pratikte mümkün değil
ENTER N,0, yerel değişkenler için N kadar stack alanı ayırır ve kabacaPUSH EBP,MOV ESP,ESP,SUB SP,Nile aynıdırYalnız
ENTERkomutunun x86-64’te olup olmadığını hatırlamıyorumYine de
CALLile frame kurulumu arasında atomik değildir; snapshotCALLsonrasında amaENTERöncesinde alınırsa frame kurulumu elde edilemezENTERkomutunun yaygın kullanılmamasının nedeni çok yavaş olduğunun düşünülmesidirLEAVE, yerine geçen komut dizisi kadar hızlı ya da daha hızlı olduğu için kullanılır, amaENTERikinci operand yüzünden performansı bozarBu operand, iç içe fonksiyonların üst stack frame’lerine erişmesi içindir ve kullanım maliyeti çok yüksektir
Profillerde görünen
[unknown]dağlarının neden oluştuğunu nihayet anlamış oldum; ilginçYine de bunu gerekçelendirmek kolay değil. %2 performans farkı aslında oldukça büyük bir fark
Frame pointer eklenmesini daha ince ayrıntıyla kontrol etmek güzel olurdu
Ayrıntılı profiling varsa, belirli fonksiyonların ya da derleme birimlerinin frame pointer’a ihtiyaç duyup duymadığı değerlendirilebilir
Frame pointer eklenince dramatik biçimde yavaşlayan iş yüklerinin azınlıkta olduğu ve geri kalanının neredeyse etkilenmediği sonucuna şaşırmam
__attribute__((optimize("no-omit-frame-pointer")))__attribute__((optimize("omit-frame-pointer")))Bu tür benchmark’lar biraz yapaydır; bu yüzden tamamen güvenmemek gerekir ve gerçek uygulamalarda sonuçlar çoğu zaman ciddi biçimde farklı olur
Profiling önemlidir; kodu dikkatle profile ederek çeşitli bölümleri %20’ye kadar hızlandırdığım oldu
Performans kaybına çok duyarlı bir uygulamanız varsa, laboratuvarda frame pointer’ları açıp profiling yapabilir, müşteriye dağıttığınız sürümde ise kapatabilirsiniz
JIT kod desteği ne yazık ki iyi değil, ancak LLVM’de üretilen her metodun ve adresinin kaydedilmesini sağlayan mükemmel bir hook var
Bu yüzden basit bir karma mod stack unwind çözümünü nispeten kolay kurabilirsiniz, ama çoğunlukla süreç içinde mümkündür
Intel’in DNN tarafı bilgileri perf’in okuyabildiği ortak bir dosyaya döküyor gibi görünüyor, ancak oneDNN çekirdeklerinin kendisi RBP’yi sürekli yeniden kullandığı için pratikte pek işe yaramıyor
Yazıdaki “Java JVM gibi JIT runtime’larda DWARF bilgisi yoktur” iddiası da şaşırtıcı
Bunun varsayılan olarak kapalı mı olduğunu, yoksa gerçekten kullanılamaz durumda mı olduğunu merak ediyorum
Aratınca konu genelde JVM stack’ine JNI/C tarafını da dahil etme isteğine çıkıyor: https://github.com/async-profiler/async-profiler/issues/215