Apple Silicon'da WebAssembly ile Zero-Copy GPU Çıkarımı

Apple Silicon'da WebAssembly ile Zero-Copy GPU Çıkarımı

WebAssembly modülleri, Apple Silicon üzerinde GPU ile sıfır kopyalama ile çalışıyor. Performans ve verimlilikte devrim niteliğinde bir gelişme.

Paylas

Apple Silicon'da GPU ile WebAssembly: Zero-Copy Nedir?

Apple Silicon üzerinde WebAssembly (Wasm) modüllerinin, GPU ile sıfır kopyalama (zero-copy) yöntemiyle çalışması, yazılım geliştirmede önemli bir yenilik sunuyor. Bu teknoloji, CPU ve GPU'nun aynı fiziksel bellek alanını paylaşmasını sağlıyor, böylece veri aktarımında kopyalama veya ara tamponlara gerek kalmıyor. Örneğin, bir Wasm misafiri, kendi lineer belleğinde bir matris dolduruyor, GPU bu veriyi okuyor, hesaplama yapıyor ve sonuçları doğrudan aynı bellek alanında geri yazıyor.

Bu süreçte, geleneksel olarak Wasm ve GPU arasındaki veri iletişimi, maliyetli bir serileştirme sınırına bağlıydı. Çoğu donanımda, bir sanal makineden (VM) bir hızlandırıcıya veri aktarımı, belleği kopyalamayı gerektiriyordu. Ancak Apple'ın Unified Memory Architecture (Birleşik Bellek Mimarisi) bu engeli ortadan kaldırarak, Wasm'ı kontrol düzlemi ve GPU'yu hesaplama düzlemi olarak kullanıyor. Sonuç olarak, neredeyse sıfır gecikme ile etkileşim sağlanıyor.

Sıfır Kopyalama Zorluğu

WebAssembly, geliştiricilere izole bir ortam sunarken, bu ortamda yalnızca düz bir bayt dizisi (lineer bellek) ile çalışmanıza olanak tanıyor. Bu da dış dünyayla etkileşim için "host" fonksiyon çağrıları gerektiriyor. GPU'lar da düz bir bayt dizisi istiyor, fakat bu, sayfa hizalı ve DMA motoruna erişilebilir olmalı. Geleneksel bir GPU ile bu veri aktarımı, iki kopyalama ve iki gecikme ile sonuçlanıyor.

Apple Silicon ile bu durum değişiyor. CPU ve GPU, aynı fiziksel bellek alanını paylaşıyor. Bu da bir işaretçi (pointer) üzerinden belleğe erişimi sağlıyor. Ancak, bu işaretçinin, Wasm çalışma zamanı ve GPU API'si arasında savunma amaçlı bir kopya yapılmadan geçip geçemeyeceği sorgulanıyor.

Üç Bağlantılı Zincir

Bu teknoloji üç temel bağlantıya dayanıyor:

  1. Bellek Eşlemesi (mmap): ARM64 macOS üzerinde, mmap ile oluşturulan bellek sayfa hizalı adresler oluşturuyor. Bu hizalama, Metal API'sinin gerekliliklerini karşılıyor.

  2. Metal API'si: Metal, bu işaretçiyi kopyalamadan kabul ediyor. MTLDevice.makeBuffer(bytesNoCopy:length:) işlevi, mevcut bir işaretçiyi Metal tamponu olarak sarmalıyor. Bu sayede GPU, CPU ile aynı fiziksel belleği kullanıyor.

  3. Wasmtime: WebAssembly çalışma zamanı olan Wasmtime, kendi bellek ayırıcıyı (allocator) getirmenize olanak tanıyor. Böylece kendi mmap bölgenizi sağlayarak, Wasm modülünün ve Metal'in aynı belleği paylaşmasını sağlıyorsunuz.

Bu üç bağlantıyı birleştirerek, Wasm modülü belirli kayıtlara veri yazıyor, GPU bu veriler üzerinde işlem yapıyor ve sonuçlar, kopyalama olmadan doğrudan bellekte güncelleniyor. Bu işlem, 128x128 boyutunda bir matris çarpma testiyle doğrulandı ve tüm verilerde sıfır hata alındı.

Ölçüm ve Performans

Bu süreçte ölçtüğüm üç temel metrik şunlardı:

  • İşaretçi Kimliği: Gerçekten sıfır kopya mı?

  • Bellek Aşırı Kullanımı: Gizli kopyalar var mı?

  • Doğruluk: GPU, Wasm'ın yazdığını görüyor mu?

Ölçümler:

Ölçüm Sıfır Kopya Yolu Kopyalama Yolu İşaretçi Kimliği mmap == MTLBuffer Farklı adresler RSS Delta (16 MB) 0.03 MB 16.78 MB GEMM Gecikmesi ~6.75 ms ~6.75 ms Doğruluk 0 hata 0 hata

Gecikme eşitliği, Unified Memory Architecture üzerinde hesaplamanın her iki yolda da aynı olmasıyla açıklanıyor. Bellek açısından sıfır kopya yolu, GPU erişimini sağlamak için neredeyse hiç aşırı yük gerektirmiyor, ancak kopyalama yolu bellek kullanımını iki katına çıkarıyor.

Sıfır Kopyadan Daha Fazlası

Artık sıfır kopya ile bellek paylaşımı yapabiliyorum. Bu yeteneği nasıl kullanabilirim? Apple’ın MLX çerçevesi ile birlikte Llama 3.2 1B Instruct modelini çalıştırdım. Bu süreçte, bellek erişimi GPU üzerinden Wasm aktörleri aracılığıyla sağlandı.

Ölçümler:

İşlem Gecikme Model yükleme (safetensors) 229 ms Önceden doldurma (5 token) 106 ms Her token için üretim ~9 ms Host fonksiyonu sınırı Negligible

Bu süreç, yerel çıkarımda anahtar-değer önbelleğinin (KV cache) taşınabilirliğini sağlıyor. GPU erişilebilir bellekte saklayarak serileştirme yapabiliyorum. Bu sayede, önbelleği diskten kaydedip geri yükleyebiliyor, böylece bir işlem sırasında duraklayıp başka bir yere geçiş yapabiliyorum. Bu, tam bağlamı koruyarak işlemi devam ettirme imkanı sunuyor.

Şevval Yüce

Yazar

Şevval Yüce

TechPusula yazarı. Teknoloji ve dijital dönüşüm üzerine içerikler üretmektedir.

Tüm yazıları gör

Yorumlar

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Yorum Yaz

0/2000

İlginizi Çekebilir

Tüm yazılar