Şöyle başlayayım: Yıllardır müşterilere “PGO’yu deneyin, performans açılıyor” diyorum, ama işin acı tarafı şu — çoğu ekip ya hiç dokunmuyor ya da yarıda bırakıyor. Sebebi de bence gayet net. Klasik PGO, kâğıt üstünde akıllıca duruyor; sahada işe biraz baş ağrısı yapıyor.
Geçen ay Logosoft’ta bir finans müşterisiyle düşük gecikmeli bir matching engine üstünde çalışıyorduk. C++ tarafında her mikrosaniye kıymetliydi, şaka değil. PGO konusunu açınca mimar arkadaşın yüz ifadesi değişti — “David, biz bunu 2021’de denedik, CI pipeline çöktü, training senaryolarını maintain edemedik, bıraktık” dedi. Tanıdık geldi mi? Bana fena hâlde tanıdık geldi.
İşte tam burada Microsoft’un yeni duyurduğu Sample Profile Guided Optimization (SPGO) devreye giriyor. Açık konuşayım: MSVC tarafında uzun zamandır “hadi artık” dediğim şeylerden biri bu (ki bu çoğu kişinin gözünden kaçıyor). Hani bazen bir özellik çıkar, “tamamdır” dersiniz ve geçersiniz ya, bu öyle değil. Bu daha çok, küçük gibi duran ama oyunun ritmini bozan cinsten.
Klasik PGO Neden Çoğu Ekipte Tutmadı?
Şunu söyleyeyim, Önce klasik PGO’yu bir dürtelim, çünkü SPGO’nün neden önemli olduğunu anlamak için o eski hikâyeyi bilmek lazım (inanın bana). Geleneksel PGO üç fazdan oluşuyor: instrument, train, optimize. Yani önce binary’nize probe ekliyorsunuz, sonra o yavaşlamış binary’yi temsili workload’larla koşturuyorsunuz, en sonda da toplanan veriye göre yeniden derliyorsunuz (kendi tecrübem)
Kulağa kötü gelmiyor. Ama sahada işler biraz dağılıyor (bizzat test ettim)
İşin garibi, Birinçisi, instrument edilmiş binary bariz yavaşlıyor. Bunu production’a atamazsınız; müşteri size çok net bakar. O yüzden üretim trafiğinden veri toplama işi çoğu zaman rafa kalkıyor. Yerine “temsili workload” üretmeniz gerekiyor (evet, doğru duydunuz). Burada da şu soru çıkıyor: Gerçek müşterinin davranışını sentetik olarak nasıl taklit edeceksiniz? Cevap genelde şu oluyor: pek taklit edemiyorsunuz.
İkincisi, training senaryoları zamanla bayatlıyor. Kod değişiyor, kullanım paterni değişiyor, ama siz hâlâ eski profile bakarak derleme yapıyorsunuz. Sonuç? Compiler bazen yanlış yere abanıyor — sıcak sandığı yer soğuk çıkıyor, soğuk sandığı yer de bir anda hot path oluyor.
Üçüncüsü de — bence en sınır bozucu tarafı — CI/CD karmaşası. Üç aşamalı build süreci kuracaksınız; hangi agent’ta training olacak, profile verisi nerede tutulacak, versiyonlama nasıl dönecek… 2019’da kendi sunucularımda test projesi için buna kalkışmıştım, üç gün sonra “yok artık” deyip kapattım. Üç gün! Sadece pipeline için.
PGO’nün en büyük derdi performans değil — operasyonel yük aslında. Teorik kazancı kimse tartışmıyor zaten. Tartışılan şey, o kazanca giderken ödediğiniz bedel.
SPGO Ne Yapıyor da Farklı Oluyor?
SPGO’nün fikri baya sade. Diyor ki: “Binary’yi instrument etmeyelim; üretimde çalışan release binary’den donanım sayaçlarıyla örnekleme yapalım.” Yani modern işlemcilerin sunduğu Last Branch Records (LBR) ve retired instruction counter gibi mekanizmaları kullanıyor.
Bu pratikte ne anlama geliyor? Şu anlama geliyor: Üretim trafiğinin gerçeğini ölçebiliyorsunuz. Sentetik senaryo yok, instrument overhead’i neredeyse yok denecek kadar az, release binary’nizi olduğu gibi çalıştırıyorsunuz.
Akış Nasıl İşliyor?
Eh, Kabaca akış şöyle gidiyor — lafı uzatmadan söyleyeyim:
- Release binary’nizi derliyorsunuz (debug bilgileriyle birlikte ama instrument etmeden).
- Bunu üretimde veya temsili ortamda çalıştırıyorsunuz, ETW (Event Tracing for Windows) ile donanım sayaçlarını topluyorsunuz.
- Toplanan ETW trace’ını SPGO formatına çeviriyorsunuz.
- Yeniden derleme sırasında compiler’a bu profil verisini veriyorsunuz.
Bitti gibi düşünün. Üç fazlı build pipeline yok, instrument edilmiş binary deploy etme derdi yok, training senaryosu uydurma baskısı yok.
Klasik PGO vs SPGO: Karşılaştırma
Bir şey dikkatimi çekti: Bunu tabloya dökeyim; gözle görmek daha rahat oluyor:
| Kriter | Klasik PGO (Instrumented) | SPGO (Sample-based) |
|---|---|---|
| Runtime overhead | Yüksek (%20-50+ yavaşlama) | İhmal edilebilir (<%1) |
| Üretime deploy | Mümkün değil | Mümkün |
| Training senaryosu | Sentetik üretmek lazım | Gerçek trafik kullanılır |
| CI/CD karmaşası | Yüksek (3 faz) | Düşük (profil opsiyonel) |
| Profil doğruluğu | Çok yüksek (exact counts) | Yüksek (statistical sampling) |
| Beklenen kazanım | %10-30 | %5-20 (workload’a göre) |
Dikkat edin: SPGO’da kazanım çoğu zaman klasik PGO kadar yüksek olmayabiliyor. Çünkü örnekleme istatistiksel gidiyor; exact count almıyorsunuz. Ama operasyonel maliyet öyle düşük ki trade-off baya mantıklı duruyor. %25 kazanım için üç ay pipeline ile boğuşmaktansa, bir günde %15 almak birçok ekip için daha cazip oluyor.
Peki Pratikte Nasıl Kullanılıyor?
Şahsen, Sıradaki kısım daha elle tutulur geliyor bana. Diyelim elinizde performans kilit bir C++ uygulaması var; SPGO’yu nasıl ekleyeceksiniz? Resmî tutorial uzun anlatıyor ama özünü vereyim:
# 1. Release build (debug info ile)
cl.exe /O2 /Zi /c myapp.cpp
link.exe /DEBUG /PROFILE myapp.obj
# 2. Üretimde ETW ile trace topla
wpr -start CPU -filemode
#... uygulama bir süre koşar...
wpr -stop trace.etl
# 3. Trace'i SPGO profiline dönüştür
spgo-converter trace.etl -o myapp.spgo
# 4. Profil ile yeniden derle
cl.exe /O2 /Zi /c /SPGO:myapp.spgo myapp.cpp
Komutlar birebir böyle olmayabilir — Microsoft dokümanında flag’lerin en güncel hâlini görürsünüz zaten —. Akış bu kadar basit sayılır. Karmaşık taraf beklediğimden az çıktı açıkçası.
/Zi‘yi kapatmayın; ayrı PDB üretin ve saklayın.
Nerede Daha Anlamlı Duruyor?
Eh, Burası biraz önemli aslında. Kurumsal tarafta gördüğüm kadarıyla Türkiye’de C++ yoğun kullanılan birkaç alan var: bankacılık (özellikle algoritmik trading. Risk hesaplama), telekom (network function işleri), savunma sanayi, oyun stüdyoları ve birkaç gömülü sistem firması. Bu alanların hepsinde performans ilk sırada geliyor. Daha fazla bilgi için Azure NetApp Files EDA İçin: Bulutta Çip Tasarımı Devri yazımıza bakabilirsiniz. Bu konuyla ilgili etcd 3.7.0-beta.0 Yayında: RangeStream ve v2store Vedası yazımıza da göz atmanızı tavsiye ederim.
Ama açık konuşayım — Türk yazılım ekiplerinin geneli compiler optimizasyonuna pek zaman ayırmıyor. “Donanımı büyütürüz, hallolur” yaklaşımı baya yaygın. Geçen sene bir telekom müşterisinde packet processing koduna baktığımızda -O2‘nın bile düzgün kurulmadığını gördük; PGO mu? Hak getireydi yani. Bu ekipler için SPGO bence güzel bir giriş kapısı oluyor; çünkü bariyer düşük kalıyor ve “bir deneyelim” demek için bahane azalıyor.
Ayrıca Azure’da C++ workload çalıştırıyorsanız — mesela HPC senaryolarında ya da Azure Batch üstünde compute-heavy işler koşuyorsanız — her %10 performans artışı doğrudan VM saatine yazılıyor. TL hesabıyla düşününce D-series VM’lerde aylık 5-6 bin liralık compute üzerinde %15 kazanım bile yıllık 10-12 bin TL civarı fark yaratabiliyor (ki bu çoğu kişinin gözünden kaçıyor). Bir kişinin yarım günlük emeğiyle bunu alabiliyorsanız ROI fena durmuyor. Bu konuyla ilgili Kubernetes v1.36 Server-Side Sharded Watch: Saha Notları yazımıza da göz atmanızı tavsiye ederim.
Küçük Ekip mi Büyük Kurum mu?
Bunu senaryoya göre ayırmak lazım; çünkü herkesin derdi aynı değil: Bu konuyla ilgili npm Staged Publishing GA: Tedarik Zinciri Artık Daha Güvenli yazımıza da göz atmanızı tavsiye ederim.
Küçük Ekipler / Startup’lar
Eğer 5-10 kişilik bir ekipseniz ve C++ uygulamanız varsa, bence direkt SPGO tarafına gidin. Klasik PGO’yu hayal bile etmeyin demem boşuna değil; sebebi şu: Küçük ekipte CI/CD’yi daha da karıştıracak nefes alanınız olmuyor çoğu zaman. SPGO ile profil opsiyonel hâle geliyor — profil yoksa normal release çıkıyor, profil varsa optimize edilmiş versiyon dönüyor. Bu esneklik küçük ekiplerde gerçekten iş görüyor.
Büyük Kurumsal Yapılar
Eğer 50+ developer olan bir yapıdaysanız ve zaten oturmuş bir CI/CD düzeniniz varsa ikisini birlikte düşünebilirsiniz. Kritik path’teki kütüphaneler için klasik PGO’yla daha yüksek kazanımı kovalamak mantıklı olabilir; genel uygulamada işe SPGO ile bakım kolaylığı sağlanabilir. Hibrit yaklaşım yani… Bir bankacılık projesinde buna benzer bir mimariyi tartışmıştık. Sonunda SPGO’da karar kılmıştık; çünkü operasyonel sadelik orada daha değerliydi.
Bunu biraz açayım.
Dikkat Edilmesi Gereken Noktalar Var mı?
Evet var tabii ki; her şey pembe değil yani mutlu son filmi çekmiyoruz burada:) SPGO yeni sayılır. Bazı pürüzleri bulunuyor. Benim denk geldiklerim şunlar oldu: Bu konuyla ilgili devri konusundaki yazımız yazımıza da göz atmanızı tavsiye ederim.
- Donanım bağımlılığı: LBR ve benzeri sayaçlar Intel ve AMD’nın yeni nesil işlemcilerinde var; eski donanımlarda örnekleme kalitesi düşebiliyor. (bu kritik)
- PDB yönetimi: Symbol management işini ciddiye almak gerekiyor çünkü PDB kaybolursa profil de işe yaramaz hâle geliyor.
- Sampling noise: Çok kısa trace’lerde istatistiksel gürültü kazanımı azaltabiliyor; en az birkaç dakikalık temsili trace toplamak daha iyi oluyor.
- Daha yeni bir teknoloji: İlk sürüm hissi var biraz; bazı edge case’lerde compiler beklenmedik kararlar verebiliyor ama production’a almadan önce A/B test yapmak iyi fikir ölür.
Zaten ben geçen haftalarda küçük bir image processing kütüphanesinde denedim bunu. İlk denemede profile converter aşamasında symbol resolution hatası aldım — meğer PDB path yanlışmış, ortam değişkeni eksikmiş falan… Çözüm \_NT_SYMBOL_PATH‘i düzgün kurmak oldu.. Dokümanda yazıyor aslında ama insan ilk seferde atlayabiliyor işte.. Sonra işler yağ gibi aktı diyebilirim; kütüphanenin sıcak yolunda yaklaşık %12 hızlanma gördüm ve şaşırdım açıkçası.. Bu ne anlama geliyor? Fena değil yani.
Peki Build Sistemine Nasıl Girer?
Eğer C++ tarafında modern paket yönetimini de düşünüyorsanız, C++ Projelerinde PackageReference: NuGet Yeni Dönem yazımdaki yaklaşımla SPGO’yu yan yana kurgulayabilirsiniz bazen NuGet üzerinden profil dosyalarını versiyonlamak ve ekipler arasında paylaşmak daha rahat hâle geliyor yani iş görüyor diyeyim.
İşte, bir şey dikkatimi çekti: Ayrıca Visual Studio 2026 ile gelen yeni planlama özelliklerini de kenara atmayın derim.
Visual Studio Plan Agent: Önce Düşün, Sonra Kodla
yazısında bahsettiğim agent yaklaşımı performans analizinde bile işinize yarayabilir — mesela “şu fonksiyonun hot path’ını analiz et” diyerek profil verisi üstünde sorgu yaptırabilirsiniz.
Neyse uzattım biraz ama bağlantı aslında net.
Ve işler burada ilginçleşiyor.
Siz Bugün Nereden Başlarsınız?
Denedirmek istiyorsanız ben olsam şu sırayla giderdim:
- Visual Studio 2022 veya 2026’nın güncel sürümünde olduğunuzdan emin olun.
- Küçük bir pilot proje seçin — production-critical olmasın ama temsili workload üretebileceğiniz bir şey olsun.
- \release build’i
/Zi\ ile derleyin ve PDB'leri saklayın.- WPR (Windows Performance Recorder) ile birkaç dakikalık trace toplayın.
- Microsoft'un tutorial'indaki converter komutunu çalıştırın.
- SPGO flag'iyle yeniden derleyin ve benchmark karşılaştırması yapın.
`}`
Sıkça Sorulan Sorular
SPGO ile klasik PGO arasındaki performans farkı ne kadar?
Aslında klasik PGO biraz daha iyi kazanım veriyor, hani exact execution count'lara bakıyor ya, ondan. Ama fark çoğu workload'da %3-5 falan. Buna karşın operasyonel maliyet farkı çok daha büyük — bence bu denklemi tamamen değiştiriyor. Siz hiç denediniz mi? Yani performans kritik kütüphane geliştiriyorsanız klasik PGO, genel uygulama geliştiriyorsanız SPGO çok daha mantıklı.
SPGO için ne tür donanım lazım?
Şöyle ki, Last Branch Records (LBR) desteği olan modern x86 işlemciler gerekiyor. Pratikte 2015 sonrası Intel Core ve son nesil AMD Ryzen'ler gayet iş görüyor. Sunucu tarafında Xeon ve EPYC ailesi de sorunsuz çalışıyor. Neden önemli bu? ARM tarafında ise açıkçası Windows'taki SPGO desteği henüz tam olgunlaşmış değil.
Profil verisini ne sıklıkla yenilemem gerekiyor?
Klasik PGO'ya kıyasla çok daha az. Üretimden sürekli veri akışı kurabilirseniz zaten her release döngüsünde otomatik güncellenip gidiyor. Manuel kurgu yapıyorsanız tecrübeme göre ayda bir yenilemek çoğu projeye yetiyor. Tabii kodda büyük bir refaktör yaptıysanız, hemen yenileyin — bekletmeyin.
Ve işler burada ilginçleşiyor.
SPGO açıkken debug deneyimim bozulur mu?
Bence, Hayır, hiç etkilenmiyor. SPGO yalnızca release build'i optimize ediyor. Geliştirme süreciniz aynı kalıyor, sadece release pipeline'ınıza ek bir adım giriyor. O adım da aslında opsiyonel — profil yoksa zaten standart release çıkıyor (bizzat test ettim)
Bu özellik hangi Visual Studio sürümlerinde var?
Garip gelecek ama, Microsoft'un duyurusuna göre Visual Studio 2022'nin büyük çoğunluk sürümlerinde ve Visual Studio 2026'da SPGO mevcut. Yani mesela Community sürümünde bile rahatlıkla deneyebilirsiniz, kurumsal lisans falan gerekmiyor.
Kaynaklar ve İleri Okuma
Introducing Sample Profile Guided Optimization in MSVC — Microsoft C++ Team Blog
Profile-Guided Optimizations — Microsoft Learn
Size bir şey söyleyeyim, Windows Performance Toolkit Dokümantasyonu (en azından benim deneyimim böyle)
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



