SIMD - SIMD

Instrucción única, datos múltiples

Instrucción única, datos múltiples ( SIMD ) es un tipo de procesamiento paralelo en la taxonomía de Flynn . SIMD puede ser interno (parte del diseño del hardware) y se puede acceder directamente a él a través de una arquitectura de conjunto de instrucciones (ISA): no debe confundirse con un ISA. SIMD describe computadoras con múltiples elementos de procesamiento que realizan la misma operación en múltiples puntos de datos simultáneamente.

Estas máquinas explotan el paralelismo a nivel de datos , pero no la concurrencia : hay cálculos simultáneos (paralelos), pero cada unidad realiza exactamente la misma instrucción en un momento dado (solo con datos diferentes). SIMD es particularmente aplicable a tareas comunes como ajustar el contraste en una imagen digital o ajustar el volumen de audio digital . La mayoría de los diseños de CPU modernos incluyen instrucciones SIMD para mejorar el rendimiento del uso multimedia . SIMD tiene tres subcategorías diferentes en la taxonomía de 1972 de Flynn , una de las cuales es SIMT . SIMT no debe confundirse con subprocesos de software o subprocesos de hardware , los cuales son tareas de tiempo compartido (tiempo dividido). SIMT es una verdadera ejecución paralela a nivel de hardware.

Historia

El primer uso de las instrucciones SIMD fue en el ILLIAC IV , que se completó en 1966.

SIMD fue la base para las supercomputadoras vectoriales de principios de la década de 1970, como la CDC Star-100 y la Texas Instruments ASC , que podían operar en un "vector" de datos con una sola instrucción. El procesamiento de vectores fue especialmente popularizado por Cray en las décadas de 1970 y 1980. Las arquitecturas de procesamiento de vectores ahora se consideran separadas de las computadoras SIMD: la Taxonomía de Duncan las incluye donde la Taxonomía de Flynn no lo hace, debido al trabajo de Flynn (1966, 1972) anterior al Cray-1 (1977).

La primera era de las computadoras SIMD modernas se caracterizó por supercomputadoras de estilo de procesamiento masivamente paralelo , como las Thinking Machines CM-1 y CM-2 . Estas computadoras tenían muchos procesadores de funcionalidad limitada que funcionarían en paralelo. Por ejemplo, cada uno de los 65,536 procesadores de un solo bit en un Thinking Machines CM-2 ejecutaría la misma instrucción al mismo tiempo, permitiendo, por ejemplo, combinar lógicamente 65,536 pares de bits a la vez, usando una red conectada a un hipercubo o RAM dedicada al procesador para encontrar sus operandos. La supercomputación se alejó del enfoque SIMD cuando los enfoques MIMD escalares económicos basados ​​en procesadores básicos como el Intel i860 XP se volvieron más poderosos y el interés en SIMD disminuyó.

La era actual de los procesadores SIMD surgió del mercado de las computadoras de escritorio en lugar del mercado de las supercomputadoras. A medida que los procesadores de escritorio se volvieron lo suficientemente potentes como para admitir juegos en tiempo real y procesamiento de audio / video durante la década de 1990, creció la demanda de este tipo particular de potencia informática, y los proveedores de microprocesadores recurrieron a SIMD para satisfacer la demanda. Hewlett-Packard introdujo las instrucciones MAX en las computadoras de escritorio PA-RISC 1.1 en 1994 para acelerar la decodificación MPEG. Sun Microsystems introdujo instrucciones de números enteros SIMD en sus extensiones de conjunto de instrucciones " VIS " en 1995, en su microprocesador UltraSPARC I. MIPS siguió su ejemplo con su sistema MDMX similar .

El primer SIMD de escritorio ampliamente implementado fue con las extensiones MMX de Intel a la arquitectura x86 en 1996. Esto provocó la introducción del sistema AltiVec mucho más poderoso en los sistemas POWER de Motorola PowerPC e IBM . Intel respondió en 1999 presentando el nuevo sistema SSE . Desde entonces, ha habido varias extensiones de los conjuntos de instrucciones SIMD para ambas arquitecturas. Las extensiones vectoriales avanzadas AVX, AVX2 y AVX-512 son desarrolladas por Intel. AMD admite AVX y AVX2 en sus productos actuales.

