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