0% encontró este documento útil (0 votos)
37 vistas20 páginas

Main

Este documento describe diferentes conceptos relacionados con la arquitectura de computadoras, incluyendo la segmentación de instrucciones, soluciones a atascos, computadoras de repertorio reducido de instrucciones y memoria. Explica cómo la segmentación de instrucciones divide el proceso de ejecución en etapas para permitir la ejecución simultánea, y cómo esto puede dar lugar a atascos. También describe técnicas para optimizar la segmentación y solucionar diferentes tipos de atascos.

Cargado por

Agustín Murray
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
37 vistas20 páginas

Main

Este documento describe diferentes conceptos relacionados con la arquitectura de computadoras, incluyendo la segmentación de instrucciones, soluciones a atascos, computadoras de repertorio reducido de instrucciones y memoria. Explica cómo la segmentación de instrucciones divide el proceso de ejecución en etapas para permitir la ejecución simultánea, y cómo esto puede dar lugar a atascos. También describe técnicas para optimizar la segmentación y solucionar diferentes tipos de atascos.

Cargado por

Agustín Murray
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Módulo 2

Conceptos de Arquitectura de Computadoras


Polanis, Iván Valentı́n

1
Índice
1. Segmentación de instrucciones 3
1.1. Segmentación en el WinMIPS64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Segmentación de cauce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1. Atascos de un cauce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3. Optimización de la segmentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2. Soluciones a Atascos 5
2.1. Soluciones a riesgos estructurales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2. Soluciones a riesgos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.1. Adelantamiento de operandos (Forwarding) . . . . . . . . . . . . . . . . . . 5
2.2.2. Instrucciones NOP o reordenamiento de código . . . . . . . . . . . . . . . . 6
2.3. Soluciones a riesgos de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.1. Técnicas de predicción de salto (Hardware) . . . . . . . . . . . . . . . . . . 6
2.3.2. Instrucciones de salto retardado (Software) . . . . . . . . . . . . . . . . . . 7

3. Computadoras de repertorio reducido de instrucciones 8


3.1. Caracterı́sticas de la ejecución de instrucciones . . . . . . . . . . . . . . . . . . . . 8
3.2. Utilización de un amplio banco de registros . . . . . . . . . . . . . . . . . . . . . . 9
3.3. Optimización de registros basada en el compilador . . . . . . . . . . . . . . . . . . 11
3.4. Arquitectura de repertorio reducido de instrucciones . . . . . . . . . . . . . . . . . 11

4. Memoria 13
4.1. Diseño de una jerarquı́a de memoria básica . . . . . . . . . . . . . . . . . . . . . . 13
4.2. Mecanismo completo de acceso a memoria . . . . . . . . . . . . . . . . . . . . . . . 14
4.3. Evaluación de prestaciones de la jerarquı́a de memoria . . . . . . . . . . . . . . . . 14
4.4. Niveles de la jerarquı́a de memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.4.1. Diseño de la memoria caché . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5. Buses 17
5.1. Interconexión con buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.1.1. Estructura del bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.1.2. ¿Cómo es un bus? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.1.3. Jerarquı́as de búses múltiples . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.2. Diseño de buses de E/S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.3. PCI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.4. Evolución jerarquı́a de buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2
1. Segmentación de instrucciones
En una arquitectura RISC1 la mayorı́a de las instrucciones son del tipo registro a registro, y
un ciclo de instrucción tiene las dos fases siguientes:

I: captación de instrucción
E: ejecución. Realiza una operación de la ALU como entrada y salida.

Las operaciones de carga y almacenamiento necesitan tres fases:

I: captación de instrucción
E: ejecución. Calcula una dirección de memoria.
D: memoria. Operación registro a memoria o memoria a registro.

Dada la simplicidad y regularidad de un repertorio de instrucciones RISC, el diseño de la


organización en tres o cuatro etapas se realiza fácilmente.

1.1. Segmentación en el WinMIPS64


Búsqueda (F, Fetch)
ˆ Se accede a memoria por la instrucción.
ˆ Se incrementa el Program Counter.
Decodificación (D, Decode)
ˆ Se decodifica la instrucción, obteniendo operación a realizar en la ruta de datos.
ˆ Se accede al banco de registros por el/los operandos/s (si es necesario).
ˆ Se calcula el valor del operando inmediato con extensión de signo (si es necesario).
Ejecución (X, Execute)
ˆ Se ejecuta la operación en la ALU.
Acceso a memoria (M, Memory Access)
ˆ Si se requiere un acceso a memoria, se accede.
Almacenamiento (W, Writeback)
ˆ Si se requiere volcar un resultado a un registro, se accede al banco de registros.

1.2. Segmentación de cauce


La segmentación de cauce (pipelining) es forma particularmente efectiva de organizar el hard-
ware de la CPU para realizar más de una operación al mismo tiempo.
Consiste en descomponer el proceso de ejecución de las instrucciones en fases o etapas que
permitan una ejecución simultánea. Explota el paralelismo entre las instrucciones de un flujo se-
cuencial.
La segmentación es una técnica de mejora de prestaciones a nivel de diseño hardware. La misma
es invisible al programador.
Es necesario uniformizar las etapas al tiempo de la más lenta.
El diseño de procesadores segmentados tiene gran dependencia del repertorio de instrucciones.
La segmentación de cauce incrementa la productividad, pero no reduce el tiempo de ejecución
de la instrucción.
1 Reduced Instruction Set Computer

3
1.2.1. Atascos de un cauce
Son situaciones que impiden a la siguiente instrucción que se ejecute en el ciclo que le corres-
ponde. Estas pueden ser:

Estructurales
Provocados por conflictos por los recursos.
Por dependencia de datos
Ocurren cuando dos instrucciones se comunican por medio de un dato.

Por dependencia de control


Ocurren cuando la ejecución de una instrucción depende de cómo se ejecute otra.

1.3. Optimización de la segmentación