Todos estos desarrollos se han orientado al soporte de gráficos en tiempo real y, por lo tanto, están orientados al procesamiento en dos, tres o cuatro dimensiones, generalmente con longitudes vectoriales de entre dos y dieciséis palabras, según el tipo de datos y la arquitectura. Cuando es necesario distinguir las arquitecturas SIMD nuevas de las antiguas, las arquitecturas más nuevas se consideran arquitecturas de "vector corto", ya que las supercomputadoras SIMD y vectoriales anteriores tenían longitudes de vector de 64 a 64.000. Una supercomputadora moderna es casi siempre un grupo de computadoras MIMD, cada una de las cuales implementa instrucciones SIMD (de vector corto).

Ventajas

Una aplicación que puede aprovechar SIMD es aquella en la que se agrega (o se resta) el mismo valor a una gran cantidad de puntos de datos, una operación común en muchas aplicaciones multimedia . Un ejemplo sería cambiar el brillo de una imagen. Cada píxel de una imagen consta de tres valores para el brillo de las partes roja (R), verde (G) y azul (B) del color. Para cambiar el brillo, los valores R, G y B se leen de la memoria, se les suma un valor (o se les resta) y los valores resultantes se vuelven a escribir en la memoria. Los DSP de audio también, para el control de volumen, multiplicarían los canales izquierdo y derecho simultáneamente.

Con un procesador SIMD hay dos mejoras en este proceso. Por un lado, se entiende que los datos están en bloques y se pueden cargar varios valores a la vez. En lugar de una serie de instrucciones que digan "recupere este píxel, ahora recupere el siguiente píxel", un procesador SIMD tendrá una única instrucción que dirá efectivamente "recuperar n píxeles" (donde n es un número que varía de un diseño a otro). Por diversas razones, esto puede llevar mucho menos tiempo que recuperar cada píxel individualmente, como con un diseño de CPU tradicional.

Otra ventaja es que la instrucción opera con todos los datos cargados en una sola operación. En otras palabras, si el sistema SIMD funciona cargando ocho puntos de datos a la vez, la addoperación que se aplica a los datos ocurrirá en los ocho valores al mismo tiempo. Este paralelismo es independiente del paralelismo proporcionado por un procesador superescalar ; los ocho valores se procesan en paralelo incluso en un procesador no superescalar, y un procesador superescalar puede realizar múltiples operaciones SIMD en paralelo.

Desventajas

