Berkeley RISC - Berkeley RISC

Berkeley RISC es uno de los dos proyectos de investigación seminales sobre el diseño de microprocesadores basado en computadora de conjunto de instrucciones reducidas (RISC) que se lleva a cabo en el marco del proyecto VLSI de la Agencia de Proyectos de Investigación Avanzada ( ARPA ) . RISC fue dirigido por David Patterson (quien acuñó el término RISC) en la Universidad de California, Berkeley entre 1980 y 1984. El otro proyecto se llevó a cabo a poca distancia en la Universidad de Stanford bajo su esfuerzo MIPS a partir de 1981 y hasta 1984.

El proyecto de Berkeley tuvo tanto éxito que se convirtió en el nombre de todos los diseños similares a seguir; incluso el MIPS se conocería como un "procesador RISC". El diseño de Berkeley RISC fue posteriormente comercializado por Sun Microsystems como la arquitectura SPARC e inspiró la arquitectura ARM .

El concepto RISC

Tanto RISC como MIPS se desarrollaron a partir de la comprensión de que la gran mayoría de los programas no usaban la gran mayoría de las instrucciones de un procesador. En un famoso artículo de 1978, Andrew S. Tanenbaum demostró que un programa complejo de alto nivel de 10.000 líneas podría representarse utilizando una arquitectura de conjunto de instrucciones simplificada utilizando un código de operación de longitud fija de 8 bits. Esta fue aproximadamente la misma conclusión a la que llegó IBM , cuyos estudios de su propio código que se ejecuta en mainframes como IBM 360 utilizaron solo un pequeño subconjunto de todas las instrucciones disponibles. Ambos estudios sugirieron que se podría producir una CPU mucho más simple que aún ejecutaría la gran mayoría del código del mundo real. Otro dato, no explorado por completo en ese momento, fue la nota de Tanenbaum de que el 81,4 por ciento de las constantes eran 0, 1 o 2.

Estas realizaciones se estaban produciendo a medida que el mercado de microprocesadores pasaba de 8 a 16 bits con diseños de 32 bits a punto de aparecer. Estos procesadores fueron diseñados con la premisa de intentar replicar algunas de las ISA más respetadas del mundo de las computadoras centrales y las minicomputadoras. Por ejemplo, el National Semiconductor NS32000 comenzó como un esfuerzo para producir una implementación de un solo chip del VAX-11 , que tenía un rico conjunto de instrucciones con una amplia variedad de modos de direccionamiento . El Motorola 68000 era similar en diseño general. Para proporcionar este rico conjunto de instrucciones, las CPU utilizaron microcódigo para decodificar la instrucción visible para el usuario en una serie de operaciones internas. Este microcódigo representaba quizás 1 / 4 a 1 / 3 de los transistores del diseño general.

Si, como sugirieron estos otros documentos, la mayoría de estos códigos de operación nunca se usarían en la práctica, entonces se estaba desperdiciando este importante recurso. Si uno simplemente construyera el mismo procesador sin las instrucciones no utilizadas, sería más pequeño y, por lo tanto, menos costoso, mientras que si en su lugar se usaran esos transistores para mejorar el rendimiento en lugar de decodificar instrucciones que no se usarían, sería posible un procesador más rápido. El concepto de RISC era aprovechar ambos, produciendo una CPU que tenía el mismo nivel de complejidad que la 68000, pero mucho más rápida.

Para hacer esto, RISC se concentró en agregar muchos más registros , pequeños bits de memoria que contienen valores temporales a los que se puede acceder muy rápidamente. Esto contrasta con la memoria principal normal , que puede tardar varios ciclos en acceder. Al proporcionar más registros y asegurarse de que los compiladores los hayan utilizado, los programas deberían ejecutarse mucho más rápido. Además, la velocidad del procesador se definiría más de cerca por su velocidad de reloj, porque se dedicaría menos tiempo a esperar los accesos a la memoria. Transistor por transistor, un diseño RISC superaría a una CPU convencional, con suerte por mucho.

