2 puan yazan GN⁺ 2025-07-19 | 1 yorum | WhatsApp'ta paylaş
  • lsr, io_uring tabanlı IO kütüphanesi ourio kullanılarak geliştirilmiş yeni bir ls(1) alternatifidir
  • Mevcut ls ve alternatif araçlara (eza, lsd, uutils ls) kıyasla komut çalıştırma hızı çok yüksektir ve sistem çağrısı sayısı 10 kattan fazla daha azdır
  • Dizin açma, stat, lstat gibi tüm temel IO işlemleri io_uring ile eşzamansız ve toplu olarak işlenerek performans en üst düzeye çıkarılır. Dosya sayısı arttıkça daha da hızlanır
  • Bellek ayırmada mmap çağrılarını en aza indirmek için Zig'in StackFallbackAllocator'ı kullanılır
  • Dinamik bağlama olmadan statik olarak derlendiği için çalıştırılabilir dosya boyutu da mevcut ls'ten daha küçüktür

Giriş ve önemi

  • lsr projesi, standart ls komutunun yerine geçebilecek ve io_uring kullanan hızlı bir dizin listeleme aracıdır
  • Mevcut ls, eza, lsd, uutils ls ile karşılaştırıldığında çalışma hızı ve sistem çağrısı kullanımı açısından üstün performans gösterir
  • Mümkün olduğunca fazla IO işlemini doğrudan gerçekleştirmek için kendi geliştirdiği IO kütüphanesi olan ourio'yu kullanır
  • Benchmark sonuçları, lsr'nin büyük ölçekli dosya ortamlarında da yüksek performans ve kalite sunduğunu gösterir

Benchmark sonuçları

  • hyperfine kullanılarak, içinde n adet normal dosya bulunan bir dizinde her komutun çalışma süresi ölçüldü
    • lsr -al, 10–10.000 dosya aralığında mevcut ls ve alternatiflerine göre açık ara daha kısa çalışma süresi kaydetti
    • Örnek: 10.000 dosyada lsr 22.1ms ile, mevcut ls (38.0ms), eza (40.2ms), lsd (153.4ms), uutils ls (89.6ms) karşısında en yüksek hızı gösterdi
  • Sistem çağrısı sayımı strace -c ile yapıldı
    • lsr -al: en az 20 çağrıdan (n=10) en fazla 848 çağrıya (n=10.000) kadar çıkarak çok düşük bir çağrı sayısını korudu
    • ls, en fazla 30.396 çağrıya (n=10.000), lsd ise 100.512 çağrıya ulaştı; diğer alternatifler de binlerce ila yüz binlerce çağrı düzeyindeydi
    • Aynı koşullarda lsr, en az 10 kat daha az syscall sayısıyla en yüksek verimliliği sağladı

lsr'nin yapısı ve uygulama yöntemi

  • Program argüman ayrıştırma, veri toplama, veri çıktısı olmak üzere 3 aşamada çalışır
  • Tüm IO işlemleri ikinci aşama olan veri toplama sırasında gerçekleşir ve mümkün olan tüm dosya erişimi/bilgi sorgulamaları io_uring ile yapılır
    • Hedef dizinin açılması, stat, lstat, zaman/kullanıcı/grup bilgisi sorguları dahil her şey io_uring tabanlı yürütülür
    • stat işlemlerinin toplu yapılması, sistem çağrısı sayısını çarpıcı biçimde azaltır
  • Zig StackFallbackAllocator ile 1MB bellek önceden ayrılarak mmap gibi ek sistem çağrıları en aza indirilir

Statik derleme ve optimizasyon

  • libc dinamik bağlaması olmadan tamamen statik derlendiği için çalışma ek yükü belirgin biçimde düşüktür
  • GNU ls ile karşılaştırıldığında lsr'nin ReleaseSmall derleme boyutu 138.7KB'ye karşı 79.3KB ile daha küçüktür
  • Ancak lsr'de locale (dil/bölge) desteği yoktur. Standart ls, farklı dilleri desteklemek için ek yük taşır