Dada la naturaleza sencilla y regular de las instrucciones RISC, los esquemas de segmentación se
pueden emplear eficientemente. Hay poca variación en la duración de la ejecución de instrucciones,
y el cauce puede adaptarse para reflejar este hecho.
Para compensar las dependencias de datos, se han desarrollado técnicas de reorganización de
código. Consideremos primero las instrucciones de salto. El salto retardado, que es una forma de
incrementar la eficiencia de la segmentación, utiliza un salto que no tiene lugar hasta después de
que se ejecute la siguiente instrucción. La posición de la instrucción inmediatamente después de la
instrucción de salto se conoce como espacio de retardo.
Para saltos condicionales, el procedimiento no puede aplicarse a ciegas. Si la condición compro-
bada por la bifurcación puede alterarse por la instrucción inmediatamente precedente, el compilador
ha de abstenerse de hacer el intercambio en su lugar, debe inserta un NOOP.
Un tipo de táctica similar, llamada carga retardada, se puede usar con las instrucciones LOAD.
En las instrucciones LOAD, el procesador bloquea el registro destino de la carga. Después el
procesador continúa la ejecución del flujo de instrucciones hasta que se alcanza una instrucción
que necesite ese registro, deteniéndose hasta que la carga finalice. Si el compilador puede reorganizar
las instrucciones de manera que se pueda hacer un trabajo útil mientras la carga está en el cauce,
la eficiencia aumenta.

4
2. Soluciones a Atascos
2.1. Soluciones a riesgos estructurales
La solución es simple, se debe replicar, segmentar o realizar turnos para el acceso a las unidades
funcionales en conflicto.

Duplicación de recursos de hardware.


Sumadores o restadores además de la ALU.

Separación en memorias de instrucciones y datos.


Turnar el acceso al banco de registro.
Escrituras en la primera mitad del ciclo de reloj.
Lecturas en la segunda mitad del ciclo de reloj.

2.2. Soluciones a riesgos de datos


Para riesgos RAW se debe determinar cómo y cuando aparecen esos riesgos. Para ello será
necesario una unidad de detección de riesgos y/o un compilador más complejo.
Para este tipo de riesgo tenemos dos soluciones:

Hardware
Adelantamiento de operandos (Forwarding).
Software
Instrucciones NOP o reordenamiento de de codigo.

2.2.1. Adelantamiento de operandos (Forwarding)


Esta técnica consiste en pasar directamente el resultado obtenido con una instrucción a las
instrucciones que lo necesitan como operando. Si el dato necesario está disponible a la salida de la
ALU (Xi ) se lleva a la entrada de la etapa correspondiente (Xi+1 ) sin esperar a la escriturar (Mi
o Wi ).

Figura 1: Adelantamiento de operandos.

5
2.2.2. Instrucciones NOP o reordenamiento de código
Evita los riesgos reordenando las instrucciones del código sin afectar el código. El compilador
es el encargado de realizar esta tarea.
Aquı́ se introducen las instrucciones NOP, que son utilizadas para generar un retardo. Estas
instrucciones no realizan ninguna operación, pero consumen un ciclo de reloj. Ademas, se reordenan
instrucciones para evitar riesgos RAW.

2.3. Soluciones a riesgos de control


En los riesgos de control se introduce la penalización por salto. Cuando el salto es incondicional,
la dirección de destino se debe determinar lo más pronto posible, dentro del cauce, para reducir la
penalización. Cuando el salto es condicional, la penalización se debe a que el procesador no sabe
si se debe tomar o no el salto hasta que se evalúe la condición.
Se utiliza una modificación sencilla de la ruta de datos para reducir la cantidad de paradas a
un solo ciclo:
Adelantar la resolución de los saltos a la etapa D
ˆ En ella se decodifica y se sabe que es un salto.
ˆ Se puede evaluar la condición de salto.
ˆ Se puede calcular la dirección de destino.

2.3.1. Técnicas de predicción de salto (Hardware)


Para este tipo de técnicas tenemos dos posibilidades:
Predicción estática
Se asume que el salto se toma o no se toma.
Predicción dinámica
Se utiliza un predictor de saltos.

Predicción estática
Predicción de salto tomado
Se asume que el salto se toma.
Se adelanta la búsqueda de la dirección de destino.
Predicción de salto no tomado
Se asume que el salto no se toma.
Se continúa con la ejecución secuencial.

Predicción dinámica
Conmutador saltar/no saltar
ˆ Basado en la historia de las instrucciones.
ˆ Es eficaz para los bucles.
Tabla de historia de saltos (BTB)
ˆ Pequeña cache asociada a la etapa de búsqueda (F).
ˆ Contiene tres campos.
Dirección de una instrucción de bifurcación.
Información de la instrucción destino.
N bits de estado (histórico).

6
Otras soluciones
Una técnica que se utiliza es la predicción según el código de operación, ya que existen
instrucciones con más probabilidades de saltar. La tasa de acierto es del 75 %.
Los Flujos múltiples utilizan varios cauces (uno por cada opción de salto). Precaptan cada
salto en diferentes cauces. Las desventajas son que provoca retardos en el acceso al bus y a los
registros. Si hay múltiples saltos, se necesita un mayor número de cauces.
La Precaptación del destino de salto consiste en precaptar la instrucción destino del salto,
además de las instrucciones siguientes a la bifurcación. La instrucción se guarda hasta que se ejecute
la instrucción de bifurcación.
En el Buffer de bucles se utiliza una memoria muy rápida gestionada por la etapa de captación
de instrucción del cauce. Comprueba el buffer antes de hacer la captación de memoria. Esta técnica
es muy eficaz para pequeños bucles y saltos.

2.3.2. Instrucciones de salto retardado (Software)


La idea es realizar trabajo útil mientras el salto se resuelve.

Hueco o ranura de retardo de salto es el perı́odo de penalización o parada luego de una


instrucción de salto.
El compilador trata de situar instrucciones útiles (que no dependan del salto) en los huecos
de retardo. Si no es posible, se utilizan instrucciones NOP.
Las instrucciones en los huecos de retardo de salto se captan siempre.