En el lado negativo, las instrucciones que se eliminaron generalmente ejecutaban varias "subinstrucciones". Por ejemplo, la ADD instrucción de un diseño tradicional generalmente vendría en varios sabores, uno que sumaba los números en dos registros y los colocaba en un tercero, otro que sumaba los números encontrados en la memoria principal y ponía el resultado en un registro, etc. Los diseños RISC, por otro lado, incluían solo un sabor único de cualquier instrucción en particular, el ADD , por ejemplo, siempre usaría registros para todos los operandos. Esto obligó al programador a escribir instrucciones adicionales para cargar los valores de la memoria, si era necesario, haciendo un programa RISC "menos denso".

En la era de la memoria cara, esto era una preocupación real, sobre todo porque la memoria también era mucho más lenta que la CPU. Dado que un diseño RISC en ADD realidad requeriría cuatro instrucciones (dos cargas, una adición y un guardado), la máquina tendría que hacer mucho más acceso a la memoria para leer las instrucciones adicionales, lo que podría ralentizarlo considerablemente. Esto se vio compensado hasta cierto punto por el hecho de que los nuevos diseños usaban lo que entonces era una palabra de instrucción muy grande de 32 bits , lo que permitía que pequeñas constantes se plegaran directamente en la instrucción en lugar de tener que cargarlas por separado. Además, los resultados de una operación a menudo se usan poco después de otra, por lo que al omitir la escritura en la memoria y almacenar el resultado en un registro, el programa no terminó siendo mucho más grande y, en teoría, podría ejecutarse mucho más rápido. Por ejemplo, una cadena de instrucciones que llevan a cabo una serie de operaciones matemáticas puede requerir solo unas pocas cargas de la memoria, mientras que la mayoría de los números que se utilizan serían constantes en las instrucciones o valores intermedios dejados en los registros de cálculos anteriores. En cierto sentido, en esta técnica algunos registros se utilizan para sombrear las ubicaciones de la memoria, de modo que los registros se utilizan como sustitutos de las ubicaciones de la memoria hasta que sus valores finales después de que se haya determinado un grupo de instrucciones.

Para el observador casual, no estaba claro que el concepto RISC mejoraría el rendimiento, e incluso podría empeorarlo. La única forma de estar seguro era simularlo. Los resultados de tales simulaciones fueron claros; Prueba tras prueba, cada simulación mostró un enorme beneficio general en el rendimiento de este diseño.

Donde los dos proyectos, RISC y MIPS, diferían fue en el manejo de los registros. MIPS simplemente agregó muchos registros y dejó que los compiladores (o programadores en lenguaje ensamblador ) los usaran. RISC, por otro lado, agregó circuitos a la CPU para ayudar al compilador. RISC utilizó el concepto de ventanas de registro , en las que todo el "archivo de registro" se dividía en bloques, lo que permitía al compilador "ver" un bloque para las variables globales y otro para las variables locales.

La idea era hacer que una instrucción particularmente común, la llamada a procedimiento , fuera extremadamente fácil de implementar. Casi todos los lenguajes de programación utilizan un sistema conocido como registro de activación o marco de pila para cada procedimiento que contiene la dirección desde la que se llamó al procedimiento, los datos (parámetros) que se pasaron y el espacio para los valores de resultado que deben devolverse. . En la gran mayoría de los casos, estos marcos son pequeños, por lo general con tres o menos entradas y una o ninguna salida (y, a veces, una entrada se reutiliza como salida). En el diseño de Berkeley, entonces, una ventana de registro era un conjunto de varios registros, suficientes de ellos para que todo el marco de la pila de procedimientos encajara por completo dentro de la ventana de registro.

