stringtranslate.com

Predicación (arquitectura informática)

En la arquitectura informática , la predicación es una característica que proporciona una alternativa a la transferencia condicional de control , tal como se implementa mediante instrucciones de máquina de bifurcación condicional . La predicación funciona al tener instrucciones condicionales ( predicadas ) que no son de bifurcación asociadas con un predicado , un valor booleano utilizado por la instrucción para controlar si la instrucción puede modificar el estado arquitectónico o no. Si el predicado especificado en la instrucción es verdadero, la instrucción modifica el estado arquitectónico; de lo contrario, el estado arquitectónico no cambia. Por ejemplo, una instrucción de movimiento predicada (un movimiento condicional) solo modificará el destino si el predicado es verdadero. Por lo tanto, en lugar de usar una bifurcación condicional para seleccionar una instrucción o una secuencia de instrucciones para ejecutar en función del predicado que controla si se produce la bifurcación, las instrucciones que se ejecutarán se asocian con ese predicado, de modo que se ejecutarán, o no, en función de si ese predicado es verdadero o falso. [1]

Los procesadores vectoriales , algunas ISA SIMD (como AVX2 y AVX-512 ) y las GPU en general hacen un uso intensivo de la predicción, aplicando un bit de un vector de máscara condicional a los elementos correspondientes en los registros vectoriales que se están procesando, mientras que la predicción escalar en conjuntos de instrucciones escalares solo necesita un bit de predicado. Las máscaras de predicado se vuelven particularmente poderosas en el procesamiento vectorial cuando una matriz de códigos de condición , uno por elemento vectorial, puede retroalimentarse en máscaras de predicado que luego se aplican a instrucciones vectoriales posteriores.

Descripción general

La mayoría de los programas informáticos contienen código condicional , que se ejecutará solo bajo condiciones específicas en función de factores que no se pueden determinar de antemano, por ejemplo, en función de la entrada del usuario. Como la mayoría de los procesadores simplemente ejecutan la siguiente instrucción en una secuencia, la solución tradicional es insertar instrucciones de bifurcación que permiten que un programa se bifurque condicionalmente a una sección diferente del código, cambiando así el siguiente paso en la secuencia. Esto era suficiente hasta que los diseñadores comenzaron a mejorar el rendimiento mediante la implementación de la canalización de instrucciones , un método que se ralentiza con las bifurcaciones. Para una descripción más completa de los problemas que surgieron y una solución popular, consulte el predictor de bifurcaciones .

Afortunadamente, uno de los patrones de código más comunes que normalmente se basa en la ramificación tiene una solución más elegante. Considere el siguiente pseudocódigo : [1]

si condición { hacer_algo } de lo contrario { hacer_algo_más }   

En un sistema que utiliza ramificación condicional, esto podría traducirse en instrucciones de máquina similares a las siguientes: [1]

 rama_si_condición_a etiqueta1 hacer_algo_más rama_siempre_a etiqueta2 etiqueta1 : hacer_algo etiqueta2 : ...      

Con la predicación, todas las posibles rutas de ramificación se codifican en línea, pero algunas instrucciones se ejecutan mientras que otras no. La idea básica es que cada instrucción está asociada con un predicado (la palabra aquí se usa de manera similar a su uso en la lógica de predicados ) y que la instrucción solo se ejecutará si el predicado es verdadero. El código de máquina para el ejemplo anterior que usa la predicación podría verse así: [1]

( condición ) hacer_algo ( no condición ) hacer_algo_más   

Además de eliminar las ramas, se necesita menos código en total, siempre que la arquitectura proporcione instrucciones predichas. Si bien esto no garantiza una ejecución más rápida en general, sí lo hará si los do_somethingbloques do_something_elsede código son lo suficientemente cortos.

La forma más simple de la predicación es la predicación parcial , donde la arquitectura tiene instrucciones de movimiento condicional o de selección condicional . Las instrucciones de movimiento condicional escriben el contenido de un registro sobre otro solo si el valor del predicado es verdadero, mientras que las instrucciones de selección condicional eligen cuál de los dos registros tiene su contenido escrito en un tercero según el valor del predicado. Una forma más generalizada y capaz es la predicación completa . La predicación completa tiene un conjunto de registros de predicado para almacenar predicados (lo que permite eliminar simultáneamente múltiples ramas anidadas o secuenciales) y la mayoría de las instrucciones en la arquitectura tienen un campo especificador de registro para especificar qué registro de predicado proporciona el predicado. [2]

Ventajas

El objetivo principal de la predicción es evitar saltos en secciones muy pequeñas del código del programa, lo que aumenta la eficacia de la ejecución segmentada y evita problemas con la memoria caché . También tiene una serie de beneficios más sutiles:

Desventajas

El principal inconveniente de la predicación es el aumento del espacio de codificación. En las implementaciones típicas, cada instrucción reserva un campo de bits para el predicado que especifica bajo qué condiciones debe tener efecto esa instrucción. Cuando la memoria disponible es limitada, como en los dispositivos integrados , este costo de espacio puede ser prohibitivo. Sin embargo, algunas arquitecturas como Thumb-2 pueden evitar este problema (ver más abajo). Otros inconvenientes son los siguientes: [3]

