stringtranslate.com

Conjunto de instrucciones ortogonales

En ingeniería informática , un conjunto de instrucciones ortogonal es una arquitectura de conjunto de instrucciones en la que 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 ortogonal 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 consideró un objetivo importante para los diseñadores de procesadores en la década de 1970, y el VAX-11 se utiliza a menudo como referencia para este concepto. Sin embargo, la introducción de las filosofías de diseño RISC en la década de 1980 revirtió significativamente la tendencia en contra de 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 las bibliotecas de funciones , como en el concepto matemático : un conjunto de funciones ortogonales es fácil de usar como base en funciones expandidas, lo que garantiza que las partes no afecten a otras si cambiamos una parte.

Conceptos básicos

En esencia, todas las computadoras de propósito general funcionan de la misma manera subyacente: la unidad central de procesamiento (CPU) lee los datos almacenados en una memoria principal en una memoria temporal rápida (por ejemplo, registros de la CPU ), procesa los datos y luego los vuelve a escribir en la memoria principal. La memoria consiste en una colección de valores de datos, codificados como números [a] y a los que se hace referencia mediante 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 con los datos, se pueden guardar temporalmente en registros del procesador , valores de borrador 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 que se encuentra 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 sola dirección tienen la desventaja de que incluso acciones simples como una suma requieren múltiples instrucciones, cada una de las cuales ocupa una cantidad escasa de memoria [c] y requiere tiempo para ser leída. Consideremos la tarea simple 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, nuevamente en 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, . Estas 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 el también se pliega en un . [4]ADD address 1, address 2SAVEADD address 1, address 2, address of result

A menudo, 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, hay 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 que cualquiera de los operandos se reemplace por una constante. Por ejemplo, elimina un ciclo de memoria y otro. [4]ADD address 1, constant 1ADD constant 1, constant 2

Datos múltiples

La complejidad aumenta cuando se consideran los patrones comunes en los que se accede a la memoria. Un patrón muy común es que una sola operación puede aplicarse 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 sumas en lenguaje de máquina . Las 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 desplazar una dirección desde una ubicación inicial, agregando un valor guardado en uno de sus registros, en algunos casos un registro de índice especial . Otras realizan esta suma automáticamente como parte de las instrucciones que la utilizan. [4]

La variedad de modos de direccionamiento da lugar a una profusión de instrucciones ligeramente diferentes. Si consideramos una ISA de una sola 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 tareas matemáticas y de direccionamiento. Esto se puede utilizar en un formato de una sola dirección si se utiliza un solo registro de dirección. En este caso, se encuentran disponibles varios modos nuevos:

Ortogonalidad

La ortogonalidad es el principio según el cual cada instrucción debe poder utilizar cualquier modo de direccionamiento compatible. En este ejemplo, si la versión de direccionamiento directo de ADDestá disponible, todas las demás también deberían estarlo. La razón de este diseño no es estética, el objetivo es reducir el tamaño total del código objeto de un programa . Al proporcionar una variedad de modos de direccionamiento, la ISA permite al programador elegir el que coincida exactamente con la necesidad de su programa en ese momento 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, lo que ahorra memoria y mejora el rendimiento. La ortogonalidad a menudo se describía como altamente "eficiente en bits". [5]

Mantener los bits especificadores 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 objetivo último del diseño ortogonal es simplemente permitir que cualquier instrucción utilice cualquier tipo de dirección, implementar la ortogonalidad es a menudo 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 indicada por el contador de 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 ningún 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 requiere más pasos internos. [5]

Como resultado, el tiempo necesario para completar distintas variaciones de una instrucción puede variar ampliamente, lo que agrega complejidad al diseño general de la CPU. Por lo tanto, la ortogonalidad representa una compensación en el diseño; el diseñador de la computadora 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 en sí sea más compleja. [5]

Cuando la memoria era pequeña y cara, especialmente durante la era de la memoria de tambor o de la memoria de núcleo , la ortogonalidad era muy deseable. Sin embargo, la complejidad a menudo superaba lo que se podía lograr utilizando la tecnología actual. Por esta razón, la mayoría de las máquinas de la década de 1960 ofrecían solo ortogonalidad parcial, tanta 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 de computadoras y comenzaron a surgir diseños completamente ortogonales. En la década de 1980, dichos diseños se podían implementar en una CPU de un solo chip. [5]

A finales de los años 1970, con la aparición de los primeros diseños totalmente ortogonales de alta potencia, el objetivo se amplió para convertirse en la arquitectura informática de lenguaje de alto nivel , o HLLCA por sus siglas en inglés. 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 los 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 soportaban directamente y tenían que implementarse usando muchas instrucciones individuales de la ISA subyacente. Agregar soporte para estas estructuras permitiría que el programa se tradujera más directamente a la ISA. [5]

La ortogonalidad en la práctica

El PDP-11

El PDP-11 era sustancialmente ortogonal (exceptuando principalmente sus instrucciones de punto flotante). [6] La mayoría de las instrucciones de números enteros podían operar con valores de 1 o 2 bytes y podían acceder a datos almacenados en registros, almacenados como parte de la instrucción, almacenados en memoria o almacenados en memoria y apuntados por direcciones en registros o memoria. Incluso el PC y el puntero de pila podían verse afectados por las instrucciones ordinarias que utilizaban 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, autoincremento" y especificando el contador de programa (R7) como el registro que se utilizaría como referencia para la indirección y el autoincremento. (Codificado como ADD (R7)+,R1 .word 4.) [7]

