2 puan yazan GN⁺ 2023-07-13 | 1 yorum | WhatsApp'ta paylaş
  • Vale’in bölge ödünç alımı prototipi ilk kez başarıyla derlendi; böylece jenerasyonel referanslarla bölgeleri birleştiren bellek güvenliği yaklaşımı gerçek programlarda doğrulanabilir hale geldi
  • Geliştiriciler kodu C/C++’a yakın bir tarzda yazıp yalnızca gereken yerlerde pure ve bölge ödünç alımını uygulayarak jenerasyon kontrolü ek yükünü azaltabiliyor
  • İlk zero-check Vale programı, roguelike seviye üretimi için bir Cellular Automata örneğiydi ve ortaya çıkan assembly, unsafe_with_bounds modu ile neredeyse aynı seviyeye getirildi
  • Benchmark’ta safe_fastest, unsafe_with_bounds karşısında gözlemlenebilir bir yavaşlama göstermedi; unsafe_no_bounds ise iki moddan da 1.18 ± 0.01 kat daha hızlıydı
  • Henüz C/Rust ile doğrudan bir karşılaştırma yapılmadı; LLVM optimizasyon gürültüsü, prototipin olgunluk düzeyi ve inline data desteğinin olmaması nedeniyle Vale’e özel bir pre-optimizer ile bölge özelliklerinin düzenlenmesi hâlâ yapılmayı bekliyor

Jenerasyonel referanslar ve bölge ödünç alımının birleşimi

  • Vale’in bellek güvenliği yaklaşımı, reference counting, izlemeli garbage collection ve borrow checking kullanmama yönünde bir hedef taşıyor
  • Temel yapı, geliştiricinin programı C veya C++’a yakın bir şekilde yazması ve Vale’in generational references mekanizmasının bellek güvenliğini koruması üzerine kurulu
  • Ardından pure ve region borrowing uygulandığında jenerasyon kontrolü ek yükünün büyük kısmı ortadan kaldırılabiliyor
  • Buna linear style da eklenirse Vale kodundaki jenerasyon kontrollerinin zero seviyesine kadar indirilebileceği düşünülüyor
  • Bölge ödünç alımı tamamen opt-in olduğundan, önce rahatça yazıp yalnızca optimizasyon gereken bölümlere sonradan eklemek mümkün
  • Amaç, aynı program içinde bazı kısımların Java gibi esnek, bazılarının Rust gibi hızlı ya da ikisi arasında bir noktada seçilebildiği bir yapı sunmak

Prototipi oluşturmak için gereken çalışmalar

  • Son birkaç yılda derleyici altyapısı kurulurken bölge tabanlı ödünç alma sistemi ile generational references desteğinin birlikte çalışması için çalışmalar yapıldı
  • Ödünç alma sisteminin kendisi karmaşık olduğu gibi, önceki şablonlardan daha güçlü full generics de gerekiyordu
  • Bölgelerle jenerasyonel referansların doğal biçimde birlikte çalışması için yeni bir derleyici aşaması da gerekti
    • Dahili olarak bölgeler, “pure height” tamsayılarına indirgeniyor
    • Bölge generic parametresi negatif, varsayılan bölge 0, her pure block ise artan pozitif sayılarla ifade ediliyor
  • Birkaç ay önce bölge prototipi tamamlandı; hâlâ pürüzlü yanları olsa da ilk kez bir şey başarıyla derlenebildi
  • Sonuç olarak ilk zero-check Vale programı ortaya çıktı
    • --print_mem_overhead true derleyici bayrağıyla programdaki jenerasyon kontrolü sayısı sayılabiliyor