Requiere reordenamiento de código.

7
3. Computadoras de repertorio reducido de instrucciones
Algunos de los principales avances desde el nacimiento del computador son:

El concepto de familia: introducido por IBM en su System/360 em 1964. El concepto de


familia separa la arquitectura de una máquina de su implementación. Se ofrece un conjunto
de computadores, con distintas caracterı́sticas en cuanto a precio/prestaciones, que presentan
al usuario la misma arquitectura.
Unidad de control micro programada: propuesta por Wilkes en 1951, e introducida
por iBM en la lı́nea S/360 en 1964. La micro programación facilita la tarea de diseñar e
implementar la unidad de control y da soporte al concepto de familia.

Memoria caché: introducida en 1968 por IBM. La introducción de este elemento en la


jerarquı́a de memoria mejoró las prestaciones de manera espectacular.
Segmentación de cauce: una manera de introducir paralelismo en la naturaleza esencial-
mente secuencial de un por instrucciones máquina.

La arquitectura RISC se aparta de manera drástica de la tendencia histórica en la arquitectura


del procesador. Un análisis de la arquitectura RISC involucra la mayorı́a de los asuntos importantes
de organización y arquitectura de computadores.
Los sistemas RISC están caracterizados por:

Un gran número de registros de uso general, o el uso de tecnologı́a de compiladores para


optimizar la utilización de los registros.

Un repertorio de instrucciones limitado y sencillo.


Un énfasis en la optimización de la segmentación de instrucciones.

3.1. Caracterı́sticas de la ejecución de instrucciones


Los repertorios complejos de instrucciones están pensados para:

Facilitar el trabajo del escritor de compiladores.


Mejorar la eficiencia de la ejecución, ya que las secuencias complejas de operaciones pueden
implementarse en micro código.
Dar soporte a HLL2 aun más complejos y sofisticados.

Para comprender la lı́nea de razonamiento de los partidarios de los RISC, comenzamos con
una breve revisión de las caracterı́sticas de la ejecución de instrucciones. Los aspectos cuyo cálculo
tiene interés son los siguientes:

Operaciones realizadas: determinan las funciones que lleva a cabo el procesador y su


interacción con la memoria.

Operandos usados: los tipos de operandos y su frecuencia de uso determinan la organización


de memoria para almacenarlos y los modos de direccionamiento para acceder a ellos.
Secuenciamiento de la ejecución: determina la organización del control y del cauce seg-
mentado.
2 High Level Language

8
Operaciones
Existe una gran concordancia en los resultados de esta mezcla de lenguajes y aplicaciones. Las
sentencias de asignación predominan, lo cual indica que el sencillo movimiento de datos tiene mucha
importancia. También predominan las sentencias condicionales (IF, LOOP). Estas sentencias se
implementen en el lenguaje máquina con alguna instrucción del tipo comparar y saltar. Esto indica
que el mecanismo incluido en el repertorio de instrucciones para el control del secuenciamiento es
importante.
Estos resultados son instructivos para el diseñador del repertorio de instrucciones máquina,
diciéndole qué tipo de sentencias tiene lugar más a menudo y por consiguiente deben ser imple-
mentadas de una forma óptima.

Operandos
EL estudio de Patterson ya referenciado también consideró la frecuencia dinámica de apari-
ción de distintas clases de variables. Los resultados, coherentes para programas en Pascal y en
C, muestran que la mayorı́a de las referencias se hacen a variables escalares simples. Además,
más del ochenta por ciento de los datos eran variables locales. Asimismo, las referencias a matri-
ces/estructuras requieren una referencia previa a su ı́ndice o puntero, que nuevamente suele ser
un dato escalar local. Por consiguiente, hay un predominio de referencias a operandos escalares, y
estos están muy localizados.
Estos estudios reflejan la importancia de una arquitectura que se preste a un rápido acceso a
operandos, dado que es una operación que se realiza con mucha frecuencia. El estudio de Patterson
indica que un candidato fundamental a optimizar es el mecanismo de almacenamiento y acceso a
variables escalares.

Llamadas a procedimientos
Las llamadas y retornos de procedimientos constituyen un aspecto importante de los programas
en HLL. Los estudios indican que son las operaciones que consumen más tiempo en programas en
HLL compilados.
Esto depende del número de parámetros tratados y del nivel de anidamiento. La mayorı́a de los
programas no tienen una larga secuencia de llamadas seguida por la correspondiente secuencia de
retornos. Además la mayorı́a de las variables suelen ser locales y las referencias a operandos están
muy localizadas.
Partiendo del trabajo de varios investigadores, surgen tres elementos que, por lo general, ca-
racterizan las arquitecturas RISC:

Utilización de un amplio banco de registros

Cuidadosa atención al diseño de los cauces de instrucciones.


Uso de un repertorio simplificado de instrucciones

3.2. Utilización de un amplio banco de registros


Se necesita una estrategia que permita que los operandos a los que se acceda con mayor fre-
cuencia se encuentren en registros y se minimicen las operaciones registro-memoria.
Son posibles dos aproximaciones básicas, una basada en software y la otra en hardware.
La aproximación por software consiste en confiar al compilador la maximización del uso de los
registros. El compilador intentará asignar registros a las variables que se usen más en un periodo
dado. Esta solución requiere el uso de sofisticados algoritmos de análisis de programas.
La aproximación por hardware consiste sencillamente en usar más registros de manera que
puedan mantenerse en ellos más variables durante perı́odos de tiempo más largos.

