Мэдээ

Go хэлэнд Assembly бичих шаардлагагүй боллоо: Платформоос хараат бус SIMD албан ёсоор гарлаа

TOGTOKHTOGTOKH·2026 оны есдүгээр сарын 25·3 үзсэн·
Go хэлэнд Assembly бичих шаардлагагүй боллоо: Платформоос хараат бус SIMD албан ёсоор гарлаа

Сүүлийн арван гаруй жилийн турш Go хэлээр өндөр ачаалалтай, тооцоолол их шаардсан систем хөгжүүлж буй инженерүүдэд тулгардаг нэгэн том "өвдөлт" байсан нь техник хангамжийн түвшний вектор зааварчилгаа буюу SIMD (Single Instruction Multiple Data)-ийг ашиглах явдал байв. Хэрэв та өгөгдлийн сангийн индексчлэл, криптограф, шахалт эсвэл AI векторын тооцооллыг хурдасгахыг хүсвэл тусдаа Go Assembly (.s) файл бичихээс өөр сонголт бараг байдаггүй байлаа.

Go багийн Дэвид Чейз (David Chase), Жунъян Шао (Junyang Shao) нар албан ёсны Go блог дээрээ архитектур харгалзахгүй, зөөврийн (platform-independent, size-agnostic) simd багцыг дэлгэрэнгүй танилцууллаа.

Энэхүү шинэчлэл нь Go хэлийг C++ болон Rust-ийн нэгэн адил өндөр гүйцэтгэлтэй тооцоолол (HPC), том хэмжээний өгөгдөл боловсруулалт, хиймэл оюуны дэд бүтцийн салбарт шинэ шатанд гаргах маш чухал алхам болж байна.


Асуудал юунд байв: Go Assembly ба арчилгааны там

Орчин үеийн бараг бүх CPU нэг цагийн циклээр олон тооны өгөгдөл дээр нэгэн зэрэг үйлдэл хийх чадвартай SIMD регистрүүдтэй байдаг. Жишээ нь, 8 ширхэг float64 утгыг ердөө ганцхан заавраар хооронд нь нэмэх боломжтой. Энэ нь алгоритмын гүйцэтгэлийг хэд дахин, зарим тохиолдолд 10 дахин өсгөх боломжийг олгодог.

Гэвч уламжлалт Go дээр үүнийг ашиглахад дараах бэрхшээлүүд тулгардаг байв:

  1. Архитектурын тархай бутархай байдал: Интел/AMD процессор дээр AVX-2 эсвэл AVX-512 ажилладаг бол Apple Silicon болон орчин үеийн серверүүдийн ARM чип дээр NEON эсвэл SVE зааварчилгаа хэрэгтэй болдог. Хөгжүүлэгч процессор бүрд тусад нь Assembly бичих шаардлага гардаг.
  2. Компиляторын оновчлол алдагдах: Go хэлний функц Assembly түвшинд бичигдсэн үед компилятор уг функцийг inline хийж чаддаггүй. Үүнээс үүдэн функц дуудах зардал нэмэгдэж, жижиг хэмжээний тооцоолол дээр SIMD-ийн ашиг гарахгүй шахам болдог.
  3. Код арчлахад төвөгтэй: Assembly кодод алдаа гаргах магадлал маш өндөр бөгөөд аюулгүй байдлын аудит хийх, багийн бусад гишүүд ойлгоход хүндрэлтэй байдаг.

Go 1.26 болон 1.27 хувилбаруудад архитектураас хамаарсан simd/archsimd туршилтын багцыг оруулж байсан ч энэ нь 플랫폼 бүрийн онцлогт тохируулж кодлох шаардлагыг бүрэн арилгаагүй юм.


Шинэ шийдэл: Google Highway-аас санаа авсан зөөврийн simd

Go багийнхан C++ ертөнц дэх алдарт Google Highway сангаас санаа авч, цоо шинэ архитектурыг бүтээжээ. Тэдний зорилго нь тун тодорхой: "Нэг л удаа цэвэр Go хэлээр бичээд, тухайн техник хангамжийн дээд хурдыг авах".

