Vectorización, en palabras simples, significa optimizar el algoritmo para que pueda utilizar las instrucciones SIMD en los procesadores.
AVX, AVX2 y AVX512 son los conjuntos de instrucciones (intel) que realizan la misma operación en múltiples datos en una sola instrucción. por ej. AVX512 significa que puede operar con 16 valores enteros (4 bytes) a la vez. Lo que eso significa es que si tiene un vector de 16 enteros y desea duplicar ese valor en cada número entero y luego agregarle 10. Puede cargar valores en el registro general [a, b, c] 16 veces y realizar la misma operación o puede realizar la misma operación cargando los 16 valores en los registros SIMD [xmm, ymm] y realizar la operación una vez. Esto permite acelerar el cálculo de los datos vectoriales.
En la vectorización, usamos esto para nuestra ventaja, al remodelar nuestros datos para que podamos realizar operaciones SIMD en él y acelerar el programa.
El único problema con la vectorización son las condiciones de manejo. Porque las condiciones ramifican el flujo de ejecución. Esto se puede manejar enmascarando. Al modelar la condición en una operación aritmética. p.ej. si queremos agregar 10 al valor si es mayor que 100. podemos hacerlo.
if(x[i] > 100) x[i] += 10; // this will branch execution flow.
o podemos modelar la condición en operación aritmética creando un vector de condición c,
c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask
Sin embargo, este es un ejemplo muy trivial ... por lo tanto, c es nuestro vector de enmascaramiento que usamos para realizar operaciones binarias en función de su valor. Esto evita la ramificación del flujo de ejecución y permite la vectorización.
La vectorización es tan importante como la paralelización. Por lo tanto, debemos utilizarlo lo más posible. Todos los procesadores modernos tienen instrucciones SIMD para cargas de trabajo informáticas pesadas. Podemos optimizar nuestro código para usar estas instrucciones SIMD usando vectorización, esto es similar a la paralelización de nuestro código para que se ejecute en múltiples núcleos disponibles en procesadores modernos.
Me gustaría irme con la mención de OpenMP, que me permite vectorizar el código usando pragmas. Lo considero un buen punto de partida. Lo mismo puede decirse de OpenACC.