El PDP-11 utilizaba 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 aplicaban los dos modos de incremento automático al contador de programa (R7) proporcionaban un total de 10 modos de direccionamiento conceptual. 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 extendió 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 es 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 (normalmente) especifican un número de registro (R0 a 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-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 dio como resultado 13 modos de direccionamiento (electrónicos), pero como 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 el puntero de pila o el contador de programa real necesario). [8]

El MC68000 y similares

Los diseñadores de Motorola intentaron 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) utilizaba registros separados para almacenar datos y las direcciones de los datos en la memoria. El ISA era ortogonal en la medida en que las direcciones solo se podían utilizar en esos registros, pero no había ninguna restricción sobre cuáles de los registros podían ser utilizados por diferentes instrucciones. Del mismo modo, 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 era un registro, con la excepción de MOV. Las instrucciones MOV admitían todos los modos de direccionamiento para ambos parámetros. [9]

En cambio, la serie NS320xx se diseñó originalmente como una implementación en un solo chip del ISA VAX-11. 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 siguió siendo completamente ortogonal. [10] Esto incluyó la eliminación de los registros de datos y direcciones separados que se encuentran en el 68k. [11]

El 8080 y diseños posteriores

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 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 solo se podían realizar en el acumulador de 8 bits (el registro A), mientras que las operaciones de 16 bits solo se podían realizar en el acumulador/puntero de 16 bits (el par de registros HL), mientras que las operaciones simples, como el incremento, eran posibles en los siete registros de 8 bits. Esto se debía en gran medida al deseo de mantener todos los códigos de operación con una longitud de un byte.

El Z80 compatible con binarios agregó posteriormente 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, no se intentó aquí 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 , fue algo más ortogonal a pesar de mantener todas las instrucciones del 8086 y sus contrapartes extendidas. Sin embargo, la estrategia de codificación utilizada aún muestra muchos rastros del 8008 y el 8080 (y el Z80). Por ejemplo, las codificaciones de un solo byte permanecen para ciertas operaciones frecuentes como push y pop 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. Observaciones como ésta a veces se aprovechan para optimizar el código, tanto en compiladores como en código escrito a mano.

RIESGO

Una serie de estudios realizados durante la década de 1970 demostraron que la flexibilidad que ofrecen los modos ortogonales rara vez o nunca se utilizaba en problemas reales. En particular, un estudio en IBM estudió rastros de código que se ejecutaba en el System/370 y demostró que solo 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 de semiconductores aumentaron rápidamente de tamaño y disminuyeron de precio. Sin embargo, no mejoraron en velocidad al mismo ritmo. Esto significaba que el tiempo necesario para acceder a los datos de la memoria aumentaba en términos relativos en comparación con la velocidad de las CPU. Esto justificaba la inclusión de más registros, lo que proporcionaba 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 sugería que las propias instrucciones se redujeran en número 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, y que el 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, y las variables simples (a diferencia de las matrices o similares) representan otro 35 a 40%. [13] Si el procesador utiliza 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 utilice 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 solo dos modos de direccionamiento, directo (constante) y de 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 binarios 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. ^ suponiendo que no se puede operar en la dirección

Referencias

  1. ^ Null, Linda; Lobur, Julia (2010). Fundamentos de la organización y arquitectura de computadoras . Jones & Bartlett Publishers. págs. 287–288. ISBN 978-1449600068.
  2. ^ Tariq, Jamil (1995), "RISC vs CISC: Why less is more", IEEE Potentials (agosto/septiembre) , consultado el 7 de mayo de 2019
  3. ^ "Organización y diseño básico de computadoras" (PDF) . Laboratorio de sistemas computacionales sensoriomotores.
  4. ^ abcde Tullsen, Dean. "Arquitectura del conjunto de instrucciones" (PDF) . UCSD.
  5. ^ abcdefg Hennessy, John; Patterson, David (29 de mayo de 2002). Arquitectura informática: un enfoque cuantitativo. Elsevier. pág. 151. ISBN 9780080502526.
  6. ^ "Introducción al PDP-11". Universidad de Sydney .
  7. ^ ab "Referencia de instrucciones del PDP-11" (PDF) . Universidad de Toronto .
  8. ^ abc "Otro enfoque para la arquitectura del conjunto de instrucciones: VAX" (PDF) .
  9. ^ Veronis, Andrew (6 de diciembre de 2012). El microprocesador 68000. Springer. pág. 54. ISBN 9781468466478.
  10. ^ Tilson, Michael (octubre de 1983). "Moving Unix to New Machines" (Trasladar Unix a nuevas máquinas). BYTE . p. 266 . Consultado el 31 de enero de 2015 .
  11. ^ "NS32532". Museo de los datos .
  12. ^ Patterson, DA ; Ditzel, DR (1980). "El caso de la computadora con conjunto de instrucciones reducido". ACM SIGARCH Computer Architecture News . 8 (6): 25–33. CiteSeerX 10.1.1.68.9623 . doi :10.1145/641914.641917. S2CID  12034303. 
  13. ^ Tanenbaum, Andrew (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.