La predicción es más efectiva cuando las rutas están equilibradas o cuando la ruta más larga es la que se ejecuta con mayor frecuencia, [3] pero determinar dicha ruta es muy difícil en tiempo de compilación, incluso en presencia de información de perfil .

Historia

Las instrucciones predicadas fueron populares en los diseños de computadoras europeas de la década de 1950, incluidos Mailüfterl (1955), Zuse Z22 (1955), ZEBRA (1958) y Electrologica X1 (1958). El diseño IBM ACS-1 de 1967 asignó un bit de "salto" en sus formatos de instrucción, y el procesador flexible CDC de 1976 asignó tres bits de ejecución condicional en sus formatos de microinstrucciones.

La arquitectura PA-RISC de Hewlett-Packard (1986) tenía una característica llamada anulación , que permitía que la mayoría de las instrucciones se predijeran a partir de la instrucción anterior. La arquitectura POWER de IBM (1990) incluía instrucciones de movimiento condicionales. El sucesor de POWER, PowerPC (1993), abandonó estas instrucciones. La arquitectura Alpha de Digital Equipment Corporation (1992) también incluía instrucciones de movimiento condicionales. MIPS ganó instrucciones de movimiento condicionales en 1994 con la versión MIPS IV; y SPARC se amplió en la versión 9 (1994) con instrucciones de movimiento condicionales tanto para registros enteros como de punto flotante.

En la arquitectura IA-64 de Hewlett-Packard / Intel , la mayoría de las instrucciones son predicadas. Los predicados se almacenan en 64 registros de predicados de propósito especial ; y uno de los registros de predicados siempre es verdadero, de modo que las instrucciones no predicadas son simplemente instrucciones predicadas con el valor verdadero. El uso de predicación es esencial en la implementación de la canalización de software de IA-64 porque evita la necesidad de escribir código separado para prólogos y epílogos. [ aclaración necesaria ]

En la arquitectura x86 , el procesador Intel Pentium Pro (1995) agregó a la arquitectura una familia de instrucciones de movimiento condicional ( CMOVy ). Las instrucciones copiaban el contenido del registro de origen al registro de destino en función de un predicado proporcionado por el valor del registro de indicadores.FCMOV CMOV

En la arquitectura ARM , el conjunto de instrucciones original de 32 bits proporciona una característica llamada ejecución condicional que permite que la mayoría de las instrucciones se predigan mediante uno de los 13 predicados que se basan en alguna combinación de los cuatro códigos de condición establecidos por la instrucción anterior. El conjunto de instrucciones Thumb de ARM (1994) abandonó la ejecución condicional para reducir el tamaño de las instrucciones para que pudieran caber en 16 bits, pero su sucesor, Thumb-2 (2003) superó este problema utilizando una instrucción especial que no tiene otro efecto que proporcionar predicados para las siguientes cuatro instrucciones. El conjunto de instrucciones de 64 bits introducido en ARMv8-A (2011) reemplazó la ejecución condicional con instrucciones de selección condicional.

SIMD, SIMT y predicción vectorial

Algunos conjuntos de instrucciones SIMD , como AVX2, tienen la capacidad de utilizar una máscara lógica para cargar/almacenar valores condicionalmente en la memoria, una forma paralela del movimiento condicional, y también pueden aplicar bits de máscara individuales a unidades aritméticas individuales que ejecutan una operación paralela. La técnica se conoce en la taxonomía de Flynn como "procesamiento asociativo" .

Esta forma de predicción también se utiliza en procesadores vectoriales y computación GPU con una sola instrucción y múltiples subprocesos . Todas las técnicas, ventajas y desventajas de la predicción escalar única se aplican igualmente al caso de procesamiento paralelo.

Véase también

Referencias

  1. ^ abcd Rick Vinyard (26 de abril de 2000). "Predicación". cs.nmsu.edu . Archivado desde el original el 20 de abril de 2015 . Consultado el 22 de abril de 2014 .
  2. ^ Mahlke, Scott A.; Hank, Richard E.; McCormick, James E.; August, David I.; Hwn, Wen-mei W. (1995). Una comparación del soporte de ejecución predicada parcial y completa para procesadores ILP . El 22.º Simposio Internacional sobre Arquitectura de Computadores, 22-24 de junio de 1995. CiteSeerX 10.1.1.19.3187 . doi :10.1145/223982.225965. ISBN .  0-89791-698-0.
  3. ^ ab Fisher, Joseph A.; Faraboschi, Paolo; Young, Cliff (2004). "4.5.2 Predicación § Predicación en el dominio integrado". Computación integrada: un enfoque VLIW para la arquitectura, los compiladores y las herramientas . Elsevier. pág. 172. ISBN 9780080477541.
  4. ^ Cordes, Peter. "ensamblaje - ¿Cómo funciona la ejecución fuera de orden con instrucciones condicionales, por ejemplo: CMOVcc en Intel o ADDNE (Add not equal) en ARM". Desbordamiento de pila . A diferencia de las dependencias de control (ramas), no predicen ni especulan cuáles serán los indicadores, por lo que un cmovcc en lugar de un jcc puede crear una cadena de dependencias transportada por bucles y terminar siendo peor que una rama predecible. El indicador de optimización de gcc -O3 hace que el código sea más lento que -O2 es un ejemplo de eso. {{cite web}}: Enlace externo en |quote=( ayuda )

Lectura adicional