Instrucción única, datos múltiples

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Tipo de procesamiento paralelo
Instrucción individual, múltiples datos

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 a él directamente a través de una arquitectura de conjunto de instrucciones (ISA), pero no debe confundirse con una ISA. SIMD describe computadoras con múltiples elementos de procesamiento que realizan la misma operación en múltiples puntos de datos simultáneamente.

Tales máquinas explotan el paralelismo a nivel de datos, pero no la concurrencia: hay cálculos simultáneos (paralelos), pero cada unidad ejecuta exactamente la misma instrucción en un momento dado (solo que con datos diferentes). SIMD es particularmente aplicable a tareas comunes como ajustar el contraste en una imagen digital o ajustar el volumen del 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 Flynn de 1972, 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 (fracción de tiempo). SIMT es una verdadera ejecución simultánea a nivel de hardware en paralelo.

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 ASC de Texas Instruments, 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 vectorial 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 Thinking Machines CM-1 y CM-2. Estas computadoras tenían muchos procesadores de funcionalidad limitada que trabajarían en paralelo. Por ejemplo, cada uno de los 65 536 procesadores de un solo bit en una Thinking Machines CM-2 ejecutaría la misma instrucción al mismo tiempo, lo que permitiría, 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 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 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 de MPEG. Sun Microsystems introdujo instrucciones de números enteros SIMD en su "VIS" extensiones del conjunto de instrucciones en 1995, en su microprocesador UltraSPARC I. MIPS hizo lo mismo con su sistema MDMX similar.

El primer SIMD de escritorio ampliamente implementado fue con las extensiones MMX de Intel para la arquitectura x86 en 1996. Esto provocó la introducción del sistema AltiVec, mucho más potente, en los sistemas PowerPC de Motorola y POWER de 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 están desarrolladas por Intel. AMD admite AVX y AVX2 en sus productos actuales.

Todos estos desarrollos se han orientado hacia la compatibilidad con gráficos en tiempo real y, por lo tanto, están orientados hacia el procesamiento en dos, tres o cuatro dimensiones, generalmente con longitudes de vector de entre dos y dieciséis palabras, según el tipo de datos y la arquitectura.. Cuando es necesario distinguir las nuevas arquitecturas SIMD de las más antiguas, las arquitecturas más nuevas se consideran de "vector corto" arquitecturas, ya que las supercomputadoras SIMD y vectoriales anteriores tenían longitudes vectoriales 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 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 (o resta) un valor 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 diga "recupere n píxeles" (donde n es un número que varía de un diseño a otro). Por una variedad de 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 en 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 operación add que se aplica a los datos se aplicará a 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

  • No todos los algoritmos pueden ser vectorizados fácilmente. Por ejemplo, una tarea de control de flujo como el análisis de códigos puede no beneficiarse fácilmente de SIMD; sin embargo, es teóricamente posible vectorizar comparaciones y comparaciones "batch flow" para apuntar la optimización máxima de caché, aunque esta técnica requerirá un estado más intermedio. Nota: Los sistemas Batch-pipeline (ejemplo: GPUs o gasoductos de rasterización de software) son los más ventajosos para el control de caché cuando se implementan con intrínseco SIMD, pero no son exclusivos de las funciones SIMD. Puede ser evidente una mayor complejidad para evitar la dependencia dentro de series como cadenas de código; mientras que la independencia es necesaria para la vectorización.
  • Grandes archivos de registro que aumenta el consumo de energía y el área de chip requerido.
  • Actualmente, implementar un algoritmo con instrucciones SIMD generalmente requiere trabajo humano; la mayoría de los compiladores no generan instrucciones SIMD de un programa C típico, por ejemplo. La vectorización automática en los compiladores es un área activa de investigación informática. (Comparar el procesamiento vectorial.)
  • 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 particular pueden no esperar esto. Peor: la alineación puede cambiar de una revisión o procesador "compatible" a otra.
    2. Reunir datos en los registros SIMD y dispersarlos a las ubicaciones de destino correctas es complicado (a veces que requieren operaciones de riesgo) y puede ser ineficiente.
    3. Instrucciones específicas como rotaciones o adición de tres operaciones no están disponibles en algunos conjuntos de instrucciones SIMD.
    4. Los conjuntos de instrucciones son específicos para la arquitectura: algunos procesadores carecen de instrucciones SIMD por completo, por lo que los programadores deben proporcionar implementaciones no victoriosas (o diferentes implementaciones vectorizadas) para ellos.
    5. Las 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 forma óptima en cualquier CPU dada. Además, el posible conjunto de instrucciones SIMD crece con cada nuevo tamaño de registro. Lamentablemente, por razones de apoyo heredadas, las versiones anteriores no pueden retirarse.
    6. El conjunto de instrucciones MMX temprano compartió un archivo de registro con la pila de punto flotante, que causó ineficiencias al mezclar punto flotante y código MMX. Sin embargo, SSE2 corrige esto.

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

