stringtranslate.com

Conjunto de instrucciones ortogonales

En ingeniería informática , un conjunto de instrucciones ortogonal es una arquitectura de conjunto de instrucciones donde todos los tipos de instrucciones pueden utilizar todos los modos de direccionamiento . Es " ortogonal " en el sentido de que el tipo de instrucción y el modo de direccionamiento varían de forma independiente. Un conjunto de instrucciones ortogonales no impone una limitación que requiera que una determinada instrucción utilice un registro específico [1] , por lo que hay poca superposición de la funcionalidad de las instrucciones. [2]

La ortogonalidad se consideraba un objetivo importante para los diseñadores de procesadores en la década de 1970, y el VAX-11 se utiliza a menudo como punto de referencia para este concepto. Sin embargo, la introducción de filosofías de diseño RISC en la década de 1980 revirtió significativamente la tendencia contra una mayor ortogonalidad.

Las CPU modernas suelen simular la ortogonalidad en un paso de preprocesamiento antes de realizar las tareas reales en un núcleo tipo RISC. Esta "ortogonalidad simulada" en general es un concepto más amplio, que abarca las nociones de desacoplamiento y completitud en bibliotecas de funciones , como en el concepto matemático : un conjunto de funciones ortogonales es fácil de usar como base en funciones expandidas, asegurando que las partes no afectar a otra si cambiamos una parte.

Conceptos básicos

En esencia, todas las computadoras de propósito general funcionan de la misma manera subyacente; Los datos almacenados en una memoria principal son leídos por la unidad central de procesamiento (CPU) en una memoria temporal rápida (por ejemplo, registros de la CPU ), se actúa sobre ellos y luego se escriben de nuevo en la memoria principal. La memoria consta de una colección de valores de datos, codificados como números [a] y referidos por sus direcciones , también un valor numérico. Esto significa que las mismas operaciones aplicadas a los datos se pueden aplicar a las direcciones mismas. [b] Mientras se trabaja en ellos, los datos se pueden guardar temporalmente en registros del procesador , valores del bloc de notas a los que se puede acceder muy rápidamente. Los registros se utilizan, por ejemplo, al sumar cadenas de números para obtener un total. [3]

Instrucción única, operando único

En las primeras computadoras, la arquitectura del conjunto de instrucciones (ISA) solía utilizar un solo registro, en cuyo caso se lo conocía como acumulador . Las instrucciones incluían una dirección para el operando. Por ejemplo, una instrucción haría que la CPU recuperara el número en la memoria encontrado en esa dirección y luego lo agregara al valor que ya está en el acumulador. Este ejemplo muy simple de ISA tiene un "formato de una dirección" porque cada instrucción incluye la dirección de los datos. [4]ADD address

Las máquinas de una dirección tienen la desventaja de que incluso acciones simples como una suma requieren múltiples instrucciones, cada una de las cuales ocupa poca memoria, [c] y requiere tiempo para ser leída. Considere la simple tarea de sumar dos números, 5 + 4. En este caso, el programa tendría que cargar el valor 5 en el acumulador con la instrucción, usar la instrucción que apunta a la dirección del 4 y finalmente almacenar el resultado. , 9, de regreso a otra ubicación de memoria. [4]LOAD addressADD addressSAVE address

Instrucción única, múltiples operandos

Se pueden encontrar mejoras adicionales proporcionando la dirección de ambos operandos en una sola instrucción, por ejemplo . Este tipo de ISA de "formato de dos direcciones" son muy comunes. Se puede ampliar aún más el concepto a un "formato de tres direcciones" donde también se pliega en un formato expandido . [4]ADD address 1, address 2SAVEADD address 1, address 2, address of result

A menudo ocurre que la palabra básica de la computadora es mucho más grande de lo necesario para contener solo la instrucción y una dirección, y en la mayoría de los sistemas, quedan bits sobrantes que se pueden usar para contener una constante en lugar de una dirección. Las instrucciones se pueden mejorar aún más si permiten reemplazar cualquiera de los operandos por una constante. Por ejemplo, elimina un ciclo de memoria y otro. [4]ADD address 1, constant 1ADD constant 1, constant 2