9
Ventanas de registros
A primera vista, el uso de un conjunto amplio de registros deberı́a reducir la necesidad de
acceder a memoria. La labor del diseño es organizar los registros de tal modo que se alcance esa
meta.
Una llamada a un procedimiento hace que el procesador conmute automáticamente a una
ventana de registros distinta de tamaño fijo, en lugar de salvaguardar los registros en memoria.
Las ventanas de procedimientos adyacentes están parcialmente solapadas para permitir el paso de
parámetros.
La ventana se divide en tres áreas de tamaño fijo. Los registros de parámetros contienen paráme-
tros pasados al procedimiento actual desde el procedimiento que lo llamó, y los resultados a de-
volver a este. Los registros locales se usan para variables locales, según la asignación que realice
el compilador. Los registros locales se usan para variables locales, según la asignación que realice
el compilador. Los registros temporales se usan para intercambiar parámetros y resultados con
el siguiente nivel más bajo (el procedimiento llamado por el procedimiento en curso). Los regis-
tros temporales de un nivel son fı́sicamente los mismos que los registros de parámetros del nivel
más bajo adyacente. Este solapamiento posibilita que los parámetros se pasen sin que exista una
transferencia de datos real.
Para manejar cualquier patrón posible de llamadas y retornos, el número de ventanas de regis-
tros tendrı́a que ser ilimitado. En lugar de eso, las ventanas de registros se pueden usar para con-
tener unas pocas, las más recientes, activaciones de procedimientos. Las activaciones más antiguas
han de salvaguardarse en memoria y restaurarse más tarde cuando la profundidad de anidamiento
disminuya.

Figura 2: Organización de las ventanas solapadas con un buffer circular.

Variables Globales
Para tratar variables globales se sugieren dos opciones.
La primera es que el compilador asigne posiciones de memoria a las variables declaradas como
globales en un HLL, y que todas las instrucciones máquina que referencien esas variables declaradas
como globales en un HLL, y que todas las instrucciones máquina que referencien esas variables
usen operandos referenciados en memoria.
Una alternativa es incorporar al procesador un conjunto de registros globales. Estos registros
serı́an fijos en cuanto a su número y accesibles por todos los procedimientos. Se puede usar un

10
esquema de numeración unificado para simplificar el formato de instrucción. Esto conlleva un
hardware añadido, que se encarga de adaptar la división en el direccionamiento de los registros.

Un amplio banco de registros frente a una caché

Banco de registros amplio Caché


Todos los datos escalares locales Datos escalares locales recientemente usados
Variables individuales Bloques de memoria
Variables globales asignadas por el compilador Variables recientemente
Salvaguarda basadas en la profundidad de anidamiento Salvaguarda basadas en el algoritmo de reemplazo
Direccionamiento a registros Direccionamiento a memoria

3.3. Optimización de registros basada en el compilador


Supongamos que ahora disponemos de una máquina RISC que contiene unicamente un pequeño
número de registros. En ese caso, el uso optimizado de registros es responsabilidad del compilador.
Los programas escritos en HLL no tienen referencias explicitas a los registros. El objetivo del
compilador es mantener en registros en lugar de en memoria los operandos necesarios para tantos
cálculos como sea posible, y minimizar las operaciones de carga y almacenamiento.
Por lo general se sigue el siguiente enfoque. Cada cantidad del programa candidata para residir
en un registro se asigna a un registro simbólico o virtual. El compilador entonces asigna el número
ilimitado de registros simbólicos a un número fijo de registros reales. Los registros simbólicos cuya
utilización no se solape pueden compartir el mismo registro real. Si en una parte concreta del
programa hay más cantidades a tratar que registros reales, algunas de las cantidades se asignan a
posiciones de memoria.

3.4. Arquitectura de repertorio reducido de instrucciones


¿Por qué CISC?
La primera de las razones es, la simplificación de los compiladores. La labor del escritor de
compiladores es generar una secuencia de instrucciones máquina para cada sentencia HLL. Se
existen instrucciones máquina que se parezcan a sentencias del HLL, la tarea se simplifica.
La otra razón importante mencionada es la esperanza de que un CISC produzca programas
más pequeños y rápido. Los programas más pequeños tienen dos ventajas. Como el programa
ocupa menos memoria, hay un ahorro de este recurso, pero como la memoria hoy en dı́a es tan
barata, este aspecto no es primordial. Tiene mayor importancia el hecho de que programas más
pequeños mejoren las prestaciones porque tienen menos instrucciones, lo que significa que hay que
captar menos bytes de instrucciones. El segundo es que en un entorno paginado los programas más
pequeños ocupan menos páginas, reduciendo los fallos de página. Sin embargo, el número de bits
de memoria que ocupa, no tiene por qué ser más pequeño al tener menos instrucciones.
El segundo factor que motivaba repertorios de instrucciones cada vez más complejos era que la
ejecución de instrucciones fuera más rápida. Parece tener sentido el que una operación compleja
de un HLL se ejecute más rápido como una única instrucción máquina que como una sucesión de
instrucciones más primitivas. Sin embargo, debido a la propensión a usar las instrucciones más
sencillas, esto puede no ser ası́. La unidad de control completa debe hacerse más compleja, y/o la
memoria de control del micro programa ha de hacerse más grande, para acomodar un repertorio
de instrucciones más rico.

Caracterı́sticas de RISC
Una instrucción por ciclo.
Operaciones registro a registro.

11
Modos de direccionamiento sencillos.

Formatos de instrucción sencillos.

Un ciclo máquina se define como el tiempo que se tarda en captar dos operandos desde dos
registros, realizar una operación de la ALU y almacenar el resultado en un registro. Ası́, las ins-
trucciones máquina de un RISC no deberı́an ser más complicadas que las micro instrucciones de
las máquinas CISC, y deberı́an comportarse más o menos igual de rápido.
Una segunda caracterı́stica es que la mayorı́a de las operaciones deben ser del tipo registro a
registro con la excepción de sencillas operaciones LOAD y STORE para acceder a memoria.
Casi todas las instrucciones RISC usan direccionamiento sencillo a registro. Se pueden incluir
varios modos adicionales, como el desplazamiento y el relativo al contador de programa.
Por último, solo se usa un formato o unos pocos. La longitud de las instrucciones es fija y
alineada en los limites de una palabra. Las posiciones de los campos, especialmente la del código
de operación, son fijas.