En este caso, la llamada y el retorno de un procedimiento es simple y extremadamente rápida. Se llama a una sola instrucción para configurar un nuevo bloque de registros (una nueva ventana de registro) y luego, con los operandos pasados ​​al procedimiento en el "extremo inferior" de la nueva ventana, el programa salta al procedimiento. Al regresar, los resultados se colocan en la ventana del mismo extremo y el procedimiento finaliza. Las ventanas de registro están configuradas para superponerse en los extremos, de modo que los resultados de la llamada simplemente "aparecen" en la ventana de la persona que llama, sin que sea necesario copiar datos . Por lo tanto, la llamada al procedimiento común no tiene que interactuar con la memoria principal, lo que la acelera en gran medida.

En el lado negativo, este enfoque significa que los procedimientos con un gran número de variables locales son problemáticos y los que tienen menos conducen al desperdicio de registros, un recurso costoso. Hay un número finito de ventanas de registro en el diseño, por ejemplo, ocho, por lo que los procedimientos solo pueden anidarse a muchos niveles de profundidad antes de que el mecanismo de ventanas de registro alcance su límite; una vez que se alcanza la última ventana, no se puede configurar una nueva ventana para otra llamada anidada. Y si los procedimientos solo se anidan en unos pocos niveles de profundidad, nunca se podrá acceder a los registros de las ventanas por encima del nivel de anidación de llamadas más profundo, por lo que estos se desperdician por completo. Fue el trabajo de Stanford sobre compiladores lo que los llevó a ignorar el concepto de ventana de registro, creyendo que un compilador eficiente podría hacer un mejor uso de los registros que un sistema fijo en hardware. (El mismo razonamiento se aplicaría a un programador inteligente en lenguaje ensamblador).

RISC I

El primer intento de implementar el concepto RISC originalmente se llamó Gold . El trabajo en el diseño comenzó en 1980 como parte de un curso de diseño de VLSI, pero el complicado diseño de ese entonces colapsó casi todas las herramientas de diseño existentes. El equipo tuvo que dedicar una cantidad considerable de tiempo a mejorar o reescribir las herramientas, e incluso con estas nuevas herramientas, tomó poco menos de una hora extraer el diseño en un VAX-11/780 .

El diseño final, llamado RISC I , fue publicado en el Simposio Internacional de Arquitectura de Computadoras (ISCA) de la Asociación de Maquinaria de Computación (ACM) en 1981. Tenía 44.500 transistores que implementaban 31 instrucciones y un archivo de registro que contenía 78 registros de 32 bits. Esto permitió seis ventanas de registro que contienen 14 registros. De esos 14 registros, 4 se superpusieron con respecto a la ventana anterior. El total es entonces: 10 * 6 registros en Windows + 18 globales = 78 registros en total. La sección de decodificación de instrucciones y control ocupaba solo el 6% del dado, mientras que el diseño típico de la época usaba alrededor del 50% para el mismo rol. El archivo de registro ocupaba la mayor parte de ese espacio.

RISC I también presentó un flujo de instrucciones de dos etapas para mayor velocidad, pero sin el complejo reordenamiento de instrucciones de diseños más modernos. Esto hace que las ramas condicionales sean un problema, porque el compilador tiene que completar la instrucción que sigue a una rama condicional (la llamada ranura de retardo de la rama ), con algo seleccionado para ser "seguro" (es decir, que no depende del resultado del condicional). A veces, la única instrucción adecuada en este caso es NOP . Un número notable de diseños posteriores de estilo RISC aún requieren la consideración del retardo de rama.

Después de un mes de validación y depuración, el diseño se envió al innovador servicio MOSIS para su producción el 22 de junio de 1981, utilizando un proceso de 2 μm (2.000 nm). Una variedad de retrasos los obligó a abandonar sus máscaras en cuatro ocasiones distintas, y las obleas con ejemplos funcionales no llegaron a Berkeley hasta mayo de 1982. La primera "computadora" RISC I en funcionamiento (en realidad, un tablero de caja) se ejecutó el 11 de junio. , los chips demostraron tener un rendimiento menor al esperado. En general, una instrucción tardaría 2 µs en completarse, mientras que el diseño original se asignaba a aproximadamente 0,4 µs (cinco veces más rápido). Las razones precisas de este problema nunca se explicaron completamente. Sin embargo, a lo largo de las pruebas quedó claro que ciertas instrucciones se ejecutaron a la velocidad esperada, lo que sugiere que el problema era físico, no lógico.