Múltiples datos

Surge una mayor complejidad cuando se consideran los patrones comunes en los que se accede a la memoria. Un patrón muy común es que se puede aplicar una única operación a una gran cantidad de datos similares. Por ejemplo, uno podría querer sumar 1000 números. En un formato simple de instrucciones de dos direcciones, [d] no hay forma de cambiar la dirección, por lo que se deben escribir 1000 adiciones en lenguaje de máquina . Los ISA solucionan este problema con el concepto de direccionamiento indirecto , en el que la dirección del siguiente punto de datos no es una constante, sino que se mantiene en la memoria. Esto significa que el programador puede cambiar la dirección realizando una suma en esa ubicación de memoria. Las ISA también suelen incluir la capacidad de compensar una dirección desde una ubicación inicial, agregando un valor mantenido en uno de sus registros, en algunos casos un registro de índice especial . Otros realizan esta adición de forma automática como parte de las instrucciones que lo utilizan. [4]

La variedad de modos de direccionamiento conduce a una profusión de instrucciones ligeramente diferentes. Considerando un ISA de una dirección, incluso para una sola instrucción, ADDahora tenemos muchos "modos de direccionamiento" posibles:

Muchas ISA también tienen registros que se pueden utilizar para abordar y realizar tareas matemáticas. Esto se puede utilizar en un formato de una dirección si se utiliza un único registro de dirección. En este caso, estarán disponibles varios modos nuevos:

Ortogonalidad

La ortogonalidad es el principio de que cada instrucción debería poder utilizar cualquier modo de direccionamiento admitido. En este ejemplo, si la versión de direccionamiento directo ADDestá disponible, todas las demás también deberían estarlo. El motivo de este diseño no es estético, el objetivo es reducir el tamaño total del código objeto de un programa . Al proporcionar una variedad de modos de direccionamiento, ISA permite al programador elegir el que coincida exactamente con la necesidad de su programa en ese punto y, por lo tanto, reducir la necesidad de utilizar múltiples instrucciones para lograr el mismo fin. Esto significa que se reduce el número total de instrucciones, ahorrando memoria y mejorando el rendimiento. La ortogonalidad se describía a menudo como muy "eficiente en bits". [5]

Mantener los bits del especificador del modo de direccionamiento separados de los bits de operación del código de operación produce un conjunto de instrucciones ortogonales.

Como el fin último del diseño ortogonal es simplemente permitir que cualquier instrucción utilice cualquier tipo de dirección, implementar la ortogonalidad suele ser simplemente un caso de agregar más cableado entre las partes del procesador. Sin embargo, también aumenta la complejidad del decodificador de instrucciones, el circuito que lee una instrucción de la memoria en la ubicación señalada por el contador del programa y luego decide cómo procesarla. [5]

En el ejemplo de ISA descrito anteriormente, la ADD.Cinstrucción que utiliza codificación directa ya tiene los datos que necesita para ejecutar la instrucción y no se necesita procesamiento adicional, el decodificador simplemente envía el valor a la unidad lógica aritmética (ALU). Sin embargo, si ADD.Ase utiliza la instrucción, se debe leer la dirección, leer el valor en esa ubicación de memoria y luego la ALU puede continuar. Esta serie de eventos tardará mucho más en completarse y requerirá más pasos internos. [5]

Como resultado, el tiempo necesario para completar diferentes variaciones de una instrucción puede variar ampliamente, lo que añade complejidad al diseño general de la CPU. Por tanto, la ortogonalidad representa una compensación en el diseño; el diseñador de computadoras puede optar por ofrecer más modos de direccionamiento al programador para mejorar la densidad del código a costa de hacer que la CPU sea más compleja. [5]

Cuando la memoria era pequeña y costosa, especialmente durante la era de la memoria de tambor o memoria central , la ortogonalidad era muy deseable. Sin embargo, la complejidad a menudo va más allá de lo que se podría lograr con la tecnología actual. Por esta razón, la mayoría de las máquinas de la década de 1960 ofrecían sólo una ortogonalidad parcial, tanto como los diseñadores podían permitirse. Fue en la década de 1970 cuando la introducción de la integración a gran escala redujo significativamente la complejidad de los diseños por computadora y comenzaron a surgir diseños completamente ortogonales. En la década de 1980, estos diseños podían implementarse en una CPU de un solo chip. [5]

