Що таке "векторизація"?


190

Зараз декілька разів я стикався з цим терміном у matlab, fortran ... деяких інших ... але я ніколи не знайшов пояснення, що це означає, і що він робить? Тому я запитую тут, що таке векторизація, і що це означає, наприклад, що "цикл векторизований"?


1
@geoffspear Посилання, здається, було переміщено на en.wikipedia.org/wiki/Array_programming
Мені подобається

Відповіді:


225

У багатьох процесорах є набори інструкцій "вектор" або "SIMD", які застосовують одну й ту ж операцію одночасно до двох, чотирьох або більше фрагментів даних. Сучасні чіпи x86 мають інструкції SSE, багато чіпів PPC мають інструкції "Altivec", і навіть деякі чіпи ARM мають векторний набір інструкцій, який називається NEON.

"Векторизація" (спрощена) - це процес перезапису циклу таким чином, що замість обробки одного елемента масиву N разів, він обробляє (скажімо) 4 елементи масиву одночасно N / 4 рази.

(Я вибрав 4, тому що саме те, що сучасне апаратне забезпечення, найімовірніше, безпосередньо підтримує; термін "векторизація" також використовується для опису перетворення програмного забезпечення вищого рівня, де ви можете просто абстрагувати цикл і просто описати роботу з масивами замість елементів які їх складають)


Різниця між векторизацією та розкручуванням циклу: Розглянемо наступний дуже простий цикл, який додає елементи двох масивів та зберігає результати до третього масиву.

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

Розгортання цього циклу перетворить його на щось подібне:

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];
}

З іншого боку, векторизація цього продукує щось подібне:

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

Де "addFourThingsAtOnceAndStoreResult" є заповнювачем для будь-яких внутрішніх (-ів), які ваш компілятор використовує для визначення векторних інструкцій. Зауважте, що деякі компілятори здатні автоматично векторизувати дуже прості петлі, як це, що часто можна включити за допомогою параметра компіляції. Більш складні алгоритми все ще потребують допомоги програміста для створення хорошого векторного коду.


11
Яка різниця між цим та розмотуванням / розкручуванням циклу?
Джеремі Пауелл

1
Чи не правда, що компілятор мав би простішу роботу з автоматичною векторизацією розкрученого циклу?
Нікос Афанасьоу

@NikosAthanasiou: Це правдоподібно, але загалом кажучи, компілятор повинен мати можливість автоматичного перегляду будь-якого циклу, оскільки вони обоє досить прості.
Стівен Канон

1
@StephenCanon Як можна перевірити чи векторизовані деякі лінії? Якщо можна використовувати objdump, що б шукати у висновку objdump?
користувач1823664

3
@Shuklaswag: векторизація - це те, що компілятори можуть зробити для вас, але це також те, що програмісти явно роблять самі. ОС не бере участь.
Стівен Канон

32

Векторизація - це термін перетворення скалярної програми у векторну програму. Векторизовані програми можуть виконувати кілька операцій з однієї інструкції, тоді як скаляр може працювати одразу лише на операндах.

З Вікіпедії :

Скалярний підхід:

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

Векторизований підхід:

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

хіба це по суті не є скалярним підходом? У вас синтаксис і цикл просування в іншому, але під ним ви все ще множите 4 рази. Але якось це буде швидше, ймовірно, процесор має вказівки, які роблять певний трюк під назвою Vectorization.
mskw

Схоже, я відповім на власне запитання тут. Синтаксис у підході векторизації, коли компілятор побачить це, він перетворить його в оптимізовані інструкції процесора, що множить вектори. Як SIMD.
mskw

10

Це стосується здатності робити одну математичну операцію за списком - або "вектором" чисел за один крок. Ви часто бачите це з Fortran, оскільки це пов'язано з науковими обчисленнями, які пов'язані із суперкомп'ютером, де вперше з'явилася векторизована арифметика. Нині майже всі настільні процесори пропонують певну форму веризованої арифметики за допомогою таких технологій, як SSE Intel. GPU також пропонують форму векторизованої арифметики.


7

Векторизація широко використовується в наукових обчисленнях, де величезні фрагменти даних потрібно ефективно обробляти.

У реальному застосуванні для програмування я знаю, що він використовується в NUMPY (не впевнений в інших).

Numpy (пакет для наукових обчислень в python) використовує векторизацію для швидкого маніпулювання n-мірним масивом, що, як правило, повільніше, якщо це робиться з вбудованими параметрами python для обробки масивів.