Si el diseño hubiera funcionado a toda velocidad, el rendimiento habría sido excelente. Las simulaciones que utilizan una variedad de programas pequeños compararon el RISC I de 4 MHz con el VAX 11/780 de 5 MHz y 32 bits y el Zilog Z8000 de 5 MHz y 16 bits lo mostraron claramente. El tamaño del programa era aproximadamente un 30% más grande que el VAX pero muy cercano al del Z8000, validando el argumento de que la mayor densidad de código de los diseños CISC no era tan impresionante en realidad. En términos de rendimiento general, el RISC I fue dos veces más rápido que el VAX y aproximadamente cuatro veces más rápido que el Z8000. Los programas terminaron realizando aproximadamente la misma cantidad total de acceso a la memoria porque el archivo de registro grande mejoró drásticamente las probabilidades de que el operando necesario ya estuviera en el chip.

Es importante poner esta actuación en contexto. A pesar de que el diseño RISC se había ejecutado más lento que el VAX, no hizo ninguna diferencia en la importancia del diseño. RISC permitió la producción de un verdadero procesador de 32 bits en una matriz de chip real utilizando lo que ya era una fábrica más antigua. Los diseños tradicionales simplemente no podían hacer esto; Con gran parte de la superficie del chip dedicada a la lógica del decodificador, un verdadero diseño de 32 bits como el Motorola 68020 requería nuevas fábricas antes de volverse práctico. Usando las mismas fábricas, RISC I podría haber superado ampliamente a la competencia.

El 12 de febrero de 2015, IEEE instaló una placa en UC Berkeley para conmemorar la contribución de RISC-I. La placa dice:

  • Los estudiantes de UC Berkeley diseñaron y construyeron la primera computadora con conjunto de instrucciones reducido VLSI en 1981. Las instrucciones simplificadas de RISC-I redujeron el hardware para la decodificación y control de instrucciones, lo que permitió un espacio de direcciones plano de 32 bits, un gran conjunto de registros y canalización ejecución. Una buena combinación con los programas C y el sistema operativo Unix, RISC-I influyó en los conjuntos de instrucciones ampliamente utilizados en la actualidad, incluidos los de consolas de juegos, teléfonos inteligentes y tabletas.

RISC II

Si bien el diseño de RISC I sufrió retrasos, el trabajo en Berkeley ya se había centrado en el nuevo diseño de Blue . El trabajo en Blue progresó más lento que en Gold, debido tanto a la falta de una necesidad urgente ahora que Gold iba a ser fabuloso, como a los cambios en las clases y los estudiantes que trabajaban en el esfuerzo. Este ritmo también les permitió agregar varias características nuevas que terminarían mejorando considerablemente el diseño.

La diferencia clave fue un circuito de caché más simple que eliminó una línea por bit (de tres a dos), reduciendo drásticamente el tamaño del archivo de registro. El cambio también requirió una sincronización del autobús mucho más ajustada, pero este fue un pequeño precio a pagar y, para satisfacer las necesidades, también se aceleraron otras partes del diseño.

Los ahorros debido al nuevo diseño fueron tremendos. Mientras que Gold contenía un total de 78 registros en 6 ventanas, Blue contenía 138 registros divididos en 8 ventanas de 16 registros cada una, con otras 10 globales. Esta expansión del archivo de registro aumenta la posibilidad de que un procedimiento dado pueda ajustar todo su almacenamiento local en registros y aumentar la profundidad de anidamiento. Sin embargo, el archivo de registro más grande requería menos transistores, y el diseño azul final, fabulado como RISC II , implementó todo el conjunto de instrucciones RISC con solo 39,000 transistores.