A finales de la década de 1970, con la aparición de los primeros diseños totalmente ortogonales de alta potencia, el objetivo se amplió hasta convertirse en la arquitectura informática de lenguaje de alto nivel , o HLLCA para abreviar. Así como se deseaba la ortogonalidad para mejorar la densidad de bits del lenguaje de máquina, el objetivo de HLLCA era mejorar la densidad de bits de lenguajes de alto nivel como ALGOL 68 . Estos lenguajes generalmente usaban un registro de activación , un tipo de pila compleja que almacenaba valores temporales, que las ISA generalmente no admitían directamente y debían implementarse utilizando muchas instrucciones individuales de la ISA subyacente. Agregar soporte para estas estructuras permitiría que el programa se traduzca más directamente a la ISA. [5]

Ortogonalidad en la práctica

El PPD-11

El PDP-11 era sustancialmente ortogonal (principalmente a excepción de sus instrucciones de punto flotante). [6] La mayoría de las instrucciones de números enteros podrían operar con valores de 1 byte o 2 bytes y podrían acceder a datos almacenados en registros, almacenados como parte de la instrucción, almacenados en la memoria o almacenados en la memoria y señalados por direcciones en los registros o en la memoria. . Incluso la PC y el puntero de la pila podrían verse afectados por las instrucciones ordinarias que utilizan todos los modos de datos ordinarios. El modo "inmediato" (números codificados dentro de una instrucción, como ADD #4, R1 (R1 = R1 + 4) se implementó como el modo "registro indirecto, incremento automático" y especificando el contador del programa (R7) como el registro para usar como referencia. para direccionamiento indirecto y autoincremento (codificado como ADD (R7)+,R1 .palabra 4.) [7]

El PDP-11 usaba campos de 3 bits para los modos de direccionamiento (0-7), por lo que había (electrónicamente) 8 modos de direccionamiento. Un campo adicional de 3 bits especificaba los registros (R0–R5, SP, PC). Los operandos de dirección inmediata y absoluta que aplicaron los dos modos de incremento automático al Contador de programa (R7) proporcionaron un total de 10 modos de direccionamiento conceptuales. La mayoría de las instrucciones de dos operandos admitían todos los modos de direccionamiento para ambos parámetros. [7]

El VAX-11

El VAX-11 amplió la ortogonalidad del PDP-11 a todos los tipos de datos, incluidos los números de punto flotante. [5] Las instrucciones como 'ADD' se dividieron en variantes dependientes del tamaño de los datos, como ADDB, ADDW, ADDL, ADDP, ADDF para agregar byte, palabra, palabra larga, BCD empaquetado y punto flotante de precisión simple, respectivamente. Al igual que el PDP-11, el puntero de pila y el contador de programa estaban en el archivo de registro general (R14 y R15). [8]

La forma general de una instrucción VAX-11 sería:

código de operación [ operando ] [ operando ] ...

Cada componente es un byte , el código de operación tiene un valor en el rango de 0 a 255 y cada operando consta de dos nibbles , los 4 bits superiores especifican un modo de direccionamiento y los 4 bits inferiores (generalmente) especifican un número de registro (R0-R15). ). [8]

A diferencia de los campos de 3 bits del PDP-11, los subbytes de 4 bits del VAX-11 dieron como resultado 16 modos de direccionamiento (0-15). Sin embargo, los modos de direccionamiento 0 a 3 eran "inmediatos cortos" para datos inmediatos de 6 bits o menos (los 2 bits de orden inferior del modo de direccionamiento eran los 2 bits de orden superior de los datos inmediatos, cuando se anteponían a los 4 bits restantes en ese byte de direccionamiento de datos). Dado que los modos de direccionamiento 0-3 eran idénticos, esto generó 13 modos de direccionamiento (electrónicos), pero al igual que en el PDP-11, el uso del puntero de pila (R14) y el contador de programa (R15) creó un total de más de 15 modos de direccionamiento conceptuales. (con el programa ensamblador traduciendo el código fuente al modo de direccionamiento basado en puntero de pila o contador de programa real necesario). [8]

