1 puan yazan GN⁺ 2025-05-11 | 1 yorum | WhatsApp'ta paylaş
  • En yeni Sep 0.10.0 sürümü, AMD 9950X üzerinde 21 GB/s gibi dikkat çekici bir CSV ayrıştırma hızına ulaşıyor
  • AVX-512 desteği ve maske yazmacı sorunlarının aşılmasıyla performans önemli ölçüde arttı
  • Yeni AVX-512-to-256 ayrıştırıcısı, AVX2 ve mevcut AVX-512 ayrıştırıcılarını geride bırakan sonuçlar gösteriyor
  • Çok iş parçacıklı ortamda 1 milyon satırı 72 ms'de işleyerek 8 GB/s bant genişliği kaydediyor
  • Sürekli yazılım ve donanım optimizasyonu sayesinde 2 yılda yaklaşık 3 kat performans artışı sağlandı

Sep 0.10.0 sürümü ve performans artışına genel bakış

  • Sep, yakın zamanda çıkan 0.10.0 sürümünde AVX-512 destekli CPU'lar (ör. AMD 9950X, Zen 5) için optimizasyon yaptı ve benchmark sonuçlarını güncelledi
  • En son sürümde düşük seviyeli CSV ayrıştırmada 21 GB/s gibi olağanüstü bir sonuç elde edildi
  • Bu, önceki sürümdeki 18 GB/s seviyesine kıyasla kayda değer bir artış anlamına geliyor
  • İyileştirmelerin ayrıntıları Sep'in GitHub sürüm notlarında ve README dosyasında görülebilir
  • Metin, .NET 9.0'ın AVX-512 makine kodundaki verimsizlikleri aşan SIMD tabanlı C# kodunu ve x64 SIMD assembly ile performansın nasıl artırıldığını açıklıyor

Sep'in performans gelişim süreci

  • Sep'in ilk 0.1.0 sürümünden 0.10.0'a, .NET 7.0'dan 9.0'a ve AMD 5950X (Zen 3)'ten 9950X (Zen 5)'e uzanan gelişim görsel olarak gösteriliyor
  • Benchmark'lar tek iş parçacığı bazında yapılıyor ve sürümler arasında küçük dalgalanmalar olabiliyor
  • Temel mesaj, büyük refactor'ların (0.2.0'daki iç yapı yeniden yazımı gibi) ve küçük değişikliklerin birikimli optimizasyonlarla sürekli performans artışı sağlaması
  • Donanım ve yazılımın birlikte gelişmesiyle ortalama 2 yıl içinde yaklaşık 3 kat iyileşmeyle 21 GB/s ayrıştırma hızına ulaşıldı
  • Sadece donanım nesli değişimi bile (5950X→9950X, 4.9→5.7GHz) 1.2x'in üzerinde bir artışı açıklıyor

AVX-512 kod üretimi ve maske yazmacı sorunu

  • Sep, 0.2.3'ten beri AVX-512 desteği sunuyordu ancak AVX-512'nin maske yazmaçlarını (k1-k8) kullanmada sınırlamalar vardı
  • .NET 8'de maske yazmaçlarına doğrudan destek olmadığından, normal yazmaçlar arasında tekrarlanan kopyalama ve dönüştürmeler performansı düşürüyordu
  • Ayrı bir AVX-512 destekli CPU bulunmayan ilk dönemde, Xeon Silver 4316 üzerinde sınırlı testler yapılarak bunun en hızlı seçenek olduğu doğrulandı

9950X yükseltmesi ve AVX-512 ile AVX2 karşılaştırması

  • Yakın zamanda CPU Zen 3 (5950X)'ten Zen 5 (9950X)'e yükseltildiğinde, Sep benchmark'ları 18 GB/s seviyesine ulaştı
  • AVX-512 ve AVX2 ayrıştırıcıları doğrudan karşılaştırıldığında, biraz şaşırtıcı biçimde AVX2'nin yaklaşık 20 GB/s ile AVX-512'den yaklaşık %10 daha hızlı olduğu görüldü
  • Bu durum, .NET JIT'in maske yazmacı işleme verimsizliğinin hâlâ sorun olduğunu düşündürüyor