Fuera de las áreas y usos especializados, para los cuales SIMD tiene grandes ahorros, las desventajas de SIMD cuando se usa para computación de propósito general no pueden ser exageradas.

  • No todos los algoritmos se pueden vectorizar fácilmente. Por ejemplo, una tarea de control de flujo pesado como el análisis de código puede no beneficiarse fácilmente de SIMD; sin embargo, teóricamente es posible vectorizar las comparaciones y el "flujo por lotes" para apuntar a la máxima optimización de la caché, aunque esta técnica requerirá un estado más intermedio. Nota: Los sistemas de canalización por lotes (ejemplo: GPU o canalizaciones de rasterización de software) son más ventajosos para el control de caché cuando se implementan con elementos intrínsecos de SIMD, pero no son exclusivos de las funciones de SIMD. Puede resultar evidente una mayor complejidad para evitar la dependencia dentro de series tales como cadenas de códigos; mientras que se requiere independencia para la vectorización.
  • Archivos de registro grandes que aumentan el consumo de energía y el área de chip requerida.
  • Actualmente, implementar un algoritmo con instrucciones SIMD generalmente requiere trabajo humano; la mayoría de los compiladores no generan instrucciones SIMD a partir de un programa C típico , por ejemplo. La vectorización automática en compiladores es un área activa de investigación en ciencias de la computación. (Compare el procesamiento de vectores ).
  • La programación con conjuntos de instrucciones SIMD particulares puede implicar numerosos desafíos de bajo nivel.
    1. SIMD puede tener restricciones en la alineación de datos ; los programadores familiarizados con una arquitectura en particular pueden no esperar esto. Peor: la alineación puede cambiar de una revisión o un procesador "compatible" a otro.
    2. Recopilar datos en registros SIMD y distribuirlos en las ubicaciones de destino correctas es complicado (a veces requiere operaciones de permutación ) y puede ser ineficaz.
    3. Las instrucciones específicas como rotaciones o suma de tres operandos no están disponibles en algunos conjuntos de instrucciones SIMD.
    4. Los conjuntos de instrucciones son específicos de la arquitectura: algunos procesadores carecen por completo de instrucciones SIMD, por lo que los programadores deben proporcionar implementaciones no vectorizadas (o diferentes implementaciones vectorizadas) para ellos.
    5. Diferentes arquitecturas proporcionan diferentes tamaños de registro (por ejemplo, 64, 128, 256 y 512 bits) y conjuntos de instrucciones, lo que significa que los programadores deben proporcionar múltiples implementaciones de código vectorizado para operar de manera óptima en cualquier CPU dada. Además, el posible conjunto de instrucciones SIMD crece con cada nuevo tamaño de registro. Desafortunadamente, por razones de soporte heredado, las versiones anteriores no se pueden retirar.
    6. El primer conjunto de instrucciones MMX compartía un archivo de registro con la pila de coma flotante, lo que causaba ineficiencias al mezclar código de coma flotante y MMX. Sin embargo, SSE2 corrige esto.

Para solucionar los problemas 1 y 5, la extensión vectorial de RISC-V utiliza un enfoque alternativo: en lugar de exponer los detalles del nivel de subregistro al programador, el conjunto de instrucciones los abstrae como unos pocos "registros vectoriales" que usan el mismo interfaces en todas las CPU con este conjunto de instrucciones. El hardware se encarga de todos los problemas de alineación y "extracción de bandas" de bucles. Las máquinas con diferentes tamaños de vector podrían ejecutar el mismo código. LLVM llama a este tipo de vector "vscale".

Las desventajas de SIMD en comparación con el procesamiento vectorial e incluso el procesamiento escalar para uso general no pueden exagerarse. Un aumento de orden de magnitud en el tamaño del código no es infrecuente, en comparación con el código escalar equivalente o vector equivalente, y un orden de magnitud o mayor eficacia (trabajo realizado por instrucción) se puede lograr con las ISA vectoriales

La extensión vectorial escalable de ARM adopta otro enfoque, conocido en la taxonomía de Flynn como "procesamiento asociativo", más comúnmente conocido hoy como SIMD "predicado" (enmascarado) . Este enfoque no es tan compacto como el procesamiento vectorial, pero es mucho mejor que el SIMD no predicado. Se dan ejemplos comparativos detallados en la página de procesamiento de vectores .

Cronología

Ejemplos de supercomputadoras SIMD (sin incluir procesadores vectoriales ):

Hardware

SIMD de pequeña escala (64 o 128 bits) se hizo popular en las CPU de uso general a principios de la década de 1990 y continuó hasta 1997 y más tarde con Motion Video Instructions (MVI) para Alpha . Instrucciones SIMD se pueden encontrar, en un grado u otro, en la mayoría de las CPU, incluyendo IBM 's AltiVec y SPE para PowerPC , HP ' s PA-RISC Multimedia eXtensiones de aceleración (MAX), Intel 's MMX y iwMMXt , SSE , SSE2 , SSE3 SSSE3 y SSE4.x , AMD 's 3DNow! , ARC 'ARC subsistema de vídeo s, SPARC ' s VIS y VIS2, Sun 's MAJC , ARM 's de neón de la tecnología, MIPS ' MDMX (Madmax) y MIPS-3D . La IBM, Sony, Toshiba co-desarrollada Cell Processor 's SPU conjunto de instrucciones' s se basa en gran medida SIMD. Philips , ahora NXP , desarrolló varios procesadores SIMD llamados Xetal . El Xetal tiene 320 elementos de procesador de 16 bits especialmente diseñados para tareas de visión.

