Подтвердить что ты не робот

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

Несколько раз сейчас, я столкнулся с этим термином в matlab, fortran... другой... но я никогда не нашел объяснения, что это значит и что он делает? Поэтому я спрашиваю здесь, что такое векторизация, и что это значит, например, что "цикл векторизован"?

4b9b3361

Ответ 1

У многих ЦП есть наборы инструкций "вектор" или "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" является заполнителем для любых внутренних (-их), используемых вашим компилятором для указания векторных инструкций. Обратите внимание, что некоторые компиляторы могут автоматически векторизовать очень простые циклы, подобные этому, что часто можно включить с помощью параметра компиляции. Более сложные алгоритмы по-прежнему требуют помощи программиста для генерации хорошего векторного кода.

Ответ 2

Векторизация - это термин для преобразования скалярной программы в векторную программу. Векторизованные программы могут запускать несколько операций из одной команды, тогда как скаляр может работать только с парами операндов сразу.

От wikipedia:

Скалярный подход:

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

Ответ 3

Это относится к способности выполнять одиночную математическую операцию над списком - или "вектором" - чисел за один шаг. Вы часто это видите с Fortran, потому что это связано с научными вычислениями, которые связаны с суперкомпьютером, где впервые появилась векторная арифметика. В настоящее время почти все настольные процессоры предлагают некоторую форму векторизованной арифметики, используя такие технологии, как Intel SSE. Графические процессоры также предлагают форму векторизованной арифметики.

Ответ 4

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

В реальном программном приложении я знаю, что он используется в NUMPY (не уверен в других).

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

хотя тонны объяснений там, ЗДЕСЬ, ЧТО ВЕКТОРИЗАЦИЯ ОПРЕДЕЛЕНА КАК В СТРАНИЦА ДОКУМЕНТАЦИИ NUMPY

Векторизация описывает отсутствие каких-либо явных циклов, индексирования и т.д. в коде - эти вещи происходят, конечно, просто "за кулисами" в оптимизированном, предварительно скомпилированном C-коде. Векторизованный код имеет много преимуществ, среди которых:

  • векторный код более краткий и более легкий для чтения.

  • меньше строк кода обычно означает меньше ошибок

  • код более близко напоминает стандартную математическую нотацию (упрощая, как правило, правильное кодирование математического конструкты)

  • векторизация приводит к более "питоновскому" коду. Без векторизации, наш код будет усеян неэффективным и трудно читать для циклов.

Ответ 5

Простыми словами, векторизация означает оптимизацию алгоритма, чтобы он мог использовать 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.

Ответ 6

См. два ответа выше. Я просто хотел добавить, что причиной желания векторизации является то, что эти операции могут быть легко реализованы в параэлле суперкомпьютерами и мультипроцессорами, что дает большой выигрыш в производительности. На однопроцессорных компьютерах прирост производительности не будет.