İlk zero-check programı ve assembly karşılaştırması

  • İlk program, roguelike oyun seviyeleri üreten bir Cellular Automata örneğiydi
  • Derleyici kodundaki küçük bir hata bile çıkan assembly’ye ek talimatlar koyarak son programda yapay ek yük oluşturabiliyor
  • Sorunu izlemek için çıkan assembly sürekli olarak Vale’in unsafe modlarıyla karşılaştırıldı
    • unsafe_no_bounds: C’ye benzer şekilde tüm bellek güvenliği korumalarını kapatıyor ve generational references yerine raw pointer kullanıyor
    • unsafe_with_bounds: Rust’taki gibi dizi erişimlerine bounds checking ekliyor
  • Aylar boyunca farklar izlendi ve sonunda çıkan assembly unsafe_with_bounds modu ile neredeyse aynı hale geldi
  • Beklenen tek fark, her allocation’ın başına pseudo-random bir generation number konmasıydı; bu sayı gerçek jenerasyon kontrollerinde okunmuyordu
    • Dahili olarak bunu hızlı tutmak için monoton artan bir register kullanılıyor
    • isolates veya unique references eklendiğinde bu fark da ortadan kaldırılabilir

Benchmark sonuçları ve ölçüm koşulları

  • Benchmark özeti şöyleydi
Summary
  './build_unsafe_no_bounds/main' ran
    1.18 ± 0.01 times faster than './build_unsafe_with_bounds/main'
    1.18 ± 0.01 times faster than './build_safe_fastest/main'
  • Vale’in normal modu olan safe_fastest, yalnızca bounds checking içeren moda kıyasla bir yavaşlama göstermiyor
  • Bu ölçümde söz konusu yaklaşım gözlemlenebilir bir ek yük taşımıyor
  • Doğrudan denemek isteyenler regions branch sürümünü derleyebilir, benchmarking scripts deposuna bakabilir ve sorularını discord server üzerinden sorabilir
  • Ölçüm koşullarının belirgin sınırlamaları var
    • Bu, C veya Rust gibi dillerle doğrudan karşılaştırmalı bir benchmark değil
    • Bu derleyiciler yıllar boyunca geliştirilmiş ayrı optimizasyonlara sahip olduğundan deney değişkenlerini bulanıklaştırabilir
    • Bellek güvenliği yaklaşımındaki farkı izole etmek için unsafe_no_bounds ve unsafe_with_bounds ile karşılaştırma yapıldı
    • Ölçüm ortamı Ubuntu 22.04 çalıştıran Razer Blade 15" 2018, 512GB SSD idi
    • Ölçüm aracı hyperfine ve çalışma ortamı cset shield idi

Daha büyük programlarda ortaya çıkan optimizasyon gürültüsü

  • Daha büyük programlarda kayda değer ölçüde optimizer noise gözlendi
    • Bu, benchmark noise’dan farklıydı; ölçüm kurulumu ± 0.01 gibi çok tutarlı çalışma süreleri gösteriyordu
    • Bir bölümdeki küçük bir değişiklik ölçüm sonuçlarını tek bir yöne kaydırabiliyordu
  • Generation number boyutu değiştirildiğinde tutarlı biçimde 1.13 ± 0.01 seviyesinde negative overhead görülen bir durum da vardı
    • Programda çok fazla generation number olmadığı için bu sonuç tuhaftı
    • Register allocation değişimlerinin, anlamsal farklardan gelen performans farkını bastırmış olması mümkün
  • Küçük bir roguelike oyun gibi daha büyük bir programda optimizer, bir if ifadesi içindeki aynı iki branch’i birleştiremedi ve başka bariz optimizasyonları da kaçırdı
  • Okunmayan bir integer’ın varlığının neyi etkilediği net değil; bunun bir LLVM hatası olması da mümkün
  • Bu sonuç, Rust’taki MIR benzeri Vale’e özel bir pre-optimizer gerekebileceğine işaret ediyor
    • LLVM daha çok C düşünülerek tasarlandı
    • LLVM, generational references’ı kasıtlı olarak serbest bırakılmış belleğe erişim deseni olarak yorumlarsa bunu undefined behavior sayabilir