Un aumento de un orden de magnitud en el tamaño del código no es poco común, en comparación con el código escalar o vectorial equivalente, y un orden de magnitud o mayor de efectividad (trabajo realizado por instrucción) se puede lograr con Vector Es como.

La Extensión de Vector Escalable de ARM adopta otro enfoque, conocido en la Taxonomía de Flynn como "Procesamiento Asociativo", más comúnmente conocido hoy como "Predicado" (enmascarado) SIMD. Este enfoque no es tan compacto como el procesamiento vectorial, pero sigue siendo mucho mejor que el SIMD no predicado. En la página de procesamiento de vectores se proporcionan ejemplos comparativos detallados.

Cronología

Ejemplos de supercomputadores SIMD (no incluyendo procesadores vectoriales)
AñoEjemplo
1974ILLIAC IV
1974Procesador de Array Distribuido ICL (DAP)
1976Burroughs Scientific Processor
1981Procesador paralel geométrico-aritmético de Martin Marietta (continúa en Lockheed Martin, luego en Teranex y Silicon Optix)
1983-1991Procesador de Paralelo Masivamente (MPP), de NASA/Goddard Space Flight Center
1985Máquina de conexión, modelos 1 y 2 (CM-1 y CM-2), de Thinking Machines Corporation
1987-1996MasPar MP-1 y MP-2
1991Zephyr DC de Wavetracer
2001Xplor de Pyxsys, Inc.

Hardware

El 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. Las instrucciones SIMD se pueden encontrar, en un grado u otro, en la mayoría de las CPU, incluidas AltiVec y SPE de IBM para PowerPC, las extensiones de aceleración multimedia (MAX) PA-RISC de HP, MMX de Intel y iwMMXt, SSE, SSE2, SSE3 SSSE3 y SSE4.x, 3DNow! de AMD, subsistema de video ARC de ARC, VIS y VIS2 de SPARC, MAJC de Sun, ARM' s Tecnología de neón, MIPS' MDMX (MaDMaX) y MIPS-3D. El conjunto de instrucciones de la SPU de Cell Processor, desarrollado conjuntamente por IBM, Sony y Toshiba, se basa en gran medida en SIMD. Philips, ahora NXP, desarrolló varios procesadores SIMD llamados Xetal. El Xetal cuenta con 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 bifurcarse, cargar y almacenar en 128 o 256 bits a la vez.

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

Software

El viaje ordinario de cuatro números de 8 bits. La CPU carga un número de 8 bits en R1, lo multiplica con R2, y luego guarda la respuesta de R3 de vuelta a RAM. Este proceso se repite para cada número.
El trío SIMD 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 de vuelta a la RAM. En teoría, la velocidad puede ser multiplicada 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 lenta al principio, 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ían 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 a menudo también carecían 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 confundieron un poco las cosas, pero hoy el sistema parece haberse calmado (después de que AMD adoptara SSE) y los compiladores más nuevos deberían dar como resultado más software habilitado para SIMD. Intel y AMD ahora brindan 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, aunque entró en el mercado SIMD más tarde que el resto. AltiVec ofreció un sistema rico y se puede programar utilizando compiladores cada vez más sofisticados de Motorola, IBM y GNU, por lo que rara vez se necesita la programación en lenguaje ensamblador. Además, Apple mismo proporcionó muchos de los sistemas que se beneficiarían de SIMD, por ejemplo, iTunes y QuickTime. Sin embargo, en 2006, las computadoras Apple se trasladaron a los procesadores Intel x86. Las API y las herramientas de desarrollo (XCode) de Apple se modificaron para admitir SSE2 y SSE3, así como también AltiVec. Apple fue el comprador dominante de chips PowerPC de IBM y Freescale Semiconductor y, aunque abandonaron la plataforma, continúa el desarrollo de AltiVec en varios diseños PowerPC y Power ISA de Freescale e IBM.

SIMD dentro de un registro, o SWAR, es una variedad 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 admite SIMD directamente.