El otro cambio importante fue incluir un expansor de formato de instrucciones , que "convertía" de manera invisible las instrucciones de 16 bits a un formato de 32 bits. Esto permitió que las instrucciones más pequeñas, normalmente cosas con uno o ningún operando, como NOP , se almacenaran en la memoria en un formato más pequeño de 16 bits, y que dos de esas instrucciones se empaquetaran en una sola palabra de máquina. Las instrucciones se expandirían de manera invisible a versiones de 32 bits antes de que alcanzaran la unidad lógica aritmética (ALU), lo que significa que no se necesitaban cambios en la lógica central. Esta sencilla técnica produjo una sorprendente mejora del 30% en la densidad del código, lo que hizo que un programa idéntico en Blue se ejecutara más rápido que en Gold debido a la disminución del número de accesos a la memoria.

RISC II demostró ser mucho más exitoso en silicio y en las pruebas superó a casi todos los miniordenadores en casi todas las tareas. Por ejemplo, el rendimiento varió desde el 85% de la velocidad VAX hasta el 256% en una variedad de cargas. RISC II también se comparó con el famoso Motorola 68000 , entonces considerado como la mejor implementación de chip comercial, y lo superó en un 140% a un 420%.

Seguimientos

El trabajo en los diseños originales de RISC terminó con RISC II, pero el concepto vivió en Berkeley. El núcleo básico se reutilizó en SOAR en 1984, básicamente un RISC convertido para ejecutar Smalltalk (de la misma manera que podría afirmarse que RISC ejecutó C ), y más tarde en el VLSI-BAM similar que ejecutó Prolog en lugar de Smalltalk. Otro esfuerzo fue SPUR , que era un conjunto completo de chips necesarios para construir una estación de trabajo completa de 32 bits .

RISC es menos famoso, pero más influyente, por ser la base del diseño del procesador comercial SPARC de Sun Microsystems . Fue el SPARC el que primero demostró claramente el poder del concepto RISC; cuando se embarcaron en los primeros Sun-4 superaron a todos los del mercado. Esto llevó a prácticamente todos los proveedores de Unix a apresurarse por un diseño RISC propio, lo que llevó a diseños como DEC Alpha y PA-RISC , mientras que Silicon Graphics (SGI) compró MIPS Computer Systems . En 1986, le siguieron la mayoría de los grandes proveedores de chips, trabajando en iniciativas como Motorola 88000 , Fairchild Clipper , AMD 29000 y PowerPC . El 13 de febrero de 2015, IEEE instaló una placa en Oracle Corporation en Santa Clara. Se lee

  • Sun Microsystems introdujo la Arquitectura de Procesador Escalable (SPARC) RISC en 1987. Basándose en UC Berkeley RISC y desarrollos de sistemas operativos y compiladores Sun, la arquitectura SPARC era altamente adaptable a la evolución de la tecnología de semiconductores, software y sistemas y las necesidades de los usuarios. La arquitectura proporcionó el más alto rendimiento, estaciones de trabajo y servidores escalables, para usos de ingeniería, negocios, Internet y computación en la nube.

Las técnicas desarrolladas para y junto con la idea del conjunto de instrucciones reducido también se han adoptado en implementaciones y extensiones cada vez más potentes de la arquitectura x86 "compleja" tradicional . Gran parte del recuento de transistores de un microprocesador moderno se dedica a cachés grandes, muchas etapas de canalización , despacho de instrucciones superescalares , predicción de ramas y otras técnicas modernas que son aplicables independientemente de la arquitectura de instrucciones. La cantidad de silicio dedicada a la decodificación de instrucciones en una implementación x86 moderna es proporcionalmente bastante pequeña, por lo que la distinción entre implementaciones de procesadores "complejos" y RISC se ha vuelto borrosa.

Ver también

Referencias

Citas

Bibliografía