Uygulanabilirlik ve sonraki çalışmalar

  • Jenerasyonel referanslar ile bölgeler birleştirildiğinde çok hızlı bir bellek güvenliği yaklaşımı ortaya çıkabiliyor
  • Bu yaklaşımın iyi uyabileceği yazılım alanları şu özellikleri taşıyor
    • tracing garbage collection’a kıyasla daha öngörülebilir latency istiyor
    • reference counting’e göre daha iyi performans ve cache friendliness arıyor
    • borrow checking’e kıyasla daha kolay prototipleme ve iterasyon yapmak istiyor
  • Vale’in C veya C++ ile doğrudan karşılaştırılmasından önce yapılması gereken işler var
    • LLVM optimizer’ın generation ve immutability çıkarsaması konusunda sorunları olduğundan Vale’e özel bir pre-optimizer gerekiyor
    • Vale’in, şu anki tüm struct’ları heap’e koyan geçici çözüm yerine inline data desteği kazanması gerekiyor
    • Bu benchmark’ta struct kullanılmadığı için inline data eksikliği bu sonuçları etkilemedi
    • Bölge özellikleri hâlâ prototip aşamasında; pürüzlerin giderilip teknik borcun azaltılmasının ardından main branch’e birleştirilmesi gerekiyor
  • Birleştirme sonrasında standart kütüphanenin bölgeleri kullanması planlanıyor; böylece kullanıcının main program code içinde bölgeleri doğrudan kullanması gerekmese bile bu avantajlardan yararlanması sağlanacak
  • Mevcut ölçümler, zero-check programların mümkün olduğunu ve beklenen hız düzeyine ulaşabildiğini gösteriyor