Las unidades de procesamiento de gráficos (GPU) modernas suelen ser implementaciones SIMD amplias, capaces de ramificar, cargar y almacenar en 128 o 256 bits a la vez.

Las últimas instrucciones de Intel AVX-512 SIMD ahora procesan 512 bits de datos a la vez.

Software

La triplicación ordinaria de cuatro números de 8 bits. La CPU carga un número de 8 bits en R1, lo multiplica por R2 y luego guarda la respuesta de R3 en la RAM. Este proceso se repite para cada número.
El SIMD triplicado de cuatro números de 8 bits. La CPU carga 4 números a la vez, los multiplica todos en una multiplicación SIMD y los guarda todos a la vez en la RAM. En teoría, la velocidad se puede multiplicar por 4.

Las instrucciones SIMD se utilizan ampliamente para procesar gráficos 3D, aunque las tarjetas gráficas modernas con SIMD integrado han asumido en gran medida esta tarea de la CPU. Algunos sistemas también incluyen funciones de permutación que vuelven a empaquetar elementos dentro de vectores, lo que los hace particularmente útiles para el procesamiento y la compresión de datos. También se utilizan en criptografía. La tendencia de la computación de propósito general en GPU ( GPGPU ) puede conducir a un uso más amplio de SIMD en el futuro.

La adopción de los sistemas SIMD en el software de las computadoras personales fue al principio lenta debido a una serie de problemas. Una fue que muchos de los primeros conjuntos de instrucciones SIMD tendían a ralentizar el rendimiento general del sistema debido a la reutilización de los registros de coma flotante existentes. Otros sistemas, como MMX y 3DNow! , ofrecía soporte para tipos de datos que no eran interesantes para una amplia audiencia y tenían costosas instrucciones de cambio de contexto para cambiar entre el uso de los registros FPU y MMX . Los compiladores también carecían a menudo de soporte, lo que requería que los programadores recurrieran a la codificación en lenguaje ensamblador .

SIMD en x86 tuvo un comienzo lento. La introducción de 3DNow! por AMD y SSE por Intel confunden un poco las cosas, pero hoy el sistema parece haberse estabilizado (después de que AMD adoptó SSE) y los compiladores más nuevos deberían dar como resultado más software habilitado para SIMD. Intel y AMD ahora proporcionan bibliotecas matemáticas optimizadas que usan instrucciones SIMD, y han comenzado a aparecer alternativas de código abierto como libSIMD , SIMDx86 y SLEEF (ver también libm ).

Apple Computer tuvo algo más de éxito, a pesar de que ingresaron al mercado SIMD más tarde que el resto. AltiVec ofrecía un sistema rico y se puede programar utilizando compiladores cada vez más sofisticados de Motorola , IBM y GNU , por lo que la programación en lenguaje ensamblador rara vez es necesaria. Además, muchos de los sistemas que se beneficiarían de SIMD fueron suministrados por la propia Apple, por ejemplo, iTunes y QuickTime . Sin embargo, en 2006, las computadoras Apple se trasladaron a procesadores Intel x86. Las API y las herramientas de desarrollo ( XCode ) de Apple se modificaron para admitir SSE2 y SSE3 , así como AltiVec. Apple fue el comprador dominante de chips PowerPC de IBM y Freescale Semiconductor y, aunque abandonaron la plataforma, se continúa desarrollando AltiVec en varios diseños PowerPC y Power ISA de Freescale e IBM.

SIMD dentro de un registro , o SWAR , es una gama de técnicas y trucos que se utilizan para realizar SIMD en registros de propósito general en hardware que no proporciona ningún soporte directo para las instrucciones SIMD. Esto se puede usar para explotar el paralelismo en ciertos algoritmos incluso en hardware que no es compatible con SIMD directamente.

