- Sep 0.10.0, AMD 9950X (Zen 5) gibi AVX-512 destekli CPU optimizasyonlarıyla düşük seviyeli CSV ayrıştırmada 21 GB/s’ye ulaşarak önceki yaklaşık 18 GB/s seviyesini aştı
- Performans artışı, .NET 9.0’ın AVX-512 kod üretiminde oluşan maske register gidiş-dönüşü darboğazını azaltacak şekilde ayrıştırıcı yapısının değiştirilmesinden geliyor
- Yeni AVX-512-to-256 ayrıştırıcı,
charverilerini 512 bit olarak yükleyip ardından 256 bit bayt vektörüne dönüştürerek maske işleme ve ayrı permütasyon maliyetinden kaçınıyor - Sep’in düşük seviyeli ayrıştırma performansı, 2023’te 0.1.0 sürümünde 5950X/.NET 7.0 ile yaklaşık 7 GB/s iken, 0.10.0’da 9950X/.NET 9.0 ile yaklaşık 21 GB/s’ye çıkarak yaklaşık 3 kat iyileşti
- Üst seviye benchmark’larda da 9950X çok iş parçacıklı Sep, 1 milyon satırlık package assets verisini 72.213 ms’de, yaklaşık 8.0 GB/s hızla işledi; floats verisinde de yaklaşık 8.1 GB/s kaydetti
Sep 0.10.0’ın hedefi ve sonuçları
- Sep 0.10.0, 22 Nisan 2025’te yayımlandı ve AMD 9950X (Zen 5) gibi AVX-512 destekli CPU optimizasyonları ile 9950X benchmark’larını içeriyor
- Düşük seviyeli CSV ayrıştırma ölçütünde Sep, 9950X’te 21 GB/s’ye ulaşıyor
- 0.10.0’dan önce aynı 9950X’te yaklaşık 18 GB/s idi
- Analiz kapsamı, package assets CSV verisinin düşük seviyeli
Rowsayrıştırmasıdır ve tüm değerler tek iş parçacığı bazındadır - Benchmark değerleri birkaç yüzde puanı oynayabildiğinden, belirli bir sürümde küçük gerilemeler görülebilir
0.1.0’dan 0.10.0’a performans değişimi
- Sep performansı; kod değişiklikleri, .NET sürümü değişimleri ve CPU nesli değişimleri birlikte etkili olarak kademeli biçimde iyileşti
- Temsili performans akışı şöyle:
- 0.1.0, 5950X, .NET 7.0: yaklaşık 7 GB/s
- 0.3.0, 5950X, .NET 8.0: yaklaşık 12 GB/s
- 0.6.0, 5950X, .NET 9.0: yaklaşık 13 GB/s
- 0.9.0, 9950X, .NET 9.0: yaklaşık 18 GB/s
- 0.10.0, 9950X, .NET 9.0: yaklaşık 21 GB/s
- Sep’in Haziran 2023’te duyurulmasından bu yana iki yıldan biraz kısa sürede yaklaşık 3 kat hızlandı
- 5950X’te Sep 0.9.0 kullanımı ile 9950X’te Sep 0.10.0 kullanımı karşılaştırıldığında yaklaşık 1.6 kat iyileşme görülüyor
- 9950X’in boost saat hızı 5.7 GHz, 5950X’inki 4.9 GHz
- Yalnızca bu saat hızı farkının yaklaşık 1.2 katı açıklayabileceği değerlendiriliyor
.NET AVX-512 kod üretiminde maske register darboğazı
- Sep, 0.2.3’ten itibaren AVX-512 destekliyordu; ancak o dönem .NET 8, AVX-512’nin
k1-k8maske register’larını açıkça desteklemiyordu - Mevcut AVX-512 kod üretiminde karşılaştırma sonucu maske register’ına giriyor, ardından genel register’a taşınıyor ve tekrar maske register’ına dönüyordu
- 9950X’e yükseltmeden sonra Sep 0.9.0, düşük seviyeli CSV ayrıştırmada yaklaşık 18 GB/s kaydetti; bu, 5950X’ten yaklaşık 1.4 kat hızlıydı
- Ortam değişkeniyle ayrıştırıcılar değiştirilip karşılaştırıldığında, 9950X’te AVX2 ayrıştırıcı yaklaşık 20 GB/s’ye ulaşarak mevcut AVX-512 ayrıştırıcıdan yaklaşık %10 hızlı çıktı
- Bu fark, AVX-512 maske register işlemenin performansı hâlâ etkilediğini doğruladı
Sep ayrıştırma döngüsünün temel yapısı
- Sep’in tüm ayrıştırıcıları aynı temel yapıyı izler ve tek bir
Parsejenerik metodu, tırnak işleme durumuna göre iki farklı yolu desteklerParseColInfos: tırnak işleme sırasında kullanılır ve daha fazla durum takibi gerektirirParseColEnds: tırnak işleme olmadığında kullanılır
- Ayrıştırma, diziden alınan
charspan’leri üzerinde yapılır; örnekte boyut 16K’dır- Bu boyut CPU önbelleğine sığacak kadar küçüktür ve sonrasında verimli çok iş parçacıklı çalışmaya da avantaj sağlar
- Döngü, SIMD register’ına 16 bit karakter verisini yükler, bunu bayt SIMD register’ına dönüştürür ve ardından CSV özel karakterleriyle karşılaştırır
- Karşılaştırma hedefleri arasında
\n,\r,",;gibi karakterler bulunur
- Karşılaştırma hedefleri arasında
- Karşılaştırma sonucu bit maskesine dönüştürülür ve maskede ayarlı bitler sırayla ayrıştırılır
- Performans farkı, bu SIMD C# kodunun .NET tarafından nasıl makine koduna JIT derlendiğine büyük ölçüde bağlıdır
Mevcut AVX-512 ayrıştırıcı ve 0.10.0’daki ayarlama
- 0.9.0’daki
SepParserAvx512PackCmpOrMoveMaskTzcnt, iki adet 512 bit SIMD register’ına ayrı ayrı 32’şercharyükler, bunları tek bir 512 bit bayt vektörüne paketleyerek döngü başına 64 karakter işler - Paketlenen verinin sırası karışık olduğundan
PermuteVar8x64ile yeniden düzenlenmesi gerekir - .NET 9.0 assembly’sinde her
Vec.Equals,vpcmpeqbvevpmovm2bolmak üzere iki komuta dönüşüyordu;k1gibi maske register’ları ilezmmgenel vektör register’ları arasında taşıma tekrarlanıyordu - Sep 0.10.0’da
MoveMaskçağrısı daha erkene alınarak maske register’ı ile genel register arasındaki gidiş-dönüş sayısı azaltıldı- Diğer ayrıştırıcılarda, “özel karakter yok” hızlı yolunda komut sayısını azaltmak için
MoveMaskyalnızca gerektiğinde çağrılır
- Diğer ayrıştırıcılarda, “özel karakter yok” hızlı yolunda komut sayısını azaltmak için
- Ayarlamadan sonra da maske register’ından genel register’a taşıma devam etse de toplam assembly komutu sayısı azaldı
AVX2 ve yeni AVX-512-to-256 ayrıştırıcı
- AVX2 tabanlı
SepParserAvx2PackCmpOrMoveMaskTzcntassembly’si maske register içermediği için daha doğrusal bir yapıya sahiptir - Bu yapı sayesinde AVX2 ayrıştırıcı, mevcut 0.9.0 AVX-512 ayrıştırıcıdan daha hızlıydı
- 0.10.0’daki yeni
SepParserAvx512To256CmpOrMoveMaskTzcnt, AVX-512 komutlarıylacharyükledikten sonraConvertToVector256ByteWithSaturationile 256 bit bayt vektörü oluşturur- Gerçek komut
vpmovuswb’dir - Döngü başına iş hacmi “yalnızca” 32
charolsa da yapı daha basittir
- Gerçek komut
- Bu yöntem 512 bit maske register sorunundan kaçınır; paketlenen veri zaten
ymm4içinde doğru sırada olduğundan ayrı permütasyon da gerekmez - Yeni ayrıştırıcı, 9950X’te Sep ayrıştırma performansını yaklaşık 21 GB/s’ye çıkardı
Ayrıştırıcı bazında 9950X düşük seviyeli benchmark’ları
- AMD 9950X’te tüm ayrıştırıcılar ortam değişkeniyle çalıştırılıp karşılaştırıldığında, yeni AVX-512-to-256 ayrıştırıcı en hızlısı oldu
- Başlıca sonuçlar şöyle:
SepParserAvx512To256CmpOrMoveMaskTzcnt: 21597.7 MB/s, 27.0 ns/row, 1.351 msSepParserVector256NrwCmpExtMsbTzcnt: 20608.5 MB/s, 28.3 ns/row, 1.416 msSepParserAvx2PackCmpOrMoveMaskTzcnt: 20599.3 MB/s, 28.3 ns/row, 1.417 msSepParserAvx512PackCmpOrMoveMaskTzcnt: 19944.3 MB/s, 29.3 ns/row, 1.463 ms
Vector256tabanlı çapraz platform ayrıştırıcı, AVX2 ile neredeyse aynı seviyeye ulaştıVector128veVector512tabanlı çapraz platform ayrıştırıcılar hâlâ hızlı olsa da %5-10 daha yavaştı;Vector512,Vector128’den daha yavaştıSepParserIndexOfAny, 2787.0 MB/s ile belirgin biçimde geride kaldı;Vector64ise 9950X’te hızlandırılmadığından 459.9 MB/s’de kaldı
5950X ve 9950X’in üst seviye benchmark’ları
- package assets verisinde 1 milyon satır işleme sonuçlarında 9950X, 5950X’ten belirgin biçimde hızlıydı
- 5950X
Sep_MT: 119.430 ms, 4888.1 MB/s - 9950X
Sep_MT: 72.213 ms, 8084.1 MB/s
- 5950X
- 9950X’te tek iş parçacıklı
Sep, 1 milyon satırlık package assets verisini 291.979 ms’de, 1999.4 MB/s hızla işledi - Aynı 9950X package assets benchmark’ında karşılaştırılan diğer seçeneklerin performansı şöyleydi:
Sylvan: 413.265 ms, 1412.6 MB/sReadLine_: 377.033 ms, 1548.4 MB/s, ayırma miktarı 1991.04 MBCsvHelper: 1005.323 ms, 580.7 MB/s
- floats verisinde de 9950X’in çok iş parçacıklı Sep’i 25.000 satırı 2.497 ms’de, 8136.8 MB/s hızla işledi
- 5950X’ten 9950X’e geçişte üst seviye benchmark iyileşmesi, düşük seviyeli benchmark’lara benzer şekilde yaklaşık 1.5-1.6 kattır
Henüz yorum yok.