deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak Hacker News – Front Page (native)

Copy-and-patch JIT: pgrust geliştiricisi 5 mikrosaniyede kod üreten bir derleyiciyi anlatıyor

Hacker News ön sayfasına çıkan bir gönderide pgrust'un yazarı, yaklaşık 5 mikrosaniyede derleme yapan bir copy-and-patch JIT'i ele alıyor; bu hız, seçili bir alt küme yerine her SQL sorgusunu derlemek için yeterli.

Copy-and-patch JIT: pgrust geliştiricisi 5 mikrosaniyede kod üreten bir derleyiciyi anlatıyor

Her sorgu için yeterince hızlı bir derleyici

malisper.me'de yayınlanan ve Hacker News ön sayfasına ulaşan bir blog yazısı iddialı bir noktaya değiniyor: mikrosaniyeler içinde tamamlanan just-in-time derleme artık elle kurulmaya uygun hale geldi ve bunu kullanan veritabanları eski motorlardan daha iyi performans gösterebilir. Yazının yazarı pgrust adlı bir veritabanı geliştiriyor; yazıya göre bu veritabanının özel JIT'i kodu yaklaşık 5 mikrosaniyede çalıştırılabilir makine koduna dönüştürüyor — bu o kadar kısa bir süre ki, yalnızca elle seçilmiş bir alt küme değil, gelen her SQL sorgusu derleniyor.

İddia ve hedeflediği boşluk

Yazı sektörle ilgili bir gözlemle başlıyor: Bugün üretime hazır hiçbir veritabanı kendi JIT derleyicisini sunmuyor. JIT kullanan motorlar ya LLVM'e bağlanıyor ya da C veya C++ kodu üretip bunun üzerinde bir derleyici çalıştırıyor; her iki yol da derleme sürelerini, tekniğin uygulanmaya değer olduğu yerleri sınırlayacak kadar uzatıyor.

Yazarın argümanı şu: Bu boşluk, doğrudan assembly üreten bir derleyici yazmanın eskiden nadir görülen düşük seviyeli uzmanlık gerektirmesinden kaynaklanıyor. Pgrust'un JIT'ini geliştirirken yazar aynı zorluğu bekliyordu ama görevin çok daha elverişli olduğunu gördü ve bunu süreç boyunca aldığı yapay zeka desteğine bağlıyor. Ortaya çıkan derleyici, pgrust'un iyi performans göstermesinin başlıca nedenlerinden biri olarak tanımlanıyor.

Neden hiç JIT?

Yazıya göre JIT, program çalışırken derlenmiş kod üretmek anlamına geliyor. İşe yaradığında kazançlar kabaca 2x ile 5x arasında ve zaman zaman daha da öteye gidiyor. Bunu haklı çıkaran durum, programın ne yapması gereceğini kökten değiştiren bilgilerin runtime'da gelmesidir. Interpreter'lar bunun tipik örneğidir; çünkü çalıştırılacak kodu yalnızca runtime'da alırlar. Yazı ayrıca, gelen verinin şemasının çalıştırma anına kadar bilinmeyebildiği ayrıştırma (parsing) durumuna işaret ediyor.

İşlenmiş örnek: bir regex motoru

Eğitim, SQL yerine minimal bir düzenli ifade (regex) motoru kuruyor. Motor tam olarak iki özelliği destekliyor: literal dizeler ve Kleene-yıldızı tekrarı; böylece b(an)* gibi desenleri eşleştirebiliyor ama alternasyon veya lookaround içeren hiçbir şeyi eşleştiremiyor. Regex, üç düğüm tipi içeren önceden ayrıştırılmış bir Rust AST'si olarak geliyor: Literal, Concatenation ve Repetition.

Interpreter sürümü 20 satırdan az Rust koduna sığıyor. b(an)* için özelleştirilmiş elle yazılmış bir eşleştiriciyle kıyaslandığında yazar, elle yazılmış kodun birkaç test örneğinde 10 ila 20 kat daha hızlı çalıştığını bildiriyor — JIT'in tamamen genel kalırken kapatması hedeflenen fark tam olarak bu.

ARM64 üzerinde copy-and-patch

Yazının öğrettiği teknik, copy-and-patch'in bir varyantı. Derleyici, stencils adı verilen assembly şablonlarından oluşan bir küme tutuyor; her biri üretmesi gereken her işlem için bir tane. Bir işlemi derlemek için ilgili stencil'i işlemin özellikleriyle yamalıyor ve çıktıya ekliyor; zincirlendiğinde, yamalanmış stencil'ler el yazımı sürüme yaklaşan performanslı bir program oluşturuyor. Son bir adım, bitmiş talimatları çalıştırılabilir belleğe kopyalayarak Rust'ın bunları sıradan bir fonksiyon gibi çağırmasını sağlıyor.

Anlatım macOS üzerinde ARM64'yü hedefliyor ve üretilen koddan geriye doğru ilerliyor. Öne çıkan tasarım kararları arasında geri izleme (backtracking) için açık bir yığın ve karakter karşılaştırmalarının dize sonunda basitçe başarısız olması için girdiyi null baytla sonlandırmak var; bu, herhangi bir uzunluk kontrolü ihtiyacını ortadan kaldırıyor. Register'lara sabit roller atanmış: x0 geçerli girdi konumunu izliyor ve dönüş değeri olarak da işlev görüyor; x1 ve x2 geri izleme yığınının tepesini ve tabanını tutuyor (taban register'ı boşluğun algılanabilir olmasını sağlıyor) ve x9 karalama alanı olarak hizmet veriyor. Prolog, yığın durumunu başlatan tek bir talimat; bir karakter eşleşmesi ise bir bayt yüklemesi, bir karşılaştırma, fallback bloğuna koşullu bir dallanma ve bir işaretçi ilerletmesi olarak derleniyor. Yazı oradan tekrar ve geri izleme mantığına, AST'den stencil'leri dolduran emitter'a ve üretilen kodun çağrılabilir bir fonksiyon olarak paketlenmesine geçiyor.

Neden önemli

Veritabanı ve sistem mühendisleri için derleme gecikmesi her zaman JIT yapmanın vergisi olmuştur. Bir sorgu motorunun içinde LLVM destekli derleme yalnızca sıcak veya pahalı sorgularda kendini amorti eder; motorların bunu eşik değerlerin ve ısınma sürelerinin arkasına koymasının nedeni de bu. Mikrosaniyelerle ölçülen bir derleyici bu ekonomiyi tersine çeviriyor: sorgu başına derleme, kapı denetimi mantığının tamamen silinmesine izin verecek kadar ucuzluyor.

İkincil nokta, böyle sistemleri kimin kurabileceğiyle ilgili. Yazarın deneyimi, yapay zeka desteğinin daha önce veritabanlarını LLVM'e bağımlı tutan assembly seviyesindeki derleyici çalışmasının önündeki engeli düşürdüğünü öne sürüyor ve bunu yeni motorlar için köklü rakiplerden ayrışma fırsatı olarak çerçeveliyor. Her zamanki uyarılar geçerli: sayılar yazara ait, benchmark yalnızca iki regex özelliği olan oyuncak düzeyinde ve yazı aynı zamanda pgrust için bir tanıtım. Yine de belgelediği teknik kendi içinde bütünlüklü ve derleme maliyeti ile runtime hızı arasındaki aynı dengeyle karşılaşan her ekip tarafından yeniden üretilebilir.

  • #jit
  • #compilers
  • #databases
  • #rust
  • #arm64