Interfaz del 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 brindan extensiones ampliamente adoptadas por los compiladores que apuntan a sus CPU. (Las operaciones más complejas son 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 caja pack_simd de Rust usa esta interfaz, al igual que Swift 2.0+.

C++ tiene una interfaz experimental std::experimental::simd que funciona de manera similar a la extensión GCC. La libcxx de LLVM parece implementarlo. Para GCC y libstdc++, está disponible una biblioteca contenedora que se basa en la extensión GCC.

Microsoft agregó SIMD a.NET en RyuJIT. El paquete System.Numerics.Vector, disponible en NuGet, implementar 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 a bucles simples.

En lugar de proporcionar un tipo de datos SIMD, también se puede insinuar a los compiladores que vectoricen automáticamente algunos bucles, lo que podría tomar algunas afirmaciones sobre la falta de dependencia de datos. Esto no es tan flexible como la manipulación directa de variables SIMD, pero es más fácil de usar. OpenMP 4.0+ tiene una sugerencia #pragma omp simd. Esta interfaz OpenMP ha reemplazado un amplio conjunto de extensiones no estándar, incluida la #pragma simd., GCC's #pragma GCC ivdep, y muchos más.

Múltiples versiones de SIMD

Por lo general, se espera que el software de consumo funcione en una variedad de CPU que cubren 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 utilice 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 (despacho dinámico). Hay dos campos principales de soluciones:

  • Función multi-versión (FMV): una subrutina en el programa o una biblioteca es duplicada y compilada para muchas extensiones de conjunto de instrucciones, y el programa decide cuál utilizar a tiempo de ejecución.
  • Biblioteca multi-versión (LMV): toda la biblioteca de programación está duplicada para muchas extensiones de conjunto de instrucciones, y el sistema operativo o el programa decide cuál de carga a tiempo de ejecución.

FMV, codificado manualmente en lenguaje ensamblador, se usa con bastante frecuencia en varias bibliotecas críticas para el rendimiento, como glibc y libjpeg-turbo. Intel C++ Compiler, GNU Compiler Collection desde GCC 6 y Clang desde clang 7 permiten un enfoque simplificado, en el que el compilador se ocupa de la duplicación y selección de funciones. GCC y clang requieren etiquetas explícitas target_clones en el código para "clon" funciones, mientras que ICC lo hace automáticamente (bajo la opción de línea de comandos / Qax). El lenguaje de programación Rust también es compatible con FMV. La configuración es similar a GCC y Clang en que el código define qué conjuntos de instrucciones compilar, pero la clonación se realiza manualmente mediante la inserción.

Como el uso de FMV requiere la modificación del código en GCC y Clang, los proveedores suelen utilizar la creación de versiones múltiples de la biblioteca: esto es más fácil de lograr, ya que solo es necesario cambiar los modificadores del compilador. Glibc admite LMV y esta funcionalidad es adoptada por el proyecto Clear Linux respaldado por Intel.

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, lo que llevó los beneficios de SIMD a los programas web por primera vez. La interfaz consta de dos tipos:

  • Float32x4, 4 valores de punto 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 sobrecarga. Esto es similar a los intrínsecos de C y C++. Los puntos de referencia para la multiplicación de matrices de 4 × 4, la transformación de vértices en 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 sigue 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 habilitar la compilación de programas de C++ que hacen uso de intrínsecos SIMD o código vectorial de estilo GCC para la API SIMD de JavaScript, lo que resulta en aceleraciones equivalentes en comparación con el código escalar. También admite (y ahora prefiere) la propuesta SIMD de 128 bits de WebAssembly.

Aplicaciones comerciales

Aunque en general ha resultado difícil encontrar aplicaciones comerciales sostenibles para los 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 encarnaciones recientes de GAPP se han convertido en una poderosa herramienta en aplicaciones de procesamiento de video en tiempo real, como conversión entre varios estándares de video y frecuencias de cuadro (NTSC a/desde PAL, NTSC a/desde formatos HDTV, etc.), desentrelazado, imagen reducción de ruido, compresión de video adaptativa y mejora de imagen.

Una aplicación más omnipresente para SIMD se encuentra en los videojuegos: casi todas las consolas de videojuegos modernas desde 1998 han incorporado un procesador SIMD en alguna parte de su arquitectura. La PlayStation 2 era inusual en el sentido de que una de sus unidades de vector flotante podía funcionar como un DSP autónomo que ejecutaba su propio flujo de instrucciones, o como un coprocesador impulsado por instrucciones ordinarias de 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. Direct3D 9.0 de Microsoft ahora elige implementaciones específicas del procesador en tiempo de ejecución de sus propias operaciones matemáticas, incluido el uso de instrucciones compatibles con SIMD.

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 tipo SIMD para usar en dispositivos móviles, como reproductores multimedia y teléfonos móviles.

Los procesadores SIMD comerciales de mayor escala están disponibles en ClearSpeed Technology, Ltd. y Stream Processors, Inc. El CSX600 (2004) de ClearSpeed tiene 96 núcleos cada uno con dos unidades de punto flotante de doble precisión, mientras que el CSX700 (2008) tiene 192. Stream Processors está dirigido por el arquitecto informático Bill Dally. Su procesador Storm-1 (2007) contiene 80 núcleos SIMD controlados por una CPU MIPS.

Contenido relacionado

Entorno de desarrollo integrado

Telecomunicaciones en Chile

AI-completa

Más resultados...
Tamaño del texto:
Copiar