Ayrıştırıcı kodu, assembly analizi ve yeni AVX-512-to-256 ayrıştırıcısı

  • Sep'teki tüm ayrıştırıcılar 16K boyutlu char span'leri işler ve SIMD yazmaçlarına (Vector256 vb.) dayalı karşılaştırma işlemlerini kullanır
  • SIMD ile özel karakterler (satır sonu, tırnak işareti, ayırıcı vb.) hızlıca belirlenir, ardından bit maskelerine dönüştürülerek küme işlemleri optimize edilir
  • AVX-512 tabanlı ayrıştırıcı, maske yazmaçları (k1 vb.) ile genel yazmaçlar (zmm vb.) arasında sürekli taşıma yaptığı için fazla ek iş üretmekteydi
  • 0.10.0'da MoveMask çağrısı öne alınarak gereksiz maske dönüşümleri en aza indirildi ve assembly komut sayısı azaltıldı
  • AVX2 ayrıştırıcısında maske yazmacı olmadığı için yapı çok daha basit kaldı ve pratikte AVX-512'den daha hızlı oldu
  • Yeni AVX-512-to-256 ayrıştırıcısı, veriyi AVX-512 ile okuyup 256 bit dönüşüm komutlarıyla maske işleme sorununu doğrudan by-pass ediyor; uygulama daha sade hale gelirken performans 21 GB/s'nin üzerine çıktı

Farklı ayrıştırıcı benchmark'larının özeti

  • Ortam değişkeniyle tüm ayrıştırıcı türleri karşılaştırıldığında, AVX-512-to-256 ayrıştırıcısı 21.5 GB/s ile en hızlı sonuç verdi
  • AVX2 tabanlı ve Vector256 tabanlı ayrıştırıcılar da yalnızca %5 içinde kalarak çok yakın performans gösterdi
  • Vector128 ve Vector512 tabanlı ayrıştırıcılar AVX2'ye göre %5-10 daha yavaştı; özellikle Vector512, Vector128'den bile yavaştı
  • IndexOfAny ayrıştırıcısı diğer SIMD ayrıştırıcılarına göre belirgin biçimde daha yavaştı. Vector64 ise 9950X üzerinde hızlandırılmadığı için çok düşük performans gösterdi
  • AVX-512 ve AVX2 tabanlı SIMD ayrıştırıcıları, benzer CSV ayrıştırıcılara kıyasla ezici bir performans ortaya koyuyor

Üst seviye benchmark: 5950X ve 9950X karşılaştırması

  • 1 milyon paket varlığı satırı temel alındığında Sep_MT, 9950X üzerinde 72 ms (8GB/s), 5950X üzerinde ise 119 ms (4.9GB/s) değerlerine ulaştı
  • Gerçek yük verilerinde de (float vb.) 9950X üzerinde çok iş parçacıklı olarak ~8GB/s bant genişliği elde edildi
  • Nesil değişimiyle (5950X→9950X) gerçek uygulama ayrıştırmasında yaklaşık 1.5-1.6 kat iyileşme görüldü
  • Rakip CSV kütüphanelerine (Sylvan, ReadLine, CsvHelper vb.) kıyasla çok daha yüksek throughput ve çok daha düşük kaynak tahsisi sergilendi

Sonuç ve özet

  • Sep 0.10.0, yazılım optimizasyonu ile en yeni donanım özelliklerini (AVX-512, yüksek saat hızı) birleştirerek CSV ayrıştırma performans sınırlarını zorluyor
  • Modern SIMD algoritma tasarımı, .NET JIT kodu ve assembly yapısındaki iyileştirmeler bu ilerlemenin merkezinde yer alıyor
  • Kısa süre içinde görülen birikimli performans iyileşmesi ve mimari nesil değişiminin etkisi dikkat çekici
  • Sep, CSV ayrıştırma alanında fiilen sektörün en üst düzeyinde yüksek performans, çoklu platform ve ölçeklenebilirlik sunuyor

