deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak Hacker News – Front Page (hnrss.org)

Go 1.26 ve 1.27, deneysel SIMD API'leriyle taşınabilir bir vektör katmanı sunuyor

Go'nun deneysel archsimd ve simd paketleri, amd64, arm64 ve wasm üzerinde assembly'ye yakın vektör performansı sağlıyor; diğer tüm platformlarda emülasyon devreye giriyor.

Go 1.26 ve 1.27, deneysel SIMD API'leriyle taşınabilir bir vektör katmanı sunuyor

Go projesi, en son iki sürümünde Tek Komut, Çok Veri (SIMD) programlaması için deneysel destek ekledi. Resmî Go blogunda yayımlanan bir yazıya göre Go 1.26, amd64 için bir SIMD API'si tanıtırken, Go 1.26 kapsamını arm64'ye (NEON aracılığıyla) ve wasm'a genişletti ve üstüne platform farklarını tamamen gizlemeyi amaçlayan yeni bir taşınabilir arayüz ekledi.

SIMD, çoğu modern CPU'da bulunan ve tek bir komutu aynı anda bir değerler vektörünün tamamına uygulayan bir donanım yeteneğidir — örneğin sekiz çift float64 sayısını tek bir işlemle toplar. Blog, bunun kriptografi, veri işleme ve yapay zekâdaki işlem yoğun işleri önemli ölçüde hızlandırabileceğini ve Go'nun Green Tea çöp toplayıcısının zaten dahili olarak SIMD'den yararlanarak bellekteki canlı nesneleri daha hızlı taramak için kullandığını belirtiyor.

İki katmanlı API

Sürüm aslında birbirleriyle ilişkili iki parça içeriyor. İlki, mimariye bağımlı archsimd adlı paket, her platformun SIMD yeteneklerinin tamamını ortaya çıkarıyor. SIMD donanımı platformlar arasında o kadar farklı ki — yalnızca desteklenen işlemlerde değil, vektörlerin kendisinin nasıl temsil edildiğinde bile — bu paket mimari başına ayrı bir paket olarak var oluyor. Bazı mimariler sabit boyutlu vektörler sunarken, diğerlerinde boyut program çalışmaya başlayana kadar bilinmiyor.

Go 1.27'de yeni olan ikinci parça ise C++ için geliştirilen Highway'den esinlenmiş, deneysel, tamamen taşınabilir ve boyuttan bağımsız simd adlı paket. Bildirilen amacı, SIMD desteği olan platformlarda elle yazılmış assembly'ye yakın performans gösteren tek seferde yazılan kod üretmek, desteği olmayan platformlarda ise yetenekli bir emülasyon katmanına geri dönmek. Bloga göre simd paketi şu anda amd64'de AVX, AVX2 ve AVX512'yi, arm64'de NEON'u ve wasm'ın SIMD komutlarını hedefliyor ve diğer platformlarda her şeyi emüle ediyor; böylece bu pakete yazılan kod her zaman çalışıyor.

SIMD neden taşınabilir olmaya direniyor

Blog, tek tip bir API'nin neden zor olduğuna açıklamak için hayli yer ayırıyor. Vektör genişlikleri büyük ölçüde farklı: wasm, PowerPC ve s390x tek bir sabit 128 bit genişlik sunuyor; amd64 128, 256 ve 512 bit destekliyor; loong64 128 ve 256 bit destekliyor; riscv64, 128 ile 65.536 bit arasındaki herhangi bir ikinin kuvveti genişliğe izin veriyor ve bu genişlik yalnızca çalışma zamanında keşfedilebiliyor; arm64 ise sabit 128 bitlik NEON'u, kendisi 128 ile 2.048 bit arasında değişen değişken genişlikli SVE ile birleştiriyor.

Maskeler — işlemlerin bir vektörün yalnızca bazı elemanlarına seçmeli olarak uygulanması — en az o kadar parçalı. Bazı mimarilerin hiç maskesi yok ve bunlar bit maskeleriyle boolean işlemlerle taklit ediliyor; AVX512 ve RVV eleman başına bir bitlik özel mask register kullanıyor; SVE bayt başına bir bit kullanıyor; AVX2 ise maskelenmiş yüklemeleri ve depolamaları düz bir vektörü maske olarak destekliyor.

Temel işlemler bile tutarsız. Örneğin wasm, 64 bitlik tam sayı vektörleri için karşılaştırma sunmuyor; yeniden sıralama ve kriptografi temel işlemleri mimariye göre değişiyor. Belirli bir makinede kod ayrıca hangi özellik varyantının gerçekten mevcut olduğunu da kontrol etmesi gerekebilir — AVX mi AVX2 mi AVX512 mi, yoksa NEON mu SVE, SVE2 ya da SVE2.1 mi.

Taşınabilir paket nasıl çalışıyor

simd paketi blogda anlatılan üç bilinçli tercihle bu çeşitliliği ele alıyor: sabit boyutlu vektörleri tip sisteminden çıkarıyor, yalnızca tüm platformlarda ortak olan işlemleri destekliyor ve boşlukları diğer SIMD komutlarından kurulan verimli bir emülasyonla dolduruyor. Ekip, işlemlerin belirli bir vektör genişliğine bağlı olmayan veri işleme algoritmalarına uygun olması, donanıma eşleştiklerinde assembly düzeyinde hızda çalışması, emüle edildiklerinde zarif biçimde yavaşlaması ve okunması kolay kalması için tasarlandığını söylüyor — blogun da belirttiği gibi, bir LLM'nin üretebileceği kod için de.

Vektör tipleri basitçe ilkel tiplerin büyük harfle yazılmış çoğulları: simd.Uint8s veya simd.Float32s gibi; bunlar sıradan slice'lardan yükleniyor ve onlara depolanıyor. Blogdaki ayrıntılı bir iç çarpım örneği, vektör yüklemelerini, MulAdd ile birleştirilmiş çarpma-toplamayı ve kuyruk elemanları için kısmi yükleme yardımcısını gösteriyor. Karşılaştırmalar, vektörleri seçip filtreleyebilen Mask8s gibi tipli maske değerleri üretiyor. Bu ilk sürümün bir sınırlaması var: bir vektörün elemanlarını toplamak için ortak bir yöntem yok, bu yüzden örnek elle skaler bir değere indirgeniyor; bir sonraki sürüm için ReduceSum fonksiyonu planlanıyor.

Her iki paket de isteğe bağlıdır ve GOEXPERIMENT=simd ortam değişkeniyle etkinleştirilir.

Neden önemli

Bu API'lerden önce Go'dan SIMD'ye ulaşmanın tek yolu assembly yazmaktı; buna da bloga göre yalnızca gerçekten performans açısından kritik çekirdekler için değer biçiliyordu — yani sıradan yazılımların çoğu CPU'nun büyük kısmını boş bırakıyordu. Ana akım bir dilde taşınabilir, assembly'ye yakın hızda bir vektör arayüzü bu hesabı tüm ekosistem için değiştiriyor; parser ve codec'lerden kriptografiye ve makine öğrenmesi koduna kadar. Tasarım açıkça LLM tarafından üretilen kod için biçimlendirilmiş durumda; bu da Go ekibinin sürdürülebilir SIMD kodunun gelecekte nerede yazılacağını beklediğine dair anlamlı bir sinyal. GOEXPERIMENT arkasındaki her şeyde olduğu gibi bu API'ler deneyseldir ve hâlâ değişebilir.

  • #go
  • #simd
  • #performance
  • #programming-languages