El MC68000 y similares

Los diseñadores de Motorola intentaron hacer que el lenguaje ensamblador fuera ortogonal, mientras que el lenguaje de máquina subyacente lo era un poco menos. A diferencia del PDP-11, el MC68000 (68k) usaba registros separados para almacenar datos y las direcciones de los datos en la memoria. La ISA era ortogonal en la medida en que las direcciones solo podían usarse en esos registros, pero no había restricción sobre cuál de los registros podía ser usado por diferentes instrucciones. Asimismo, los registros de datos también eran ortogonales entre instrucciones. A diferencia del PDP-11, el 68000 solo admitía un modo de direccionamiento general para instrucciones de dos parámetros. El otro parámetro siempre fue un registro, a excepción de MOV. Las instrucciones MOV admitieron todos los modos de direccionamiento para ambos parámetros. [9]

Por el contrario, la serie NS320xx se diseñó originalmente como implementaciones de un solo chip del VAX-11 ISA. Aunque esto tuvo que cambiar debido a cuestiones legales, el sistema resultante conservó gran parte de la filosofía de diseño general del VAX-11 y permaneció completamente ortogonal. [10] Esto incluyó la eliminación de los registros de direcciones y datos separados que se encuentran en el 68k. [11]

El 8080 y los siguientes diseños.

El microprocesador Intel 8080 de 8 bits (así como el 8085 y el 8051) era básicamente un diseño basado en acumuladores ligeramente extendido y, por lo tanto, no era ortogonal. Un programador en lenguaje ensamblador o un escritor de compiladores tenía que tener en cuenta qué operaciones eran posibles en cada registro: la mayoría de las operaciones de 8 bits sólo podían realizarse en el acumulador de 8 bits (el registro A), mientras que las operaciones de 16 bits podían realizarse. se realizaba sólo en el puntero/acumulador de 16 bits (el par de registros HL), mientras que operaciones simples, como el incremento, eran posibles en los siete registros de 8 bits. Esto se debió en gran medida al deseo de mantener todos los códigos de operación en un byte de longitud.

Posteriormente, el Z80 compatible con binarios agregó códigos de prefijo para escapar de este límite de 1 byte y permitir un conjunto de instrucciones más potente. La misma idea básica se empleó para el Intel 8086 , aunque, para permitir extensiones más radicales, aquí no se intentó la compatibilidad binaria con el 8080. Mantuvo cierto grado de no ortogonalidad en aras de la alta densidad de código en ese momento. La extensión de 32 bits de esta arquitectura que se introdujo con el 80386 , era algo más ortogonal a pesar de mantener todas las instrucciones del 8086 y sus homólogos extendidos. Sin embargo, la estrategia de codificación utilizada todavía muestra muchos rastros del 8008 y 8080 (y Z80). Por ejemplo, las codificaciones de un solo byte permanecen para ciertas operaciones frecuentes, como la inserción y extracción de registros y constantes; y el acumulador primario, el registro EAX , emplea codificaciones más cortas que los otros registros en ciertos tipos de operaciones. A veces, observaciones como esta se aprovechan para optimizar el código tanto en compiladores como en código escrito a mano.

RISC

Varios estudios realizados durante la década de 1970 demostraron que la flexibilidad ofrecida por los modos ortogonales rara vez o nunca se utilizaba en problemas reales. En particular, un esfuerzo de IBM estudió rastros de código que se ejecutan en System/370 y demostró que sólo una fracción de los modos disponibles se utilizaban en programas reales. Estudios similares, a menudo sobre el VAX, demostraron el mismo patrón. En algunos casos, se demostró que la complejidad de las instrucciones significaba que tardaban más en ejecutarse que la secuencia de instrucciones más pequeñas, siendo el ejemplo canónico de esto la INDEXinstrucción del VAX. [12]