12
4. Memoria
4.1. Diseño de una jerarquı́a de memoria básica
El sistema de memoria formado por una memoria principal única que se propuso en los primeros
modelos de computador sencillo quedó descartado rápidamente por sus bajas prestaciones.
La alternativa a esta memoria única es una jerarquı́a de memoria organizada en niveles, cuanto
más cercanos al procesador, más pequeños, rápidos y caros. Hoy en dı́a esta jerarquı́a incluye, en
casi todos los casos, tres tipos de memorias: memoria caché, memoria principal y memoria virtual.

Memoria Caché (MC): Se ubica dentro del mismo chip que el procesador, fabricada con
RAM estática (SRAM) y controlada por el controlador de caché incluido en el mismo chip.
Hoy en dı́a lo habitual es que haya varios niveles de caché.
Memoria Principal (MP): Se ubica en un chip diferente al procesador, fabricada con RAM
dinámica (DRAM) y controlada por el controlador de memoria principal. Este controlador
es muy importante para el rendimiento de la jerarquı́a de memoria ya que se encarga de la
planificación de los accesos a memoria principal. Hoy en dı́a puede ubicarse en el mismo chip
que el procesador y la memoria caché, o en otro chip como el el chipset norte o el MCH.
Memoria virtual (MV): Ubicada en la actualidad en el disco duro, se fabrica por lo tanto
con tecnologı́a magnética y se controla desde el sistema operativo a través del controlador
del disco duro.

El objetivo es conseguir una estructura de memoria de gran capacidad, con un coste casi tan
bajo como el del nivel más barato de la jerarquı́a, pero con latencia comparable a la del nivel más
rápido.
Hay dos propiedades que la jerarquı́a debe cumplir para que su funcionamiento sea adecuado:

Inclusión: implica que cualquier información contenida en un nivel de la jerarquı́a debe estar
también en los niveles superiores (en los que están más lejos del procesador a partir de él):
Coherencia: garantiza que las copias de la misma información en los diferentes niveles de
la jerarquı́a son coherentes entre sı́, es decir, que almacenan los mismos valores.

Cuando el procesador realiza un acceso a memoria, primero se busca la palabra que hay que
leer o escribir en la memoria caché (MC). Si esta palabra se encuentra en la caché, ha ocurrido
un acierto. Si por el contrario, no se encuentra a ocurrido un fallo.
En este último caso, se traerá de memoria principal (MP) un bloque que contendrá varias
palabras, entre ellas, la que ha producido el fallo.
El principio de localidad tiene dos aspectos diferentes:

Localidad espacial: es la tendencia del procesador a referenciar elementos de memoria


cercanos a los últimos que han sido referenciados.
Localidad temporal: es la tendencia del procesador a referenciar elementos de memoria
que han sido referenciados recientemente.

Al acceder a memoria principal también pueden producirse aciertos y fallos, ya que no toda
la información cabe al mismo tiempo en este nivel. La relación entre la memoria principal y la
memoria virtual es similar a la que existe entre la memoria caché y la principal.
La memoria principal se divide en páginas o segmentos, de mayor tamaño que los bloques de
caché. Cuando se produce un fallo con una página o segmento que no se encuentra en la memoria
principal, deberá traerse de la memoria virtual.
La principal diferencia con los fallos de la memoria caché está en que la penalización por este
tipo de fallos es bastante grande, ya que la memoria virtual es la más lenta de toda la jerarquı́a.
Por ello el procesador suele pasara realizar otro tipo de tareas, realizando un cambio de contexto,
hasta que la página o segmento esté disponible en la memoria principal.

13
4.2. Mecanismo completo de acceso a memoria
En primer lugar, el procesador genera la dirección virtual de la palabra que se debe leer o
escribir. Normalmente, lo primero que se hace es traducir esta dirección virtual a una dirección
fı́sica comprensible para la jerarquı́a de memoria.
Si se consigue realizar esta traducción de dirección, es porque la palabra que está buscando se
encuentra actualmente en la memoria principal. Con esta dirección se accede a la memoria caché,
y si la palabra buscada se encuentra en este nivel, el acceso a memoria ya ha finalizado.
Si por el contrario, se produce un fallo, se busca la palabra en el siguiente nivel, en este caso
en la memoria principal, (si existiese otro nivel de cache, se buscarı́a primero allı́).
La resolución de un fallo siempre implica buscar el bloque necesario en la memoria principal.
Cu¿ando se realice el acceso, todo el bloque en el que se incluye la palabra solicitada por el
procesador se envı́a a la memoria caché para resolver su fallo, y el acceso puede completarse con
éxito.
Si por el contrario, la palabra no se encuentra en memoria principal y desde un principio no
se pudo traducir su dirección virtual a dirección fı́sica por este motivo, se debe resolver el fallo de
página o segmento desde la memoria virtual. El sistema operativo realiza un cambio de contexto
para que otro proceso pase a ejecutarse en el procesador mientras se trae desde memoria virtual
la página o segmento, que hace falta para resolver el fallo. Una vez que esté en memoria principal
esta página o segmento, ya puede llevarse el bloque correspondiente a memoria caché y cuando el
proceso que habı́a provocado el fallo vuelva a pasar a ejecución, el acceso puede completarse con
éxito.
Para un procesador segmentado, los accesos a memoria en la etapa MEM, en su mayorı́a, sólo
tienen en cuenta los accesos a caché, y si hay que resolver un fallo, el tiempo que se tarda en resolver
este fallo se considera un tiempo extra que hay que sumar al tiempo que tarda en ejecutarse una
instrucción.

4.3. Evaluación de prestaciones de la jerarquı́a de memoria


En el caso de la jerarquı́a de memoria también se puede definir una ecuación de prestaciones
que proporciones una herramienta cuantitativa de evaluación de rendimiento.
En este caso lo que interesa saber es cuánto tiempo le cuesta en media al procesador realizar un
acceso a memoria. Si la memoria caché fuera perfecta y no fallara nunca, el tiempo medio de acceso
a memoria serı́a justo el tiempo de acierto a la memoria caché. Pero como se producen fallos, el
tiempo medio de acceso a memoria se calcula teniendo en cuenta estos fallos y el tiempo que se
invierte en resolverlos, lo que se ha denominado penalización por fallo:

tM EM = taciertoM C + T F · pF

taciertoM C : Tiempo de acierto de MC


número de fallos
T F : Tasa de fallos de MC → T F =
número total de accesos a memoria
pF : Penalización por fallo en MC

Si lo que interesa es evaluar las prestaciones de la memoria principal o de la memoria virtual


como niveles aislados de la jerarquı́a, las métricas que se suelen utilizarse son:

Latencia: tiempo que transcurre desde que un acceso a memoria comienza hasta que finaliza.
Está muy relacionada con la tecnologı́a con la que está fabricada la memoria.

Ancho de banda: cantidad de información por unidad de tiempo que puede transferirse
desde/hacia la memoria. En este caso está muy relacionado con la organización de la memoria
más que con la tecnologı́a.

14
4.4. Niveles de la jerarquı́a de memoria
4.4.1. Diseño de la memoria caché
La memoria caché almacena en cada momento unos determinados bloques de información, por
lo tanto se divide en marcos capaces de albergar estos bloques en su interior.
La caché no sólo se compone de marcos, ya que para determinar qué bloque está ocupando un
determinado marco en un instante concreto se utilizan etiquetas que también deben almacenarse
en la memoria. Esta etiquetas se comparan con la del bloque que se está buscando para determinar
si éste se encuentra o no en la memoria caché.

Organización de la memoria caché


El primer aspecto importante a decidir es el tamaño de la cache, no puede ser demasiado
pequeña ya que aumentarı́a el número de fallos porque no se capturarı́a bien la localidad.
Tampoco puede ser demasiado grande por dos motivos, el primero es que va integrada en el
chip de la cpu y el segundo es que una cache muy grande requerirı́a una lógica más compleja, por
lo que serı́a más lenta.
El segundo aspecto a tener en cuenta es el tamaño de marco que se va a manejar. Devuelta
tenemos el mismo problema, si capturamos bloques muy grandes se captura mejor la localidad
espacial, pero a su vez aumenta la penalización por fallo, ya que se necesitarı́a más tiempo para
traer los bloques del siguiente nivel de la jerarquı́a de memoria.
En muchos casos, la segmentación del procesador obligará a dividir la caché de instrucciones y
la de datos para evitar los riesgos estructurales entre las etapas de búsqueda de instrucción y las
de acceso a memoria para la lectura o escritura de operandos/resultados.
Por último, destacar dentro de la organización de la caché uno de los aspectos que más influye
ene l rendimiento de la jerarquı́a de memoria: la implementación de cachés multinivel.
Normalmente se utilizan dos niveles de memoria caché:

L1: este nivel es el más cercano al procesador, por lo tanto, esta memoria caché es pequeña
y rápida.
L2: es el siguiente nivel de la jerarquı́a, de mayor tamaño (por lo que aprovecha mejor el
principio de localidad) y por lo tanto, más lento aunque con menos fallos de capacidad.

De esta manera, cuando se produzca un fallo en el nivel 1 de la memoria, la penalización de


esta fallo será menor que si sólo hubieran un nivel de caché, porque en lugar de ir a la memoria
principal irá a la caché de nivel 2.

Polı́tica de ubicación
Hay tres tipos de ubicación:

Directo: a cada bloque le corresponde un único marco de caché y sólo puede alojarse en este
marco.

Asociativo: un bloque puede alojarse en cualquier marco de la memoria caché.


Asociativo por conjuntos: la memoria caché se divide en conjuntos con un número deter-
minado de marcos por conjunto. A un determinado bloque le corresponde un único conjunto,
pero dentro de él, puede alojarse en cualquier marco.

Las diferentes alternativas para la ubicación en la memoria caché llevan a diferentes interpre-
taciones de la dirección fı́sica desde el punto de vista de esta memoria. Según el tipo de ubicación
de la memoria caché:

Directo: el ı́ndice indica al marco que le corresponde a ese bloque de memoria.

15
Asociativo: no existe este campo en la dirección, ya que el bloque puede alojarse en cualquier
marco.
Asociativo por conjuntos: el ı́ndice indica el conjunto que le corresponde a ese bloque de
memoria.

Polı́tica de reemplazo
Además de decidir la polı́tica de ubicación de la memoria caché, también es necesario definir
qué ocurre cuando se produce un fallo. Si no se encuentra un determinado bloque de memoria en
la caché, habrá que traerlo del siguiente nivel de la jerarquı́a de memoria. Pero, ¿qué bloque se
reemplaza?
En el caso de una caché directa, no cabe ninguna duda, puesto que cada bloque sólo puede
alojarse en un determinado marco. Pero en el caso de memorias con una asociatividad mayor, el
reemplazamiento puede hacerse con distintos tipos de polı́ticas.

Aleatoria: se utiliza un generador de números aleatorios para escoger el bloque que se


reemplaza.

Least Recently Used (LRU): se escoge el bloque que lleva más tiempo sin utilizarse. Asi
se minimiza la probabilidad de sustituir un bloque que vaya a necesitarse en el futuro.
First In, First out (FIFO): se reemplaza el bloque que lleva más tiempo en la caché.

Polı́tica de escritura
Las escrituras llevan más tiempo ya que no pueden solaparse con la comparación de las etiquetas
como se hace con las lecturas. En muchos casos se recupera la información de un marco determinado
de caché antes de saber si el bloque que está ubicado en él es el que se está buscando. Esto sólo
puede hacerse con operaciones de lectura, ya que si finalmente el bloque no es el adecuado, no se
ha modificado sun contenido.
Pero una operación de escritura sólo puede hacerse si la comparación de etiquetas da como
resultado que el bloque ubicado en ese marco es el que se estaba buscando; no se puede hacer
trabajo en paralelo:

Escritura directa: cuando se modifica una palabra con una instrucción de almacenamiento,
se realiza la escritura en el primer nivel de caché y en el siguiente nivel de la jerarquı́a.

