Topik ini membahas register ymm 256-bit beserta keluarga AVX2-nya. Register ymm memperpanjang lebar SIMD dari empat lane menjadi delapan lane 32-bit. AVX pertama hanya membawa float ke lebar 256 bit, sedangkan AVX2 melengkapinya dengan integer 256-bit dan instruksi gather yang mengumpulkan elemen dari alamat tak berurutan. Struktur register dan syarat penyelarasannya dibahas lebih dahulu, dilanjutkan dengan mekanisme gather, kemudian satu program menjalankan keduanya dan diperiksa lewat keluaran gdb yang asli.
Register ymm 256-bit#
Setiap prosesor dengan AVX menyediakan enam belas register ymm bernama ymm0 sampai ymm15, masing-masing menyimpan 256 bit atau delapan lane 32-bit. Register ymm bukan tambahan yang berdiri sendiri, melainkan perluasan dari register xmm yang sudah dikenal, karena 128 bit bawah ymm0 berbagi tempat yang sama dengan xmm0. Menulis ke ymm0 mengubah isi xmm0 juga, sedangkan menulis ke xmm0 dengan instruksi ber-VEX mengosongkan bagian atas ymm0, sehingga keduanya harus diperlakukan sebagai satu tempat penyimpanan.
Instruksi 256-bit mengenali lebarnya dari bit L pada prefiks VEX, sehingga pasangan vaddps untuk xmm dan untuk ymm berbagi mnemonic yang sama. Syarat penyelarasan juga naik seiring lebar, karena vmovaps dengan operan memori 256-bit menuntut alamat kelipatan 32 byte, dan itulah alasan arahan align 32 pada program di bagian akhir. AVX pertama hanya menyediakan float pada lebar ini, sedangkan AVX2 menambahkan instruksi integer 256-bit seperti vmovdqa dan vpaddd, sehingga pengolahan integer delapan lane menjadi mungkin tanpa memecah datanya menjadi dua register xmm. Lebar ganda ini berdampak langsung pada jumlah iterasi, karena blok data yang sama hanya membutuhkan separuh muat dan separuh operasi dibandingkan dengan versi xmm.
Instruksi gather#
Muat biasa seperti vmovaps mengambil data berurutan dari memori, sedangkan sebagian data nyata tersusun dalam urutan yang berbeda dari urutan pemrosesannya. Kebutuhan itu muncul pada tabel yang dibaca per baris padahal tersusun per kolom, atau pada pemilihan elemen tertentu dari data besar. Instruksi gather menyelesaikan kebutuhan itu dengan mengumpulkan elemen dari banyak alamat sekaligus. Bentuknya adalah vpgatherdd ymm1, [rax + ymm2*4], ymm3, yang untuk setiap lane membaca memori pada alamat rax + indeks*4 menggunakan isi lane ymm2 sebagai indeksnya, lalu menuliskan hasilnya ke lane ymm1 yang sejajar.
Operan ketiga berupa register mask, yaitu penyeleksi lane yang menentukan pengumpulan mana yang dijalankan. Lane dengan bit mask bernilai satu ikut dibaca dan diperbarui, sedangkan lane dengan bit nol dibiarkan tanpa mengakses memori sama sekali, sehingga indeks yang tidak sah pada lane nonaktif tidak memicu fault. Penyeleksian per lane juga membuat gather dapat dibatasi pada sebagian lane saja, misalnya ketika jumlah elemen yang sah tidak mengisi register penuh. Perbedaan penting dengan muat biasa adalah register mask ikut dikosongkan setelah instruksi selesai, sehingga mask tidak dapat digunakan kembali tanpa diisi kembali. Kebalikan gather, yaitu scatter yang menyebarkan isi register ke banyak alamat, tidak tersedia pada AVX2 dan baru muncul pada generasi setelahnya.
Delapan lane dan pengumpulan tak berurutan#
Program berikut menjalankan dua hal sekaligus. Pertama, delapan float dimuat ke ymm0 dan digandakan dengan satu vaddps tiga operan. Kedua, elemen integer dari array data dikumpulkan dengan vpgatherdd mengikuti urutan pada array indeks, yang memotong data menjadi dua bagian berselang-seling. Alamat dasar array ditaruh di rax terlebih dahulu karena pengalamatan gather menggabungkan register umum, register vektor indeks, dan faktor skala dalam satu operan.
default rel
section .data
align 32
suhu: dd 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0
align 32
data: dd 10, 20, 30, 40, 50, 60, 70, 80
align 32
indeks: dd 0, 2, 4, 6, 1, 3, 5, 7
section .text
global _start
_start:
vmovaps ymm0, [suhu] ; muat delapan float sekaligus
vaddps ymm0, ymm0, ymm0 ; gandakan setiap lane
lea rax, [data]
vmovdqa ymm2, [indeks] ; vektor indeks pengumpulan
vpcmpeqd ymm3, ymm3, ymm3 ; mask: semua lane aktif
vpgatherdd ymm1, [rax + ymm2*4], ymm3 ; kumpulkan data tak berurutan
mov eax, 60
xor edi, edi
syscall# rakit dan tautkan program
nasm -f elf64 avx2-ymm.asm -o avx2-ymm.o
ld avx2-ymm.o -o avx2-ymm
# hasil delapan lane, hasil gather, dan kondisi register mask
gdb -batch -ex 'break _start' -ex 'run' -ex 'stepi 6' -ex 'p $ymm0.v8_float' -ex 'p $ymm1.v8_int32' -ex 'p $ymm3.v8_int32' ./avx2-ymmBreakpoint 1 at 0x401000
Breakpoint 1, 0x0000000000401000 in _start ()
0x0000000000401025 in _start ()
$1 = {42, 44, 46, 48, 50, 52, 54, 56}
$2 = {10, 30, 50, 70, 20, 40, 60, 80}
$3 = {0, 0, 0, 0, 0, 0, 0, 0}Register ymm0 terbaca {42, 44, 46, 48, 50, 52, 54, 56}, yaitu delapan suhu yang masing-masing digandakan dalam satu instruksi, dua kali lebar empat lane pada topik register xmm. Delapan float dimuat dan digandakan tanpa satu pun struktur perulangan, sesuatu yang pada lebar 128-bit membutuhkan dua register serta dua kali pekerjaan. Register ymm1 terbaca {10, 30, 50, 70, 20, 40, 60, 80}, yaitu elemen array data yang dikumpulkan mengikuti indeks 0, 2, 4, 6, 1, 3, 5, 7, sehingga urutannya berubah menjadi dua kelompok berselang-seling tanpa satu pun perulangan per elemen. Register mask ymm3 terbaca sebagai delapan nol, bukti keluaran bahwa gather mengosongkan mask yang selesai digunakan, sesuai perilaku yang didokumentasikan. Arahan align 32 menjaga kedua array yang dimuat vmovaps dan vmovdqa pada alamat kelipatan 32 byte, sesuai syarat kedua instruksi tersebut untuk operan memorinya.
Ringkasan#
- Register ymm0 sampai ymm15 menyimpan 256 bit atau delapan lane 32-bit, dan 128 bit bawahnya berbagi tempat dengan register xmm yang bernomor sama.
- AVX1 membawa float ke 256 bit, sedangkan AVX2 melengkapinya dengan integer 256-bit seperti
vmovdqadanvpaddd. vpgatherddmengumpulkan elemen dari alamatdasar + indeks*4per lane, diseleksi oleh register mask yang ikut dikosongkan setelah instruksi selesai.- Gather jauh lebih lambat daripada muat berurutan dan scatter tidak tersedia pada AVX2.
Referensi#
- Intel 64 and IA-32 Architectures Software Developer’s Manual — Intel — Volume 1 mendokumentasikan register ymm, hubungannya dengan xmm, dan semantik instruksi gather AVX2 beserta pembaruan mask-nya.
- Intel Intrinsics Guide — Intel
— rujukan intrinsik seperti
_mm256_add_psdan_mm256_i32gather_epi32yang memetakan langsung ke instruksi ymm dan gather pada topik ini.