Apa itu "vektorisasi"?

190

Beberapa kali sekarang, saya telah menemukan istilah ini di matlab, fortran ... beberapa lainnya ... tapi saya belum pernah menemukan penjelasan apa artinya, dan apa artinya? Jadi saya bertanya di sini, apa itu vektorisasi, dan apa artinya misalnya, bahwa "sebuah loop di-vektor-kan"?

Thomas Geritzma
sumber
1
@geoffspear Tautan tampaknya telah dipindahkan ke en.wikipedia.org/wiki/Array_programming
I Like to Code

Jawaban:

225

Banyak CPU memiliki set instruksi "vektor" atau "SIMD" yang menerapkan operasi yang sama secara bersamaan untuk dua, empat, atau lebih banyak data. Chip x86 modern memiliki instruksi SSE, banyak chip PPC memiliki instruksi "Altivec", dan bahkan beberapa chip ARM memiliki set instruksi vektor, yang disebut NEON.

"Vektorisasi" (disederhanakan) adalah proses penulisan ulang sebuah loop sehingga alih-alih memproses elemen tunggal dari array N kali, ia memproses (katakanlah) 4 elemen array secara bersamaan N / 4 kali.

(Saya memilih 4 karena itulah yang paling mungkin didukung oleh perangkat keras modern; istilah "vektorisasi" juga digunakan untuk menggambarkan transformasi perangkat lunak tingkat lebih tinggi di mana Anda dapat memisahkan abstrak dari loop secara bersamaan dan hanya menjelaskan pengoperasian pada array daripada elemen-elemennya). yang terdiri dari mereka)


Perbedaan antara vektorisasi dan loop terbuka: Pertimbangkan loop sangat sederhana berikut yang menambahkan elemen dari dua array dan menyimpan hasilnya ke array ketiga.

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

Membuka gulungan lingkaran ini akan mengubahnya menjadi seperti ini:

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

Vektorisasi, di sisi lain, menghasilkan sesuatu seperti ini:

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

Di mana "addFourThingsAtOnceAndStoreResult" adalah placeholder untuk intrinsik apa pun yang digunakan kompiler Anda untuk menentukan instruksi vektor. Perhatikan bahwa beberapa kompiler dapat melakukan autoisasi vektor loop yang sangat sederhana seperti ini, yang seringkali dapat diaktifkan melalui opsi kompilasi. Algoritma yang lebih kompleks masih membutuhkan bantuan dari programmer untuk menghasilkan kode vektor yang baik.

Stephen Canon
sumber
11
Apa perbedaan antara ini dan loop unwinding / unrolling?
Jeremy Powell
1
Bukankah benar bahwa kompiler akan memiliki pekerjaan yang lebih mudah secara otomatis untuk meng-vektor-kan loop yang belum dibuka?
Nikos Athanasiou
@NikosAthanasiou: Ini masuk akal, tetapi secara umum kompiler harus dapat mengotomatisasi setiap loop, karena keduanya cukup sederhana.
Stephen Canon
1
@StephenCanon bagaimana kita bisa memeriksa apakah beberapa baris telah di-vektor? Jika seseorang akan menggunakan objdump, apa yang akan dicari dalam output dari objdump?
user1823664
3
@Shuklaswag: vektorisasi adalah sesuatu yang dapat dilakukan oleh kompiler untuk Anda, tetapi juga sesuatu yang dilakukan sendiri oleh programmer. OS tidak terlibat.
Stephen Canon
32

Vektorisasi adalah istilah untuk mengubah program skalar menjadi program vektor. Program vektor dapat menjalankan beberapa operasi dari satu instruksi, sedangkan skalar hanya dapat beroperasi pada pasangan operan sekaligus.

Dari wikipedia :

Pendekatan skalar:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

Pendekatan vektor:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}
Anders
sumber
Bukankah itu pada dasarnya sama dengan pendekatan Scalar? Sintaks dan loop lanjutan Anda berbeda, tetapi di bawahnya Anda masih mengalikannya 4 kali. Tetapi entah bagaimana itu akan lebih cepat, mungkin CPU memiliki instruksi yang melakukan beberapa trik yang disebut Vectorization.
mskw
Sepertinya saya akan menjawab pertanyaan saya sendiri di sini. Sintaksis dalam pendekatan vektorisasi ketika kompilator melihat itu, itu akan menerjemahkannya ke dalam instruksi CPU yang dioptimalkan yang mengalikan vektor. Seperti SIMD.
mskw
10

Ini mengacu pada kemampuan untuk melakukan operasi matematika tunggal pada daftar - atau "vektor" - angka dalam satu langkah. Anda sering melihatnya dengan Fortran karena itu terkait dengan komputasi ilmiah, yang dikaitkan dengan superkomputer, di mana aritmatika vektor muncul pertama kali. Saat ini hampir semua CPU desktop menawarkan beberapa bentuk aritmatika vektor, melalui teknologi seperti Intel SSE. GPU juga menawarkan bentuk aritmatika vektor.

Warren Young
sumber
7

Vektorisasi sangat banyak digunakan dalam komputasi ilmiah di mana sejumlah besar data perlu diproses secara efisien.

Dalam aplikasi pemrograman nyata, saya tahu itu digunakan dalam NUMPY (tidak yakin yang lain).

Numpy (paket untuk komputasi ilmiah dalam python), menggunakan vektorisasi untuk manipulasi cepat array n-dimensi, yang umumnya lebih lambat jika dilakukan dengan opsi python bawaan untuk menangani array.