Interfaz de programador

Es común que los editores de los conjuntos de instrucciones SIMD hagan sus propias extensiones de lenguaje C / C ++ con funciones intrínsecas o tipos de datos especiales (con sobrecarga de operadores ) que garantizan la generación de código vectorial. Intel, AltiVec y ARM NEON proporcionan extensiones ampliamente adoptadas por los compiladores que apuntan a sus CPU. (Las operaciones más complejas son la tarea de las bibliotecas matemáticas vectoriales).

El compilador GNU C lleva las extensiones un paso más allá al abstraerlas en una interfaz universal que se puede usar en cualquier plataforma al proporcionar una forma de definir los tipos de datos SIMD. El compilador LLVM Clang también implementa la función, con una interfaz análoga definida en el IR. La cajapack_simd de Rust usa esta interfaz, al igual que Swift 2.0+.

C ++ tiene una interfaz experimental std::experimental::simdque funciona de manera similar a la extensión GCC. Libcxx de LLVM parece implementarlo. Para GCC y libstdc ++, está disponible una biblioteca contenedora que se construye sobre la extensión GCC.

Microsoft agregó SIMD a .NET en RyuJIT. El System.Numerics.Vectorpaquete, disponible en NuGet, implementa tipos de datos SIMD. Java también tiene una nueva API propuesta para instrucciones SIMD disponible en OpenJDK 17 en un módulo de incubadora. También tiene un mecanismo de respaldo seguro en CPU no compatibles para bucles simples.

En lugar de proporcionar un tipo de datos SIMD, también se puede sugerir a los compiladores que auto-vectoricen algunos bucles, posiblemente tomando algunas afirmaciones sobre la falta de dependencia de datos. Esto no es tan flexible como manipular directamente variables SIMD, pero es más fácil de usar. OpenMP 4.0+ tiene una #pragma omp simdpista. Cilk tiene una característica similar #pragma simd. GCC y Clang también tienen sus propios pragmas privados para hacer que los bucles sean vectorizables, pero los tres han quedado obsoletos gracias a OpenMP.

Versiones múltiples de SIMD

Por lo general, se espera que el software de consumo funcione en una variedad de CPU que abarquen varias generaciones, lo que podría limitar la capacidad del programador para usar nuevas instrucciones SIMD para mejorar el rendimiento computacional de un programa. La solución es incluir varias versiones del mismo código que utilizan tecnologías SIMD más antiguas o más nuevas, y elegir la que mejor se adapte a la CPU del usuario en tiempo de ejecución ( envío dinámico ). Hay dos campos principales de soluciones:

  • Función de múltiples versiones: una subrutina en el programa o una biblioteca se duplica y compila para muchas extensiones de conjuntos de instrucciones, y el programa decide cuál usar en tiempo de ejecución.
  • Versiones múltiples de la biblioteca: toda la biblioteca de programación se duplica para muchas extensiones del conjunto de instrucciones, y el sistema operativo o el programa decide cuál cargar en tiempo de ejecución.

La primera solución es compatible con Intel C ++ Compiler , GNU Compiler Collection desde GCC 6 y Clang desde clang 7. Sin embargo, dado que GCC y clang requieren target_clonesetiquetas explícitas para "clonar" funciones, una forma más fácil de hacerlo es compilar varias versiones. de la biblioteca y dejar que el sistema glibc elija uno, un enfoque adoptado por el proyecto Clear Linux respaldado por Intel.

El lenguaje de programación Rust también admite múltiples versiones. La clonación se puede realizar llamando a la función original, de modo que la alineación se haga cargo.

SIMD en la web

En 2013, John McCutchan anunció que había creado una interfaz de alto rendimiento para conjuntos de instrucciones SIMD para el lenguaje de programación Dart , llevando los beneficios de SIMD a los programas web por primera vez. La interfaz consta de dos tipos:

  • Float32x4, 4 valores de coma flotante de precisión simple.
  • Int32x4, 4 valores enteros de 32 bits.