хоча тут є багато пояснень, ТУТ, ЩО ВЕКТОРИЗАЦІЯ ВИЗНАЧАЄТЬСЯ НА СТОРІНЦІ ДОКУМЕНТАЦІЇ

Векторизація описує відсутність явного циклу, індексації тощо у коді - ці речі відбуваються, звичайно, просто «поза кадром» в оптимізованому заздалегідь складеному коді С. Векторизований код має багато переваг, серед яких:

  1. векторний код більш стислий і легший для читання

  2. менше рядків коду, як правило, означає менше помилок

  3. код більше нагадує стандартні математичні позначення (полегшує, як правило, правильне кодування математичних конструкцій)

  4. векторизація призводить до отримання «пітонічного» коду. Без векторизації наш код був би засмічений неефективним і важким для читання циклом.


4

Векторизація простими словами означає оптимізацію алгоритму, щоб він міг використовувати інструкції SIMD в процесорах.

AVX, AVX2 і AVX512 - це набори інструкцій (intel), які виконують одну операцію над декількома даними в одній інструкції. напр. AVX512 означає, що ви можете одночасно працювати з 16 цілими значеннями (4 байти). Це означає, що якщо у вас вектор 16 цілих чисел, і ви хочете подвоїти це значення у кожному цілому числі, а потім додати до нього 10. Ви можете або завантажити значення в загальний регістр [a, b, c] 16 разів і виконати одну і ту ж операцію, або ви можете виконати одну і ту ж операцію, завантаживши всі 16 значень на регістри SIMD [xmm, ymm] і виконавши операцію один раз. Це дозволяє прискорити обчислення векторних даних.

У векторизації ми використовуємо це на нашу користь, переробляючи наші дані, щоб ми могли виконувати операції з SIMD на ньому та пришвидшити програму.

Єдина проблема векторизації - це умови обробки. Тому що умови розгалужують потік виконання. З цим можна впоратися маскуванням. За допомогою моделювання умови в арифметичній операції. напр. якщо ми хочемо додати 10 до значення, якщо воно більше 100. ми можемо будь-яке.

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

або ми можемо моделювати умову в арифметичній операції, створюючи вектор умови c,

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

це дуже тривіальний приклад, хоча ... таким чином, c - наш маскуючий вектор, який ми використовуємо для виконання бінарних операцій на основі його значення. Це дозволяє уникнути розгалуження потоку виконання та дозволяє векторизацію.

Векторизація так само важлива, як і паралелізація. Таким чином, ми повинні максимально використовувати його. Усі сучасні процесори мають інструкції SIMD для великих обчислювальних навантажень. Ми можемо оптимізувати наш код для використання цих інструкцій SIMD, використовуючи векторизацію, це аналогічно паралелізації нашого коду для роботи на декількох ядрах, доступних на сучасних процесорах.

Я хотів би залишити згадку про OpenMP, який дозволяє вам векторизувати код за допомогою прагм. Я вважаю це гарною відправною точкою. Те саме можна сказати і для OpenACC.


0

На думку Intel, я думаю, це легко зрозуміти.

Векторизація - це процес перетворення алгоритму з операції на одне значення за один раз до операції на наборі значень одночасно . Сучасні процесори забезпечують пряму підтримку векторних операцій, коли одна інструкція застосовується до декількох даних (SIMD).

Наприклад, процесор з 512 бітовим регістром міг би утримувати 16 32-бітових одноточних подвійних подвійних дій і робити один обчислення.

16 разів швидше, ніж одночасно виконувати одну інструкцію. Поєднання цього з нарізними і багатоядерними процесорами призводить до набору значень підвищення продуктивності.

Посилання https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

У Java є можливість цього включити в Jdk 15 2020 або пізно в JDK 16 на 2021 рік.

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


-4

Дивіться дві відповіді вище. Я просто хотів додати, що причина того, щоб хотіти робити векторизацію, полягає в тому, що ці операції можуть легко виконуватись паралельно суперкомп'ютерам та багатопроцесорним процесам, даючи великий приріст продуктивності. На комп’ютерах з однопроцесорними процесами збільшення продуктивності не буде


12
"На однопроцесорних комп'ютерах посилення продуктивності не буде": неправда. Більшість сучасних процесорів мають (обмежену) апаратну підтримку векторизації (SSE, Altivec. Тощо), яку називають stephentyrone), що може забезпечити значне прискорення при використанні.
sleske

дякую, я забув, що паралелізація може бути проведена і на тому рівні.
Ларрі Ватанабе
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.