meskipun ada banyak penjelasan, DI SINI ADA VEKTORISASI YANG DITETAPKAN SEBAGAI DALAM HALAMAN DOKUMENTASI NUMPY

Vektorisasi menjelaskan tidak adanya perulangan eksplisit, pengindeksan, dll., Dalam kode - hal-hal ini terjadi, tentu saja, "di belakang layar" dalam kode C yang dioptimalkan, yang telah dikompilasi sebelumnya. Kode vektor memiliki banyak keunggulan, di antaranya adalah:

  1. kode vektor lebih ringkas dan lebih mudah dibaca

  2. lebih sedikit baris kode umumnya berarti lebih sedikit bug

  3. kode lebih menyerupai notasi matematika standar (membuatnya lebih mudah, biasanya, dengan benar mengkodekan konstruksi matematika)

  4. hasil vektorisasi lebih banyak kode "Pythonic". Tanpa vektorisasi, kode kita akan dikotori dengan tidak efisien dan sulit dibaca untuk loop.

programmer buruk
sumber
4

Vektorisasi, dengan kata sederhana, berarti mengoptimalkan algoritme sehingga dapat memanfaatkan instruksi SIMD dalam prosesor.

AVX, AVX2 dan AVX512 adalah set instruksi (intel) yang melakukan operasi yang sama pada banyak data dalam satu instruksi. untuk mis. AVX512 berarti Anda dapat beroperasi pada 16 nilai integer (4 byte) sekaligus. Apa itu artinya adalah jika Anda memiliki vektor 16 bilangan bulat dan Anda ingin menggandakan nilai itu di setiap bilangan bulat dan kemudian menambahkan 10 untuk itu. Anda dapat memuat nilai ke register umum [a, b, c] 16 kali dan melakukan operasi yang sama atau Anda dapat melakukan operasi yang sama dengan memuat semua 16 nilai ke register SIMD [xmm, ymm] dan melakukan operasi sekali. Ini memungkinkan mempercepat perhitungan data vektor.

Dalam vektorisasi kami menggunakan ini untuk keuntungan kami, dengan memperbarui data kami sehingga kami dapat melakukan operasi SIMD dan mempercepat program.

Satu-satunya masalah dengan vektorisasi adalah penanganan kondisi. Karena kondisi bercabang aliran eksekusi. Ini bisa ditangani dengan menutupi. Dengan memodelkan kondisi tersebut ke dalam operasi aritmatika. misalnya. jika kita ingin menambahkan 10 ke nilai jika lebih besar dari 100. kita juga bisa.

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

atau kita dapat memodelkan kondisi ke dalam operasi aritmatika menciptakan vektor kondisi c,

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

ini adalah contoh yang sangat sepele ... jadi, c adalah vektor masking kami yang kami gunakan untuk melakukan operasi biner berdasarkan nilainya. Ini menghindari percabangan aliran eksekusi dan memungkinkan vektorisasi.

Vektorisasi sama pentingnya dengan Paralelisasi. Jadi, kita harus memanfaatkannya sebanyak mungkin. Semua prosesor modern memiliki instruksi SIMD untuk beban kerja komputasi yang berat. Kita dapat mengoptimalkan kode kita untuk menggunakan instruksi SIMD ini menggunakan vektorisasi, ini mirip dengan memparalelkan kode kita untuk berjalan pada banyak core yang tersedia pada prosesor modern.

Saya ingin meninggalkan dengan menyebutkan OpenMP, yang memungkinkan Anda mengubah kode menggunakan pragma. Saya menganggapnya sebagai titik awal yang baik. Hal yang sama dapat dikatakan untuk OpenACC.

Antrian Pasar
sumber
0

Menurut orang Intel, saya pikir ini mudah dipahami.

Vektorisasi adalah proses mengubah algoritma dari operasi pada nilai tunggal pada suatu waktu untuk beroperasi pada satu set nilai pada satu waktu . CPU modern memberikan dukungan langsung untuk operasi vektor di mana satu instruksi diterapkan ke beberapa data (SIMD).

Sebagai contoh, CPU dengan register 512 bit dapat menampung 16 32 bit presisi tunggal ganda dan melakukan perhitungan tunggal.

16 kali lebih cepat daripada menjalankan satu instruksi pada satu waktu. Kombinasikan ini dengan threading dan multi-core CPU mengarah ke urutan peningkatan kinerja yang luar biasa.

Tautan https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

Di Jawa ada opsi untuk ini dimasukkan dalam Jdk 15 tahun 2020 atau terlambat di JDK 16 pada 2021.

https://bugs.openjdk.java.net/browse/JDK-8201271

chiperortiz
sumber
-4

Lihat dua jawaban di atas. Saya hanya ingin menambahkan bahwa alasan ingin melakukan vektorisasi adalah bahwa operasi ini dapat dengan mudah dilakukan di paraell oleh superkomputer dan multi-prosesor, menghasilkan keuntungan kinerja yang besar. Pada komputer prosesor tunggal tidak akan ada peningkatan kinerja.

Larry Watanabe
sumber
12
"Pada komputer prosesor tunggal tidak akan ada peningkatan kinerja": tidak benar. Sebagian besar prosesor modern memiliki (terbatas) dukungan perangkat keras untuk vektorisasi (SSE, Altivec, dll. Seperti dinamai oleh stephentyrone), yang dapat memberikan peningkatan signifikan saat digunakan.
sleske
terima kasih, saya lupa bahwa paralelisasi dapat dilakukan pada level itu juga.
Larry Watanabe