Las instancias de estos tipos son inmutables y en código optimizado se asignan directamente a los registros SIMD. Las operaciones expresadas en Dart generalmente se compilan en una sola instrucción sin gastos generales. Esto es similar a los intrínsecos de C y C ++. Los puntos de referencia para la multiplicación de matrices 4 × 4 , la transformación de vértices 3D y la visualización de conjuntos de Mandelbrot muestran una aceleración cercana al 400% en comparación con el código escalar escrito en Dart.

El trabajo de McCutchan en Dart, ahora llamado SIMD.js, ha sido adoptado por ECMAScript e Intel anunció en IDF 2013 que están implementando la especificación de McCutchan tanto para V8 como para SpiderMonkey . Sin embargo, para 2017, SIMD.js se eliminó de la cola estándar de ECMAScript a favor de buscar una interfaz similar en WebAssembly . A partir de agosto de 2020, la interfaz WebAssembly permanece sin terminar, pero su función SIMD portátil de 128 bits ya se ha utilizado en muchos motores.

Emscripten, el compilador de C / C ++ a JavaScript de Mozilla, con extensiones puede permitir la compilación de programas C ++ que hacen uso de intrínsecos SIMD o código vectorial de estilo GCC para la API SIMD de JavaScript, lo que da como resultado aceleraciones equivalentes en comparación con el código escalar. También es compatible con la propuesta SIMD de 128 bits de WebAssembly.

Aplicaciones comerciales

Aunque en general ha resultado difícil encontrar aplicaciones comerciales sostenibles para procesadores solo SIMD, una que ha tenido cierto éxito es el GAPP , que fue desarrollado por Lockheed Martin y llevado al sector comercial por su spin-off Teranex . Las recientes encarnaciones de GAPP se han convertido en una poderosa herramienta en aplicaciones de procesamiento de video en tiempo real , como la conversión entre varios estándares de video y velocidades de cuadro ( NTSC a / desde PAL , NTSC a / desde formatos HDTV , etc.), desentrelazado , reducción de ruido de imagen , adaptación compresión de video y mejora de imagen.

Una aplicación más ubicua para SIMD se encuentra en los videojuegos : casi todas las consolas de videojuegos modernas desde 1998 han incorporado un procesador SIMD en algún lugar de su arquitectura. La PlayStation 2 era inusual en el sentido de que una de sus unidades flotantes vectoriales podía funcionar como un DSP autónomo ejecutando su propio flujo de instrucciones, o como un coprocesador impulsado por instrucciones ordinarias de la CPU. Las aplicaciones de gráficos 3D tienden a prestarse bien al procesamiento SIMD, ya que dependen en gran medida de operaciones con vectores de 4 dimensiones. Microsoft 's Direct3D 9,0 elige ahora en tiempo de ejecución implementaciones procesador específicas de sus propias operaciones matemáticas, incluyendo el uso de instrucciones SIMD con capacidad.

Uno de los procesadores recientes que utiliza el procesamiento vectorial es el Cell Processor desarrollado por IBM en cooperación con Toshiba y Sony . Utiliza varios procesadores SIMD (una arquitectura NUMA , cada uno con almacenamiento local independiente y controlado por una CPU de propósito general) y está orientado a los enormes conjuntos de datos que requieren las aplicaciones de procesamiento de video y 3D. Se diferencia de las ISA tradicionales por ser SIMD desde cero sin registros escalares separados.

Ziilabs produjo un procesador de tipo SIMD para su uso en dispositivos móviles, como reproductores multimedia y teléfonos móviles.

Procesadores SIMD escala comercial más grande están disponibles en ClearSpeed Technology, Ltd. y Stream Processors, Inc. ClearSpeed CSX600 's (2004) tiene 96 núcleos, cada uno con dos puntos de flotación de doble precisión, mientras que el CSX700 (2008) tiene 192. Stream Processors es dirigido por el arquitecto informático Bill Dally . Su procesador Storm-1 (2007) contiene 80 núcleos SIMD controlados por una CPU MIPS.

Ver también

Referencias

enlaces externos