Энэхүү шинэ simd багц нь дараах гол зарчмаар ажилладаг:

  • Хэмжээг хатуу заагаагүй вектор төрлүүд: Процессорын вектор регистр 128 бит үү, 256 бит үү, 512 бит үү гэдгийг хөгжүүлэгч заавал урьдчилж мэдэх шаардлагагүй. simd.Int32s, simd.Float64s зэрэг төрлүүд нь ажиллаж буй техник хангамжийн хамгийн оновчтой уртыг автоматаар ашигладаг.
  • Өргөн дэмжлэг: Одоогоор amd64 дээрх AVX, AVX2, AVX-512, arm64 дээрх NEON, тэр байтугай хөтөч болон сервер дээрх WebAssembly-ийн WASM SIMD зааварчилгааг дэмжиж байна.
  • Алдаа гарахгүй Fallback (Emulation): Хэрэв таны код хуучин эсвэл SIMD дэмждэггүй систем дээр ажиллавал компилятор автоматаар энгийн Go давталтаар орлуулан (emulation) ажиллуулна. Систем нурах, build тасалдах ямар ч эрсдэлгүй.

Бодит гүйцэтгэл: Системүүд хэрхэн хурдсах вэ?

Go хөгжүүлэгчдийн нийгэмлэгийн эхний туршилтууд маш өндөр үр дүнг үзүүлж байна.

  • Криптограф ба сүлжээ: ChaCha20 зэрэг шифрлэлтийн алгоритмд уг багцыг ашиглахад өмнөх энгийн хэрэгжүүлэлтээс 7.5 дахин хурдан ажилласан байна.
  • Текст хайлт ба индексинг: Түгээмэл fzf хайлтын хэрэгслийн ашигладаг вектор хайлтын аргуудыг хэрэгжүүлснээр CPU-ийн ачаалал бараг 4 дахин буурчээ.
  • Go-ийн өөрийн бүтэц: Go-ийн шинэ үеийн Green Tea Garbage Collector болон Swiss Table хэлбэрийн map бүтцийн дотоод хэрэгжүүлэлт санах ойн скан хийх, hash бодох ажлаа хэдийнэ уг SIMD бүтцэд шилжүүлээд эхэлсэн байна.
// Жишээ: GOEXPERIMENT=simd горимд ажиллах хялбар вектор нийлбэр
package main

import "simd"

func VectorAdd(a, b, dst []float32) {
    // Техник хангамжийн дэмжих векторын хэмжээгээр боловсруулах
    lane := simd.Float32sLane()
    i := 0
    for ; i+lane <= len(a); i += lane {
        va := simd.LoadFloat32s(a[i:])
        vb := simd.LoadFloat32s(b[i:])
        vsum := va.Add(vb)
        vsum.Store(dst[i:])
    }
    // Үлдсэн элементүүдийг боловсруулах энгийн fallback
    for ; i < len(a); i++ {
        dst[i] = a[i] + b[i]
    }
}

Хэрхэн туршиж үзэх вэ?

Одоогоор энэхүү функц нь туршилтын шатандаа байгаа бөгөөд Go 1.27 дээр дараах флагтайгаар ашиглах боломжтой:

GOEXPERIMENT=simd go build .

Go-ийн багийн мэдээлснээр дараагийн хувилбаруудад вектор доторх бүх элементүүдийн нийлбэрийг авах simd.ReduceSum зэрэг илүү өндөр түвшний функцүүдийг нэмж, улмаар GOEXPERIMENT тугийг халан бүх нийтийн стандарт болгохоор зорьж байна.

Хэрэв та өөрийн back-end үйлчилгээнд их хэмжээний өгөгдөл шүүх, математик загварчлал ажиллуулах, эсвэл AI вектор хайлтын хөдөлгүүр хөгжүүлдэг бол энэхүү шинэ боломжийг заавал туршиж үзэхийг зөвлөж байна.

Эх сурвалж: The Go Blog (go.dev)

Сэтгэгдэл

Ачаалж байна...