Durante este mismo período, las memorias semiconductoras aumentaron rápidamente de tamaño y disminuyeron de costo. Sin embargo, no estaban mejorando en velocidad al mismo ritmo. Esto significaba que el tiempo necesario para acceder a los datos de la memoria crecía en términos relativos en comparación con la velocidad de las CPU. Esto abogaba por la inclusión de más registros, dando a la CPU más valores temporales con los que trabajar. Un mayor número de registros significaba que se necesitarían más bits en la palabra de la computadora para codificar el número de registro, lo que sugirió que se redujera el número de instrucciones para liberar espacio.

Finalmente, un artículo de Andrew Tanenbaum demostró que el 97% de todas las constantes de un programa están entre 0 y 10, donde 0 representa entre el 20 y el 30% del total. Además, entre el 30 y el 40% de todos los valores de un programa son constantes, con variables simples (a diferencia de matrices o similares) otro 35 a 40%. [13] Si el procesador usa una palabra de instrucción más grande, como 32 bits, se pueden codificar dos números de registro y una constante en una sola instrucción siempre que la instrucción en sí no use demasiados bits.

Estas observaciones llevaron al abandono del diseño ortogonal como objetivo principal del diseño de procesadores y al surgimiento de la filosofía RISC en la década de 1980. Los procesadores RISC generalmente tienen sólo dos modos de direccionamiento, directo (constante) y registro. Todos los demás modos que se encuentran en procesadores más antiguos se manejan explícitamente mediante instrucciones de carga y almacenamiento que mueven datos hacia y desde los registros. Es posible que solo estén disponibles unos pocos modos de direccionamiento , y estos modos pueden variar dependiendo de si la instrucción se refiere a datos o implica una transferencia de control .

Notas

  1. Ver digitalización .
  2. ^ las direcciones son números hexadecimales simples que pueden tratarse como datos
  3. ^ Incluso en las computadoras modernas, el rendimiento se maximiza manteniendo los datos en la memoria caché, un recurso limitado.
  4. ^ asumiendo que la dirección no se puede operar

Referencias

  1. ^ Nulo, Linda; Lobur, Julia (2010). Los fundamentos de la organización y arquitectura de las computadoras . Editores Jones y Bartlett. págs. 287–288. ISBN 978-1449600068.
  2. ^ Tariq, Jamil (1995), "RISC vs CISC: por qué menos es más", IEEE Potentials (agosto/septiembre) , consultado el 7 de mayo de 2019
  3. ^ "Organización y diseño informáticos básicos" (PDF) . Laboratorio de Sistemas Computacionales Sensorio-Motores.
  4. ^ abcde Tullsen, decano. "Arquitectura del conjunto de instrucciones" (PDF) . UCSD.
  5. ^ abcdefg Hennessy, John; Patterson, David (29 de mayo de 2002). Arquitectura informática: un enfoque cuantitativo. pag. 151.ISBN 9780080502526.
  6. ^ "Introducción al PDP-11". Universidad de Sídney .
  7. ^ ab "Referencia de instrucciones PDP-11" (PDF) . Universidad de Toronto .
  8. ^ abc "Otro enfoque a la arquitectura del conjunto de instrucciones: VAX" (PDF) .
  9. ^ Veronis, Andrés (6 de diciembre de 2012). El microprocesador 68000. pag. 54.ISBN 9781468466478.
  10. ^ Tilson, Michael (octubre de 1983). "Trasladar Unix a nuevas máquinas". BYTE . pag. 266 . Consultado el 31 de enero de 2015 .
  11. ^ "NS32532". Museo Dator .
  12. ^ Patterson, DA ; Ditzel, DR (1980). "El caso de la computadora con conjunto de instrucciones reducido". Noticias de arquitectura informática de ACM SIGARCH . 8 (6): 25–33. CiteSeerX 10.1.1.68.9623 . doi :10.1145/641914.641917. S2CID  12034303. 
  13. ^ Tanenbaum, Andrés (1978). "Implicaciones de la programación estructurada para la arquitectura de máquinas". Comunicaciones de la ACM . 21 (3): 237–246. doi : 10.1145/359361.359454 . hdl : 1871/2610. S2CID  3261560.