Sistem çağrıları ve performans sorunlarının analizi

  • lsd, dosya başına clock_gettime'ı 5 kereden fazla çağırıyor; nedeni belirsiz (iç zamanlama ölçümü vb. tahmin ediliyor)
  • Sıralama (sorting) işlemi, toplam işin önemli bir kısmını (yaklaşık %30) oluşturuyor
    • uutils ls, sistem çağrısı verimliliği yüksek olsa da sıralama işlemlerinde yavaşlıyor
  • Yalnızca io_uring kullanımıyla bile sunucular gibi yüksek IO yüküne sahip ortamlarda çarpıcı performans artışı potansiyeli doğrulanmış oldu

Sonuç

  • Geliştirme süresi de çok uzun sürmedi ve syscall optimizasyonunun etkisi beklenenden büyüktü
  • lsr, yüksek hız, az sistem çağrısı ve kompakt boyutu aynı anda sağlayan deneysel bir ls alternatifidir
  • Büyük hacimli dosya ortamları veya yüksek performanslı IO'nun önemli olduğu sistemler için çok uygundur
  • locale desteği olmaması gibi bazı işlevsel sınırlara rağmen hem pratik kullanımda hem de benchmarklarda yenilikçi sonuçlar gösterir

1 yorum

 
GN⁺ 2025-07-19
Hacker News görüşleri
  • Projenin yazarı olduğunu belirtiyor ve io_uring tabanlı lsr için tanıtım yazısının burada okunabileceğini söylüyor

    • Sun'da I18N projesinde çalıştığı deneyimini paylaşıyor. Birden fazla ortamı (yerelleştirme, utf8 vb.) desteklemek için programa çeşitli işlemler eklemek gerektiğinden, sonuç üretmenin maliyeti ile hızın ters orantılı olduğunu bizzat hissettiğini söylüyor. Aslında UNIX'in ls(1)'i basit tasarımı sayesinde çok hızlıydı, ancak çeşitli özellik eklemeleri, sanal dosya sistemi (VFS), farklı karakter kümeleri, renk desteği gibi küçük maliyetler sürekli birikerek onu yavaşlattı. Bunu, io_uring'in ele aldığı soyutlama maliyeti üzerine ilginç bir tartışma olarak görüyor
    • bfs projesi de io_uring kullanıyor (kaynak kodu bağlantısı). lsr ile bfs -ls'in performans karşılaştırmasını merak ediyor. Şu anda bfs yalnızca çok iş parçacıklı durumda io_uring kullanıyor, ancak tek iş parçacığında da (bfs -j1) kullanılıp kullanılamayacağını düşünmeye değer buluyor
    • Zaman ölçümü için tim'in (tanıtım bağlantısı) hyperfine'dan daha iyi olabileceğini düşünüyor. Nim ile yazılmış olması zorlayıcı olabilir ama isim benzerliğini tesadüfi olmaktan öte eğlenceli buluyor
    • C++ projesini Zig'e taşımayı aklında tutuyor. Kendi yaptığı 'libevring' de hâlâ erken aşamada olduğu için, gerekirse ourio ile değiştirilebileceğine açık bakıyor. Zig tabanlı projelerde C/C++ binding desteği olursa bunun C/C++'tan Zig'e geçişte faydalı olacağını düşünüyor
    • Bu tanıtım yazısının arka planı daha iyi anlattığını, bu yüzden ana bağlantı olarak onu kullanıp depo başlığını yukarıya eklemeyi planladığını söylüyor
  • NFS sunucusunda (özellikle iyi olmayan ağ koşullarında) lsr'nin performansının nasıl olacağını merak ediyor. Güvenilmez ağ hizmetlerinde blocking POSIX syscall kullanmanın NFS tasarımının bariz bir zayıflığı olduğunu düşünüyor. io_uring'in bu tür sorunları ne kadar hafifletebildiği de gözlemlemek istediği bir nokta

    • NFS tasarımcısının dağıtık sistemi sabit disk gibi çok tutarlı davranacak şekilde gerçekleştirdiğini söylüyor. Mevcut araçların (ls vb.) ağ hatalarını doğrudan ele almak zorunda kalmamasının bir avantaj olduğunu belirtiyor. Orijinal NFS protokolü durum tutmadığı için sunucu yeniden başlasa bile istemcinin otomatik toparlandığını hatırlatıyor. io_uring'in bu tür durumlarda hataları düzgün aktarıp aktarmadığını merak ediyor. NFS timeout olduğunda bunun nasıl işlendiği de ilgisini çekiyor
    • Evde birden fazla PC'de NFS $HOME kullandığını, ağ iyi olduğu ve paralel yazma gibi zor durumlar kaçınıldığı sürece NFS'nin ortalama kullanılabilirliğinden oldukça memnun olduğunu söylüyor. Ancak ağ kablosu kararsız olduğunda kopmalar yüzünden zorlandığı zamanlar olduğunu ekliyor
    • NFS klasörü okuyan uygulamalarda ctrl+c'nin çalışmaması bilinen bir rahatsızlık. Teoride intr mount seçeneği, takılı kalan uzak sunucu işlemlerine sinyal iletip kesmeye izin veriyordu; ancak Linux'ta bu uzun zaman önce kaldırıldı (şimdi yalnızca soft seçeneği mümkün) (kaynak 1, kaynak 2 (FreeBSD desteği))
    • Samba'da da buna benzer sorunlar var
  • syscall çağrı sayısını 35 kat azaltmasına rağmen hız artışının yaklaşık 2 katla sınırlı kalması ilginç bulunuyor

    • syscall'ların çoğu VDSO üzerinden gerçekleştiği için büyük bir maliyet taşımıyor
    • Daha önce okuduğu bir io_uring benchmark'ında, io_uring tabanlı syscall'ların klasik syscall'lardan daha ağır çıktığını hatırlıyor. Yine de hissedilen iyileşmenin oldukça büyük olduğunu söylüyor. Tam kaynağı hatırlamasa da aklında kalmış
  • Bunu, io_uring kullanımına dair beklenen uzun vadeli hız kazancı örneğinden çok, bir tutorial veya kullanım örneği olarak daha ilgi çekici buluyor. Mevcut eza gibi araçlara kıyasla bunun neden gerekli olduğuna dair sezgisel motivasyonu olmadığını söylüyor. On bin dosyalık bir listenin 40ms yerine 20ms sürmesi, tek çalıştırma açısından ona göre hissedilir bir fark yaratmaz

    • Eğlencesine io_uring kullanımını öğrenmek için yaptığı deneysel bir proje olduğunu söylüyor. Pratikte elde edilen zaman kazancı küçük (hayat boyunca belki 5 saniye tasarruf) ve asıl mesele de bu değilmiş
    • Gerçekte milyonlarca JSON dosyası içeren dizinlerde ls/du çalıştırmanın dakikalar sürebildiğini belirtiyor. coreutils'in temel komutlarının modern SSD performansını çoğu zaman tam kullanamadığını düşünüyor
  • lsr güzel olsa da renkler ve ikon desteğinde eza'nın daha iyi olduğunu söylüyor. Kendisinin ayarı "eza --icons=always -1" olduğu için müzik dosyaları (.opus vb.) otomatik olarak ikon ve renklerle görünüyor, ama lsr'de sadece sıradan dosya gibi görünüyor. Yine de lsr'nin hem kolay yamalanabildiğini hem de çok hızlı olduğunu açıkça hissettiğini belirtiyor. Ayrıca cat ve diğer yardımcı araçların da bu şekilde yapılmasını istediğini, tangled.sh ve atproto kullanımını da ilginç bulduğunu söylüyor. Zig ile yazılmış olmasının da bir acemi olarak Rust'tan daha erişilebilir hissettirdiğini ekliyor

    • “bat”, modern bir “cat” alternatifidir (bat bağlantısı)
    • Renk desteği için LS_COLORS/dircolors gibi standart yöntemin uygulanmasının en iyisi olacağını düşünüyor. GNU ls'in renkleri güzel görünüyor
  • Neden tüm CLI araçlarının io_uring kullanmadığını merak ettiğini söylüyor. Kendi deneyiminde nvme'yi usb 3.2 gen2'ye bağladığında sıradan araçlarla hız 740MB/s iken, aio veya io_uring tabanlı araçlarla 1005MB/s'ye çıktığını aktarıyor. Bunun kuyruk uzunluğu stratejisi ya da lock azaltma etkileriyle ilişkili olabileceğini düşünüyor

    • Taşınabilir yapı için geleneksel olarak #ifdef benzeri makro dallanmaları olmadan yazıldığı için, platforma veya sürüme özel yeni teknolojilerin benimsenmesi yavaş kalıyor. Artık farklı POSIX-benzeri platformlar arası uyumluluğun avantajının eskisi kadar büyük olmadığını düşünüyor
    • io_uring'i verimli kullanmak için asenkron, olay tabanlı bir model gerektiğini söylüyor. Mevcut CLI araçlarının çoğu sezgisel ve sıralı şekilde yazılmış. Dil düzeyinde async doğal olsaydı taşıması daha kolay olurdu, ama şu anda büyük bir refactoring gerektiriyor. io_uring'in de tamamen olgunlaşmadığını, bu yüzden yeni teknolojilerin çıkmasını beklemek ya da otomatik taşıma araçları / AI gibi çözümlerin gelmesini ummak gerektiğini düşünüyor
    • io_uring'in ilk dönemlerinde önemli güvenlik sorunları vardı (yaklaşık 2 yıl önce). Bunların çoğu şimdi çözülmüş olsa da yaygınlaşmaya olumsuz etki etti
    • io_uring güvenlik açısından çok zorlayıcı
    • io_uring çok yeni bir teknoloji olduğu için coreutils'in (ve bağımlı paketlerin) onlarca yıllık geleneği karşısında benimsenmesi zaman alacaktır. “Paylaşımlı ring buffer” tarzı sistem çağrılarının mevcut eşzamanlı yöntemlerin yerine standart hâle gelmesi için zamana ihtiyaç var
  • strace ile bakıldığında lsd'nin dosya başına yaklaşık 5 kez clock_gettime çağırdığı görülüyor. Bunun nedenini tam bilmiyor; muhtemelen her zaman damgası için “kaç dakika/saat/gün önce” hesabı yapıyordur ya da bir kütüphane mirası olabilir

    • Artık clock_gettime gerçek bir syscall değil, vDSO üzerinden işleniyor (man 7 vDSO'ya bakılabilir). Acaba zig bu yapıyı kullanmıyor olabilir mi diye düşünüyor
  • Konudan biraz sapıyor olabilir ama Mellanox 4 veya 5 gibi üst düzey kurumsal sunucularda, 10G NIC ortamında io_uring'in LD_PRELOAD'a kıyasla soket gecikmesi overhead'ini mikrosaniye düzeyinde ne kadar azalttığına dair gerçek deneyim veya benchmark sayıları merak ediyor. Etkilerin birbirine eklenmediği anlaşılıyor; doğrudan deneyimi olan birinin rakam paylaşmasını isterdi

  • io_uring getdents'i desteklemediği için asıl fayda bulk stat işlemlerinde (ör. ls -l) görülüyor. getdents işini asenkronlaştırıp üst üste bindirmek mümkün olsa daha iyi olurdu diye düşünüyor

    • POSIX'te NFS'nin “readdirplus” (getdents + stat) işlemi standartlaştırılırsa, io_uring'in bazı avantajlarının dengelenebileceğini öngörüyor
  • .mjs ve .cjs uzantıları için ikon olmasına rağmen, .c, .h, .sh gibi dosya uzantıları için olmamasını ilginç buluyor