1 yorum

 
GN⁺ 2025-05-11
Hacker News yorumları
  • Intel'in tüketici ürünlerinde AVX-512 desteği için yıllarca çip alanına kadar yatırım yapmasına rağmen, kütüphaneler bunu giderek daha fazla kullanmaya tam başlamışken AVX-512'yi tüketici SKU'larından kaldırmış olması gerçekten çok saçma. AMD'nin AVX-512 desteği daha iyi olduğu için değil, Intel kendi yaptığı yatırımı kendi eliyle çöpe attığı için AMD'nin tüketici CPU'larında AVX-512'nin yer alması gibi ironik bir akış ortaya çıktı.
    • Intel sürekli aynı kalıbı tekrarlıyor: bir teknoloji pazarı kuruyor (Optane), sonra da aniden çekilip giderek tüketicileri şaşkına çeviriyor (Depth Cameras). Yeni teknolojiye bir anda yüklenip beklediği benimsenme olmazsa hemen bırakıyor. Optane desteği Linux çekirdeğinde nihayet olgunlaşmaya başlarken fişi çekildi. Garip maliyet düşürme stratejileri de var. Tarihe biraz gidince Intel iAPX 432 döneminden beri aynı hataları tekrarladığını görüyorsunuz.
    • Bu yazıda AMD CPU üzerinde şu hızlar görülüyor: orijinal: 18GB/s, AVX2: 20GB/s, AVX512: 21GB/s. Yani AVX-512'nin AVX2'ye göre neredeyse hiçbir avantajı yok. Intel'in tüketici CPU'ları E-core'larda da AVX2 destekliyor. Benchmark tek iş parçacıklı. Intel daha fazla çekirdek için çipten AVX-512'yi çıkardı ve sonuçta en üst seviye model 24 çekirdeğe çıktı; AMD ise 16 çekirdekte kaldı. AVX2→AVX512 farkı çok küçük olduğundan çok iş parçacıklı senaryolarda daha fazla çekirdeği olan taraf kazanabilir. Gerçek dünyadaki iş yüklerinin çoğunda AVX-512 yerine çekirdek sayısındaki artışın faydası daha büyük. Çok özel bazı işler dışında Intel'in kararı makuldü diye düşünüyorum.
    • Yakında AVX-10 geliyor ve AVX-512 ile neredeyse aynı özelliklere sahip olması bekleniyor (farkın ne olduğunu ben de bilmiyorum).
    • Bu yazıdaki en ilginç nokta, AMD 9950X üzerinde AVX2 ayrıştırıcısının AVX-512 tabanlı ayrıştırıcıdan yaklaşık %10 daha hızlı olmasıydı (20GB/s'ye karşı 21GB/s). Sonuç olarak AVX-512'nin gerçek tüketici için pek de büyük bir faydası yok gibi görünüyor. CSV ayrıştırma 20GB/s olsa zaten şikayet etmem. Sadece assembly meraklıları destek durumuna takılıyor.
    • Intel'in bu kadar aptalca davranıyor olması gerçekten akıl almaz.
    • Teselli olacaksa, Sep mümkün olduğunda ekstra ayar gerektirmeden AVX-512 kullanıyor. JIT çalışma zamanında iyi çalışıyor, bu yüzden farkında olmadan en düşük performans tabanını hedefleseniz bile kaybınız olmuyor.
    • Intel'in yazılım desteği de pek iyi değil. Dizüstü bilgisayarımdaki iGPU da aslında epey iyi ama PyTorch gibi araçlarda doğru düzgün desteklenmediği için yazık oluyor. llama.cpp ve Vulkan ile çıkarım güzel çalışıyor; keşke diğer yazılımlar da bu şekilde destek verse.
  • Karakter başına dört karşılaştırma ('\n', '\r', ';', '“') ve ardından üç or işlemi yapmak yerine, yaygın bir numarayla 1 kez shuffle, 1 kez karşılaştırma ve 0 or işlemi yapılabilir. Bu numarayı anlattığım bir blog yazım var, bakabilirsiniz. Bu arada bu yazıda da vpternlogd ve vpor işlemleriyle or sayısı azaltılmış.
  • Intel'in tüketici CPU'larına yavaş çekirdek koymak zorundaymış gibi davranması ve "multi-pumping" gibi şeyleri düşünmeden AVX-512'yi toptan kaldırması çirkin görünüyor.
    • Bu tercihin ana nedeni 10nm süreç sorunlarıydı. Verim düşüktü ve maliyet çok yüksekti; bu yüzden çipi mümkün olduğunca bölüp Atom türevi çekirdekler / düşük güç pazarlamasıyla gelir elde etmeye çalıştılar. Üst seviye ürünlerde ise boyutu büyütüp marjı düşürerek sunucu/bulut pazarını korumaya uğraştılar. Sonunda kârlılık yine düştü ve pazar payı da kaybedildi ama en azından denediler.
  • Sep'in çıkışından (Haziran 2023) bu yana 2 yılda yaklaşık 3 kat hızlanma olduğu iddiası, donanım sıçraması da hesaba katılınca tartışmalı.
    • Aynı donanımda yazılımın (0.9.0 ve 0.10.0) iyileşmesi %17. 0.9.0'daki 13088'e %17 eklenince 15375 ediyor; bunu 0.1.0'daki 7335 ile karşılaştırınca yaklaşık 2,1 kat iyileşme çıkıyor.
    • Aynı donanım üzerinde sep'in önceki sürümüne göre 3GB/s artış olduğu söyleniyor; gerçek hızlar ve donanım bilgileri de şeffaf biçimde yazılmış.
    • Artık Moore yasası gibi dönemler geride kaldığı için sadece donanımla 3x hız artışı beklemek zor. Bu kadarı bile günümüz için yeterince etkileyici bir sonuç bence.
    • Donanım sıçramasını hesaba katmadan 3 kat iyileşme var demek elbette tartışmaya açık, ama yine de yıllara göre yazılımın gerçek performansına bakmanın ilginç bir yolu.
    • Benchmark grafiği CPU nesillerinde tam 4 kuşak atlayıp bir anda "büyük performans artışı" varmış gibi gösteriyor, o yüzden çok güven vermiyor.
  • Arthur Whitney'nin bu sonuçtan etkilenip bunu tek satırlık kodla geçmesini ya da shakti motoru güncellemesiyle yine tek satırda rekor kırmasını, belki de bir haber güncellemesi gelmesini bekliyorum; ilerlemeyi görmek güzel olur.
  • Birinin on milyon satırlık CSV'yi bu hızda işlemek zorunda olduğunu düşünmek bile ürkütücü.
    • Ben de bunu yaşadım. Başta veri az olduğu için CSV seçiliyor; geliştirici olmayanlar, özellikle Excel'i iyi kullanan kişiler için okunması kolay oluyor, loglar ve süreçler de CSV ile temiz görünüyor. Ama veri miktarı 10x, 100x büyüyünce milyarlarca satırlık CSV'yi optimize edip hızlı ingest etmek fiilen ihtiyaç haline geliyor. Böyle optimizasyonlar, iç süreçleri zaman içinde daha uygun formatlara taşımak için size zaman kazandırıyor.
    • CSV kurum içinde de düşünüldüğünden daha yaygın bir format ve sıkıştırılması da kolay (deflate). Bir zamanlar CSV'yi NIC kartı hızında Netflow verisi kusan bir kodla uğraşmıştım. Kişisel olarak bu kadar karmaşık iş yapılacaksa protocol buffers kullanmak daha mantıklı diye düşünüyorum. protobuf o kadar da zor bir format değil ama bir türlü yeterince benimsenmiyor.
    • 21GB/s seviyesinde işlenen CSV'nin çıktısının bir yere kaydedilmesi fikri daha da korkutucu geliyor. Ne kadar faydalı özetleme yapılırsa yapılsın, bu hızda veri sonuçta bir yerde birikmek zorunda; insan merak ediyor.
    • Tüm kusurlarına rağmen CSV'nin hâlâ en yaygın veri alışverişi formatı olduğunu düşünüyorum.
    • Finans dünyasında CSV herkesle paylaşılabilir ve metin tabanlı olduğu için neredeyse her yere koyup işleyebilirsiniz.
    • Yıl sonunda muhasebe departmanının gönderdiği cartesian product dosyaları buna örnek olabilir.
    • Ben de gerçekten bu tür eski usul CSV'lerle uğraşmak zorunda kaldığım için acısını biliyorum.
    • Neredeyse her durumda HDF5, CSV'den daha iyi. Buna rağmen başka açıklama olarak ancak cehalet, tembellik ya da "çalışıyor işte" yaklaşımı kalıyor.
  • Assembly kodu göreceğimi sanarak geldim ama C# çıkınca hem şaşırdım hem etkilendim; harika bir sonuç.
    • Modern .NET, SIMD ve vektör intrinsics'lerini en derin entegre eden "yüksek seviyeli dillerden" biri. Microsoft'tan Tanner Gooding bu alanda çok ilerleme sağladı; ilgili blog yazıları da çok iyi.
  • Yazıda 21GB/s kodunun tam olarak ne yaptığı net tanımlanmadığı için kafa karıştırıcı. Örneğin ayrıştırılan formatın tam olarak ne olduğu (CSV'de tırnak işleme gibi ayrıntılar) ve ayrıştırma sonrası sonucun nasıl kullanıldığı (örneğin bir veri yapısına mı yazıldığı) belirsiz.
    • Yazıdaki hesaplanan ns/row değeri yaklaşık 27ns/row (saniyede 37.000 row civarı) ama eğer hız 21GB/s ise satır başına yaklaşık 570KB düşüyor; bu yüzden benchmark çok sıra dışı görünüyor.
  • Benim deneyimimde özel SIMD koduyla, modern derleyicilerin otomatik vektörleştirmesine kıyasla büyük kazanç elde etmek zor oldu; özellikle de zaten vektör dostu kodda. Ama JSON ayrıştırma gibi bazı özel durumlar biraz farklı.
  • Kısa süre önce 300GB'lık bir CSV çıktısıyla çalıştım; düzenleme, işleme ve bütünlük doğrulaması için çok fazla zaman harcandığı için böyle hızlı bir CSV ayrıştırıcısına gerçekten ihtiyaç var.
    • Kayan noktalı veriyi saklamak için neden özel bir format kullanılmadığını anlamıyorum; HDF5 çok daha iyi bir alternatif.