Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Bir C# Satırı CPU'da Nasıl Çalışır: Kaynak Koddan IL'e, Assembly'den Instruction'a
Bir C# satırı CPU'ya iki çeviriyle ulaşır: Roslyn onu IL'e, JIT de çalışma anında o makinenin ISA'sına göre machine code'a çevirir; CPU bu byte'ları fetch-decode-execute döngüsüyle işler. TotalQuantity'nin 30 byte'lık x64 Tier-1 kodunu satır satır okuyor, ARM64 karşılığıyla, 789 byte'lık decimal versiyonuyla ve optimizasyonsuz Tier-0 ölçümüyle karşılaştırıyor, .NET 11'in x86-64-v2 tabanını anlatıyoruz.
CPU Pipeline ve Branch Prediction: Sıralı Array Neden Daha Hızlı İşlenir?
Sıralı array daha hızlı işlenir çünkü içindeki if'ler tahmin edilebilir hâle gelir ve CPU pipeline'ı boşaltmak zorunda kalmaz. Bir milyon siparişte 9,4 kat fark, JIT'in döngüde neden cmov üretmediği, bit mask ile branchless toplama, bağımlılık zinciri ve ILP, Spectre'nin neden var olduğu.
Memory Hierarchy: Register'dan SSD'ye Latency Rakamları ve Locality
Bellek tek parça değildir: register ve L1'den DRAM'e, SSD'ye ve network'e indikçe her katman büyür ve yavaşlar; bir DRAM okuması L1'den yaklaşık 90 kat uzun sürer. 256 MB'lık bir array'i karışık sırayla toplamanın 13,4 kat yavaşlaması, pointer chasing ile kendi makinende latency ölçmek, stack ile heap'in aynı RAM olması ve struct array'in List<Book>'tan 6 kat hızlı taraması.
CPU Cache Nasıl Çalışır: Cache Line, Associativity ve Cache-Friendly C# Kodu
CPU bellekten byte değil cache line okur (x64'te 64 byte) ve bir adresi tag, index ve offset'e bölüp tek bir set'te arar; kodun hızı bu düzene uyup uymamasına bağlıdır. 4096 × 4096 tabloyu sütun sütun gezmenin 6,5 kat yavaşlığı, genişliği 16 artırınca conflict miss'in kalkıp döngünün 4,6 kat hızlanması, Struct of Arrays ile 5 kat kazanç ve field sırasıyla 40 byte'tan 24 byte'a inen struct.
Multi-Core, Hyper-Threading ve False Sharing: Çekirdek Sayısı Neden Performansı Doğrusal Artırmaz?
Çekirdek sayısı performansı doğrusal artırmaz, çünkü core'lar cache line, bellek bant genişliği ve execution unit gibi kaynakları paylaşır. Dört worker'lık Bookstore sayacında paylaşılan Interlocked sayacın 15 kat yavaşlaması, yan yana slot'ların false sharing yüzünden tek thread'i geçememesi, padding ve local değişkenle düzeltme, Environment.ProcessorCount'un container limitine göre değişmesi ve Hyper-Threading ile P/E core'ların etkisi.
SIMD ve Vectorization: Vector128, Vector256, Vector512 ve TensorPrimitives ile Aynı Anda Çok Veri
SIMD, tek bir instruction ile geniş bir register'daki 4, 8 ya da 16 değeri aynı anda işlemektir; .NET'te bunu BCL, TensorPrimitives, Vector<T> ve Vector128/256/512 katmanlarıyla kullanırsın. Bir milyon int toplamda tek accumulator'lı vector döngüsü 2 kat, dört accumulator'lı olan 6,5 kat hızlı; x64 assembly'de vpaddd ymm/zmm, IsHardwareAccelerated'ın JIT sabiti olması ve double toplamın donanıma göre değişmesi.