Post-Escritura: cuando se modifica una palabra sólo se hace en el primer nivel de la me-
moria caché. Cuando este bloque modificado sea reemplazado, se actualizará el contenido dle
nivel siguiente. Para no actualizar la memoria con cada reemplazamiento que se haga, suele
utilizarse un bit que indica si el bloque que está en cache ha sido modificado (sucio) y por lo
tanto debe actualizarse en memoria, o no (limpio).

Por último, en el caso de algunas jerarquı́as de memoria, para evitar la penalización extra que
las escrituras implican se ignoran los fallos de escritura, especialmente en el caso de las memorias
de escritura directa.
Por lo tanto suelen encontrarse dos opciones:

Write Allocate: los fallos de escritura se comportan como los fallos de lectura, se trae el
bloque que ha provocado el fallo a la memoria caché y se realiza en función de la polı́tica
utilizada. Habitual con Post-Escritura.
No-write Allocate: cuando se produce un fallo de escritura, el bloque se modifica directa-
mente en el siguiente nivel de la jerarquı́a de memoria y no se trae a la caché. Habitual con
Escritura directa.

16
5. Buses
Un computador es una red de módulos elementales. Por consiguiente, deben existir lineas para
interconectar estos módulos.
Existen distintos tipos de interconexiones para los distintos tipos de unidades:

Memoria: un módulo de memoria está constituido por N palabras de la misma longitud. A


cada palabra se le asigna una única dirección numérica (entre 0 y N-1). Una palabra de datos
puede leerse de o escribirse en memoria. El tipo de operación se indica mediante las señales
de control Read y Write. La posición de memoria para la operación se especifica mediante
una dirección.
Módulo de E/S: Hay dos tipos de operaciones, leer y escribir. Además, un módulo de E/S
puede controlar más de un dispositivo externo. Nos referiremos a cada una de estas interfaces
con un dispositivo externo con el nombre de puerto, y se le asignara una dirección a cada
uno. Por otra parta, existen lı́neas externas de datos para la entrada y la salida de datos por
un dispositivo externo. Por último, un módulo de E/S puede enviar señales de interrupción
al procesador.

Procesador: el procesador lee instrucciones y datos, escribe datos una vez los ha procesado,
y utiliza ciertas señales para controlar el funcionamiento del sistema. También puede recibir
señales de interrupción.

5.1. Interconexión con buses


Un bus es un camino de comunicación entre dos o más dispositivos. Una caracterı́stica clave
de un bus es que se trata de un medio de transmisión compartido. Al bus se conectan varios
dispositivos, y cualquier señal transmitida por uno de esos dispositivos está disponible para que
los otros dispositivos conectados al bus puedan acceder a ella. Solo un dispositivo puede transmitir
con éxito en un momento dado.

5.1.1. Estructura del bus


El bus del sistema está constituido, usualmente, por entre cincuenta y cien lineas. A cada
lı́nea se le asigna un significado o una función particular. Aunque existen diseños de buses muy
diversos, se suelen clasificar en tres grupos funcionales:

Lı́neas de datos
Proporcionan un camino para transmitir datos entre los módulos del sistema. El conjunto
constituido por estas lı́neas se denomina bus de datos. El bus de datos puede incluir entre 32 y
cientos de lineas, cuyo número se conoce como anchura del bus de datos. Puesto que cada lı́nea solo
puede transportar un bit cada vez, el número de lı́neas determina cuántos bits se pueden transferir
al mismo tiempo.

Lı́neas de dirección
Se utilizan para designar la fuente o el destino del dato situado en el bus de datos. Claramente,
la anchura del bus de direcciones determina la máxima capacidad de memoria posible en el sistema.
Además, las lı́neas de direcciones generalmente se utilizan también para direccionar los puestos de
E/S dentro de un módulo. Usualmente, los bits de orden más alto se utilizan para seleccionar una
posición de memoria o un puerto de E/S dentro de un módulo.

17
Lineas de control
Se utilizan para controlar el acceso y el uso de las lı́neas de datos y de direcciones. Puesto que
las lı́neas de datos y de direcciones son compartidas por todos los componentes, debe existir una
forma de controlar su uso. Las señales de control transmiten tanto órdenes como información de
temporización entre los módulos. Las señales de temporización indican la validez de los datos y las
direcciones. Las señales de órdenes especifican las operaciones a realizar.

5.1.2. ¿Cómo es un bus?


Fı́sicamente, el bus de sistema es de hecho un conjunto de conductores eléctricos paralelos.
Estos conductores son lı́neas de metal grabadas en una tarjeta. El bus se extiende a través de
todos los componentes del sistema, cada uno de los cuales se conecta a algunas o a todas las lı́neas
del bus.
Cada uno de los componentes principales del sistema ocupa una o varias tarjetas y se conecta
al bus a través de esas ranuras. Los sistemas actuales tienden a tener sus componentes principales
en la misma tarjeta y los circuitos integrados incluyen más elementos. Asi, el bus que conecta el
procesador y la memoria caché se integra con el microprocesador junto con el procesador y la caché
(on-chip), y el bus que conecta el procesador con la memoria y otros componentes se incluye en la
tarjeta (on-board).

5.1.3. Jerarquı́as de búses múltiples


Si se conecta un gran número de dispositivos al bus, las prestaciones pueden disminuir. Hay
dos causas principales:

En general, a más dispositivos conectados al bus, mayor es el retardo de propagación. Este


retardo determina el tiempo que necesitan los dispositivos para coordinarse en el uso del bus.
El bus puede convertirse en un cuello de botella a medida que las peticiones de transferencia
acumuladas se aproximan a la capacidad del bus.

Por consiguiente, la mayorı́a de los computadores utilizan varios buses, normalmente organiza-
dos jerárquicamente.