1 yorum

 
GN⁺ 2023-07-13
Hacker News yorumları
  • Vale’i indirip denedim ama valec derleyicisini ilk çalıştırdığımda argüman vermezsen doğrudan "(panic)" yazdırması kötü bir izlenim bıraktı
    panic çok ağır bir ifade ve normal hata işleme durumlarında bundan kaçınılması gerektiğini düşünüyorum. Programın panic vermesi kontrolsüz bir durum hissi uyandırıyor, bu da hoş bir tat bırakmıyor
    Sonra komut satırı argüman yardımına bakmaya çalıştım ama şu anda fiilen yok gibiydi; sitedeki Hello World örneğini hello.vl olarak kaydedip valec hello.vl çalıştırınca Unknown subcommand çıktı
    Bunun üzerine valec build hello.vl çalıştırdım, bu kez Unrecognized input: hello.vl ardından yine (panic) geldi; valec help de yardımcı olmayınca sonunda vazgeçtim. Bunun nasıl kullanılacağını anlayamadım

    • Üzgünüm. Görünüşe göre yardım dosyası artık düzgün görüntülenmiyor. İndirme paketindeki valec-help-build.txt dosyasını doğrudan cat edersen aradığın şeyin açıklandığını göreceksin
      Derleyici şu anda hâlâ oldukça pürüzlü bir durumda. Ağustostan mayısa kadar %100 bölge(region) prototiplemesine odaklandım; şu an yaşadığın şey de bu süreçte biriken teknik borç. Buna yardım sistemi için entegrasyon testlerinin olmaması da dahil
      Son 1-2 aydır bu borcu kapatıyorum ama hâlâ 0.2 sürümündeki seviyeye geri dönebilmiş değilim. Daha fazla yardıma ihtiyacın olursa haber ver ya da Discord sunucusuna gel; yardımcı olacak çok kişi var
    • Bana kalırsa Vale hâlâ fiilen Ar-Ge aşamasında. En fazla belli bir dalın belirli bir commit’inin çalışmasını bekleyebileceğin bir noktada; herhangi birinin derleyiciyi indirip bir şeyler inşa edebileceği aşamada olduğunu söylemek zor
      Yine de README bunu açıkça göstermiyor, “Try Vale” yazdığı için biraz muğlak kalıyor. Ama şu an için Ar-Ge/kavram kanıtı düzeyine daha yakın görünüyor
    • Bu bir bug’dan çok kullanıcı arayüzü sorunu gibi. Deneysel bir şeyse gerçek bug’lara da belli ölçüde tolerans gösterebilirim
      Kullanıcı arayüzü ya da bug’lar açısından bakarsak, 40 yıllık C++’ı 35 yıllık gdb ile debug etme deneyimi herhangi bir deneysel dille rahatlıkla yarışır. Mesela funcname()::staticvarname çıktısı tuhaf bir arayüz ve yarı yarıya başarısız oluyor. C++ build sistemlerinden hiç bahsetmiyorum bile
      Deneysel bir teknoloji söz konusuysa kavramı eleştirebilirsin ama pürüzlü bir kullanıcı arayüzünü bir yere kadar tolere edebilirim
    • Derleyicinin nasıl kullanılacağı GitHub README’sinde yazıyor
      https://github.com/ValeLang/Vale#building-a-vale-program
    • Henüz alfa aşamasındaki bir yazılımdan kabaca beklenebilecek görünüm bu
  • İzlemeli çöp toplamaya göre gecikmesi daha öngörülebilir, referans sayımına göre performansı ve cache dostluğu daha iyi, borrow checking’e göre de prototipleme ve yineleme daha kolaysa, bu merakın ötesinde gerçekten ilgi çekici
    RSS akışına da abone olmaya başladım: https://verdagon.dev/rss.xml

    • Nihayet AOT derlenen bir dilde “arada sırada bellek hataları olsun gitsin” sonucuna varmayan yeni bir fikir çıktı
  • Vale’in daha fazla destekçiye ihtiyacı var
    https://github.com/sponsors/ValeLang
    Bu yazı ön sayfadayken projenin aylık 3.000 dolar hedefine ulaşmasına yardımcı olunmasını isterim
    Evan’ın bu işi tam zamanlı yapabilmesine yardımcı olmak istiyorum. Ben de destekçilerden biriyim. Hızlı, güvenli ve aynı zamanda prototiplemesi keyifli bir dil desteklenmeye değer

    • GitHub Sponsors ile Patreon desteği arasında gelir paylaşımının nasıl farklılaştığını merak ediyorum
  • “Vale’e özel bir ön optimize edici, Rust’taki Cranelift’e benzer bir şey” muhtemelen MIR, yani orta seviye ara gösterimden söz ediyor. Bununla ilgili güzel bir blog yazısı var: https://blog.rust-lang.org/2016/04/19/MIR.html
    Cranelift esas olarak JIT odaklı bir derleyici backend’i ama teorik olarak LLVM’in yerini de alabilir. Alternatif backend çalışması da sürüyor, fakat bazı kısıtları var: https://github.com/bjorn3/rustc_codegen_cranelift

    • Öyle gibi görünüyor. Cranelift’i WebAssembly için bir Rust optimize edicisi olarak görebiliriz
  • Çoğu kodda bellek yönetimini düşünmek zorunda kalmadan, yalnızca sıcak kod yollarını sıfır maliyetli soyutlamalarla optimize etme seçeneği sunan bir yaklaşım iki tarafın da avantajlarını birleştiriyor gibi duruyor
    Özellikle de rahatlık uğruna güvenlikten değil yalnızca performanstan ödün veriliyorsa

    • Sadece C++ kullanıyorum ama bellek yönetimi konusunda hiç endişelenmiyorum
      Paylaşımlı sahiplik kötü bir fikir olduğu için akıllı işaretçiler de kullanmıyorum
      Bellek yönetimi meselesinin çoğunlukla önemsiz olduğunu düşünüyorum
  • Nesilsel referanslar (generational references) bağlamında güvenli denince tam olarak ne kastedildiğini merak etmeye devam ediyorum
    Doğru anladıysam bu, use-after-free ve double-free’yi önlediği anlamına mı geliyor? Öyleyse beklenen nesil ile gerçek nesil eşleşmediğinde bellek erişiminde program yine de başarısız olabilir
    Bu açıdan bakınca referans sayımı, izlemeli çöp toplama ve borrow checking’den daha az güvenli görünüyor

    • double-free, Vale’in tek sahipliği yani C++ anlamındaki tek sahiplik sayesinde önleniyor; nesilsel referanslar ise use-after-free’yi güvenli biçimde tespit etmeyi sağlıyor
      Bir referans üzerinden serbest bırakılmış belleğe erişmeye çalışırsanız öngörülebilir ve güvenli şekilde bir segmentation fault ya da assertion failure oluşması gerekir. İleride sanal adres alanını yeniden eşleyen iyileştirme gelirse segmentation fault’ları da ortadan kaldırabilecek olmamız heyecan verici
    • Sarkan pointer’ın rastgele belleği okuyup yazmasına izin vermek yerine segmentation fault vermesi anlamında güvenli
      Yine de nesil indeksi kullanılıyorsa, gerçek erişim denenmeden önce erişimin geçerli olup olmadığını çalışma anında kontrol etmek de mümkün olmalı. Vale’de bunun mümkün olup olmadığını bilmiyorum
    • GC, borrow checking ve referans sayımından daha az güvenli. Yine de malloc/free’den daha güvenli ve başka avantajları da var
    • Ben de merak ediyorum. Bunun use-after-free ve double-free’yi nasıl önlediğini anlamıyorum
      check fonksiyonu, tahsisin nesil numarasına ihtiyaç duyduğu için tahsise erişiyor. Yani referansın o tahsise erişip erişemeyeceğini kontrol etmek için önce o tahsise erişmek gerekiyor
      Elbette tahsis zaten serbest bırakıldıysa, o tahsise ve nesil numarasına erişmenin kendisi tanımsız davranış olduğundan bu işe yaramaz
      O kadar bariz görünüyor ki benim çok büyük bir şeyi mi kaçırdığımı, yoksa burada söylenen “bellek güvenliği”nin bambaşka bir anlamı mı olduğunu anlayamıyorum
    • Kişinin kendi sınırlı “güvenli” tanımına göre daha az güvenli mi derseniz, muhtemelen evet olabilir
  • Vale, V gibi bir dil değil. V, https://mawfig.github.io/2022/06/18/v-lang-in-2022.html adresinde çok eleştirel bir inceleme aldı; isimler benzer olduğu için ben de onu Vale diye yanlış hatırlıyordum
    Aynı hatayı yapan başkaları olur diye bunu not düşüyorum

    • O “çok eleştirel inceleme” aslında sadece bir yıl önce düzeltilmiş küçük hata listesinden ibaret
      Yazının içeriği artık geçerli değil ama hâlâ duruyor ve zaten o blogdaki tek yazı da bu
    • O “eleştirel inceleme”, muhaliflerin ya da trollerin sürekli kullandığı eski bir spam’e daha yakın görünüyor. Dilin alfa sürümü hakkında bir “inceleme”; aslında saldırgan bir yazı, bunun dışında pek bir değeri yok gibi
      Şu an 2023 ve V de beta (0.4). Üstelik o yazıyı hazırlayan kişi tek kullanımlık bir GitHub hesabıyla bu inceleme/saldırıyı yayımlayıp tartışma yaratmış, sonra da kaybolmuş
      O blogdaki tek yazı da V’ye saldıran bu yazı; başka inceleme yok. Kayda değer içerik taşıyan kısımlar zaten düzeltildi[1]
      mawfig.github diye aratırsanız bunun HN’de tekrar tekrar dolaşıma sokulduğunu ve genelde karalama için kullanıldığını da görebilirsiniz
      [1]: https://github.com/vlang/v/issues/14803
      [1]: https://github.com/vlang/v/issues/14787
      [1]: https://github.com/vlang/v/issues/14786
  • Evan’ı bu dönüm noktasına ulaştığı için tebrik ederim. Programlama dili tasarımı ya da derleyici konusunda deneyimim yok ama Vale yazılarını okumaktan keyif alıyorum

    • Ben de benzer düşünüyorum; keşke adı farklı olsaydı
      Artık Evan’ın Vale’i ile Adobe Software Technology Lab’in Val’i var ve bu yüzden ilgili şeyleri aratmak epey zorlaşacak gibi görünüyor
      https://www.val-lang.dev
    • Ben de çoğu durumda yazıları anlayacak arka plan bilgisine sahip değilim ama yine de ilginç buluyorum
    • Ben de yazıların harika olduğunu düşünüyorum ve Vale’in geleceği için heyecanlıyım
  • “Vale hızlıdır: Vale, LLVM ile AOT derlenir, statik tip kullanır, hız ve esneklik sunan bellek güvenliği için yeni bir nesilsel referanslar tekniği kullanır ve yakında region borrow checking ekleyerek daha da hızlanacaktır”
    https://vale.dev/

  • İki kişinin 5 yıldır süren tartışmasına kulak misafiri oluyormuşum gibi geliyor
    Burada neler olduğunu açıklayabilecek biri var mı? Yazı fazla anlaşılmaz