Bus del sistema y bus de memoria: son los que conectan el procesador con el resto del
sistema y la memoria principal con el controlador de memoria respectivamente. Se trata de
buses rápidos y cortos, propietarios y optimizados para arquitecturas y diseños especı́ficos.
Esta optimización es posible qa que a estos buses se conectan un número fijo de dispositivos
de prestaciones conocidas.
Buses de expansion: se trata de buses más largos y lentos, abiertos, accesibles por el
usuario y a los que se conectan un número indeterminado de dispositivos de prestaciones
desconocidas muy diferentes entre sı́.

Es posible conectar controladores de E/S directamente al bus de sistema. Una solución más
eficiente consiste en utilizar uno o más buses de expansión. La interfaz del bus de expansión
regula las transferencias de datos entre el bus de sistema y los controladores conectados al bus de
expansión. Esta disposición permite conectar al sistema una amplia variedad de dispositivos de
E/S y al mismo tiempo aislar el tráfico de información entre la memoria y el procesador del tráfico
correspondiente a la E/S.
Esta arquitectura de buses tradicional es razonablemente eficiente, pero muestra su debilidad
a medida que los dispositivos de E/S ofrecen prestaciones cada vez mayores. La respuesta común
a esta situación, por parte de la industria, ha sido proponer un bus de alta velocidad que está
estrechamente integrado con el resto del sistema, y requiere solo un adaptador (bridge) entre el
bus del procesador y el bus de alta velocidad.

18
Tipos de buses
Los buses dedicados, usan lı́neas separadas para direcciones y para datos. Suelen tener 16
lı́neas de direcciones y 16 lı́neas de datos. Tienen una lı́nea de control de lectura ó escritura.
Los buses multiplexados, usa las mismas lı́neas, tienen 16 lı́neas que pueden ser tanto para
direcciones como para datos, una lı́nea de control para escritura ó lectura y una lı́nea de control
para definir direcciones ó datos.

Arbitraje del bus


El control del bus puede necesitar más de un módulo. Solamente una unidad puede transmitir
a través del bus en un instante dado. Los métodos de arbitraje se pueden clasificar en:

Centralizado: un único dispositivo hardware, denominado controlador del bus o árbitro, es


responsable de asignar tiempos en el bus. El dispositivo puede estar en un módulo separado
o ser parte el procesador.
Distribuido: no existe un controlador central. En su lugar, cada módulo dispone de lógica
para controla el acceso y los módulos actúan conjuntamente para compartir el bus.

En ambos métodos de arbitraje, el propósito es designar un dispositivo, el procesador o un


módulo de E/S como maestro del bus. El maestro podrı́a entonces iniciar una transferencia de
datos con otro dispositivo, que actúa como esclavo en este intercambio concreto.

Temporización
El término temporización hace referencia a la forma en la que se coordinan los eventos en el
bus. Los buses utilizan temporización sı́ncrona o ası́ncrona.

Temporización sı́ncrona: La presencia de un evento está determinada por un reloj. El bus


incluye una lı́nea de reloj. Un intervalo desde un uno seguido de otro a cero se conoce como
ciclo de bus. Todos los dispositivos del bus pueden leer la lı́nea de reloj. Suele sincronizar en
el flanco de subida. La mayorı́a de los eventos se prolongan durante un único ciclo de reloj.

Temporización ası́ncrona: la presencia de un evento en el bus es consecuencia y depende de


que se produzca un evento previo. El módulo de memoria correspondiente decodifica la direc-
ción y responde proporcionando el dato en la lı́nea de datos. Una vez estabilizadas las lı́neas
de datos, el módulo de memoria activa la lı́nea de reconocimiento para indicar al procesador
que el dato está disponible. Cuando el maestro ha leı́do el dato de las lı́neas correspondien-
tes, deshabilita la señal de lectura. Esto hace que el módulo de memoria libere las lı́neas de
tatos y reconocimiento. Por último, una vez se ha desactivado la lı́nea de reconocimiento, el
procesador quita la información de dirección de las lı́neas correspondientes.

5.2. Diseño de buses de E/S


Es necesario diseñar el protocolo de transferencia que gobierna la operación del bus y especifica
cómo se utilizan las señales de datos, control y direcciones para realizar una transferencia de
información completa.
Además es necesario decidir el tipo de protocolo que sincroniza las transferencias de información
y en este casi si que existe un conjunto muy reducido de alternativas. En los buses sincrónicos las
transferencias están gobernadas por una única señal de reloj compartida por todos los dispositivos
que se conectan al bus, de manera que cada transferencia se realiza en un número fijo de ciclos de
reloj.
Los protocolos sincrónicos son muy sencillos y sólo necesitan una señal de reloj. Pero hay
que adaptar esta señal al dispositivo más lento y además es necesario distribuirla a todos los
dispositivos conectados al bus. También existen confirmaciones en las transferencias por lo que es
difı́cil implementar mecanismos de detección y corrección de errores. Con los protocolos ası́ncronos

19
no existen estos inconvenientes, pero son menos eficientes debido a la necesidad de intercambiar
señales de control.
Por eso surgen los buses semisı́ncronos, que combinan las ventajas de los dos anteriores, se
comportan como sı́ncronos para dispositivos rápidos y como ası́ncronos para dispositivos lentos.

5.3. PCI
El bus PCI es un bus muy popular de ancho de banda elevado, independiente del procesador,
que se puede utilizar como bus de periféricos o bus para una arquitectura de entreplanta. Com-
parado con otras especificaciones comunes de bus, el PCI proporciona mejores prestaciones para
los subsistemas de E/S de alta velocidad. El PCI ha sido diseñado especı́ficamente para ajustarse,
económicamente a los requisitos de E/S de los sistemas actuales; se implementa con muy pocos
circuitos integrados y permite que otros buses se conecten al bus PCI.
El PCI esta diseñado para permitir una cierta variedad de configuraciones basadas en micro-
procesadores, incluyendo sistemas tanto de uno como de varios procesadores. Por consiguiente,
proporciona un conjunto de funciones de uso general. Utiliza temporización sı́ncrona y un esquema
de arbitraje centralizado.

5.4. Evolución jerarquı́a de buses


Ver páginas 117 a 120 de Diseño y Evaluación de arquitectura de computadores.

20

También podría gustarte