Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Segmentacion PDF
Segmentacion PDF
Curso 2010-2011
SEGMENTACIÓN
La segmentación es una técnica de diseño de procesadores que se viene empleando desde la tercera
generación de computadores. En la figura siguiente podemos ver como se han diseñado los
procesadores en cada generación.
En las dos figuras siguientes se puede observar cómo funciona la segmentación cuando se ejecutan
varias instrucciones sobre un procesador segmentado. La figura 1 es en el caso ideal, y la figura 2 en
el caso real.
Ejemplo 1: Sea un procesador segmentado en 5 etapas con una duración de (50, 50, 60, 50, 50) nseg
de duración para cada una de las etapas. Es decir, cuando ejecuta una instrucción de forma no
segmentada, tarda 260 nseg en ejecutarla.
Si este mismo procesador lo diseñamos de forma segmentada, deberemos añadir 5 nseg. a cada etapa
debido al retardo de los biestables que almacenan la información entre etapas.
Ver el esquema siguiente:
La pregunta es, cuando ejecutamos N=10 instrucciones, ¿qué aceleración y que eficiencia se
consiguen?
n 10 10
Eficiencia 0.71
(k (n 1)) (5 (10 1)) 14
Ejemplo 2: En esta figura 6.3 del Tomo 2 de “Estructura y diseño de Computadores” (Ed. Reverté)
Se puede observar cómo se realiza la ejecución de una instrucción de DLX de forma no segmentada.
Se observa como al ejecutarse de forma segmentada, se necesita definir un único tiempo de
segmento, por lo cual elegimos el segmento de mayor duración.
Antes de pasar a ver como definimos con detalle las operaciones a realizar en cada uno de los
segmentos de ejecución segmentada de DLX, debemos recordar cuales son los tres formatos de
instrucciones de que dispone.
También necesitamos recordar la estructura del procesador DLX con ejecución monociclo, pues en
esta estructura nos basaremos para definir el procesador segmentado.
1. IF-Paso de búsquea de instrucción: Se pasa el valor del Contador de Programa (PC) al Registro
de Acceso a Memoria (MAR). Se lee de memoria la siguiente instrucción y se carga en el RI.
MAR PC ; IR Mem[MAR
3. EX-Paso de dirección efectiva /ejecución. La ALU podrá operar con los operandos del paso
anterior para realizar una de estas tres funciones.
i) Referencia a memoria: La ALU suma los operandos para formar la dirección efectiva y se
carga en el MDR.
MAR A+(IR16)16##IR16..31; MDR Rd
ii) Instrucción ALU: La ALU realiza la instrucción especificada por el código de operación
sobre los registros Rs1 y Rs2 o Rs1 y un valor inmediato.
ALU-salida (A op B) ó (A op ((IR16)16##IR16..31))
iii) Salto/bifurcación: La ALU suma el PC al valor inmediato de signo extendido (de 16 bits
para saltos y 26 para bifurcaciones) y así calcula la dirección de salto.
ALU-salida PC + ((IR16)16##IR16..31)) ; cond (A op 0)
Para saltos condicionales se examina un registro que ha sido leído en un paso anterior para saber si la
dirección calculada se coloca en el PC.
La arquitectura de carga/almacenamiento de DLX supone que el cálculo de una dirección efectiva y
la ejecución de una instrucción en la ALU se pueden superponer, pues ninguna instrucción aritmética
necesita calcular una dirección para acceder a un operando.
4. MEM-Paso de completar salto/acceso a memoria: las únicas instrucciones DLX activas en este
paso son las de acceso a memoria y los saltos.
i) Referencia a memoria: Accede a memoria para leer o escribir un dato.
MDR Mem[MAR ó Mem[MAR MDR
ii) Salto: El valor de PC es sustituido por la dirección de salto.
if (cond) : PC ALU-salida
Camino de datos. Muestra, como ya sabemos de cursos anteriores, como funciona el procesador de
DLX cuando está ejecutando una instrucción por ciclo (es decir, es un repaso de materia ya vista en
primero, en EC I). Es un ejemplo de cómo se propagan los datos a través del procesador.
Por este y otros motivos similares, en los registros intermedios del procesador segmentado para
DLX, se almacena toda la información necesaria de la instrucción que se está ejecutando en ese
segmento, y cuando pasamos al segmento siguiente, esta información si se va a utilizar en algún
segmento posterior, se traslada también copiándose en los registros que hay entre segmentos.
En la figura 6.19 observamos la forma que ha de tener el procesador segmentado para que la
segmentación funciones correctamente.
Observar:
Propagación del valor del NPC.
Propagación del código del registro destino hasta último segmento.
Propagación de resultado de la ALU: ALUOutput.
Como se actualiza el valor del contador de programa, usando una puerta AND.
Líneas de entrada del Banco de Registros.
Líneas de entrada de Memoria de Datos.
Una ALU para datos y otra para direcciones de saltos.
Ahora todo junto. Se muestra tanto el camino de datos como el camino de control para la realización
segmentada de instrucciones de DLX. (figura 6.30). Esta transparencia debe ser analizada con
detalle.
Riesgos estructurales.
En una máquina segmentada deben de poderse solapar cualquier combinación de instrucciones. Si no
es así, se dice que la máquina posee riesgos estructurales. Una máquina sin riesgos estructurales
siempre tendrá un CPI más alto que si no los tuviera.
Para evitar estos riesgos en muchos casos tenemos que duplicar recursos. Por ejemplo, si
tenemos un único puerto de acceso a memoria, si una instrucción en un determinado segmento debe
acceder a memoria para leer o escribir, en ese segmento no se podrá leer ninguna instrucción, por lo
cual el inicio de una nueva instrucción se tendrá que retrasar un ciclo de reloj. En la figura siguiente
se ilustra este caso, aunque se ve mejor en la transparencia de la hoja siguiente (Fig. 3.6 y 3.7).
Ciclos de Reloj
Instrucción 1 2 3 4 5 6 7 8 9
Carga IF ID EX MEM WB
Instrucción i+1 IF ID EX MEM WB
Instrucción i+2 IF ID EX MEM WB
Instrucción i+3 detención IF ID EX MEM WB
Instrucción i+4 IF ID EX MEM
Sin embargo hay máquinas que se diseñan con riegos estructurales, el motivo es sencillo:
Para reducir el coste en la producción. Está claro que si un determinado riesgo estructural no se
presenta muy a menudo, puede que no valga la pena evitarlo, y simplemente introducimos un retardo
en el funcionamiento.
En este caso, el riesgo es tan notorio por el elevado número de veces que ocurre que vale la pena
realizar el procesador con dos puertos de acceso, uno para lectura de datos y otro para lectura de
instrucciones.
También hay que destacar que aparecen dos tipos de riesgos más:
El riesgo estructural que se introduce al acceder al banco de registros.
El riesgo estructural que se produce cuando tenemos instrucciones cuya ejecución dura más
de un ciclo de reloj.
El primero en los riesgos se soluciona realizando un banco de registros de forma que el acceso de
escritura y de lectura se realicen en un mismo ciclo de reloj, pero en flancos distintos. Además, es
mejor que primero sea la escritura y luego la lectura, pues evitaremos un posible riesgo por
dependencia de datos.
El segundo riesgo lo analizaremos con más detalle cuando introduzcamos las instrucciones
multiciclo. Pero ahora vamos a realizar un pequeño estudio, considerando lo que ocurriría si todas las
instrucciones tuviesen un ciclo de reloj en ejecución salvo las instrucciones de multiplicación y
división que tienen 2 ciclos.
Se pide analizar estas dos opciones y decidir cuál es la más conveniente.
Caso 2: Duplicamos unidad aritmética de Mult/Div. Tenemos una burbuja o ciclo de espera en la
ejecución de estas 4 instrucciones.
Caso 3: No duplicamos unidad aritmética pero Si planificamos Código. Seguimos teniendo una
burbuja o ciclo de espera en la ejecución de estas 4 instrucciones.
La instrucción SUB tiene como registro fuente R1, y la instrucción anterior ADD guarda el
resultado de una suma en este mismo registro. Si ejecutásemos de forma segmentada estas dos
instrucciones tendríamos:
Ciclos de Reloj
Instrucción 1 2 3 4 5 6
ADD IF ID EX MEM WB_en_R1
SUB IF ID_leo_R1 EX MEM WB
Ciclos de Reloj
Instrucción 1 2 3 4 5 6 7 8 9
ADD IF ID EX MEM WB_R1
nop - - - - -
nop - - - - -
SUB IF ID_R1 EX MEM WB
El problema planteado aquí se resuelve con una sencilla técnica llamada según autores de la
siguiente forma:
Con ello se consigue que si una instrucción utiliza un registro como fuente y la instrucción
anterior lo tiene como destino de una operación, entonces la segunda instrucción utilizará como valor
del registro fuente la salida de la ALU. Así, aunque el valor no se grabe en el registro conflictivo
hasta 2 ciclos después, la segunda instrucción ya habrá hecho uso de su valor.
Como hemos visto, en la segmentación de DLX, no solo la instrucción siguiente puede
necesitar un valor de un registro todavía no actualizado, también las tres siguientes instrucciones
pueden necesitar este valor, que hasta el final del cuarto segmento (el de WB) no estará
correctamente almacenado.
En la figura 3.10 anterior se muestra un ejemplo de cómo una instrucción utiliza como
registro destino R1 y las siguientes 4 instrucciones lo tienen como registro fuente. El resultado
deberá ser adelantado para las dos siguientes instrucciones. (Figura 6.7).
En la página siguiente se muestra como se realizarían los adelantamientos de datos para estas dos
secuencias de instrucciones:
Cada nivel de destino requiere de un cerrojo (biestable D activado por nivel) y un par de
comparadores para examinar si instrucciones adyacentes, comparten un destino y una fuente. En la
figura siguiente se muestra una ALU con esta estructura.
Fichero de
Registros
Mux Mux
Caminos de
desvio
ALU
Bus de escritura
de resultados
R4 Buffers de resultados
de la ALU
R1
Como puede observarse, se necesitan dos buffers para almacenar los resultados de la ALU.
Los resultados de la ALU pueden ser entradas de la propia ALU vía la utilización de dos
multiplexores, tal como aparece en la figura.
El control de estos multiplexores se puede realizar de dos formas:
Por la propia Unidad de control.
Por una lógica local asociada al desvío.
En cualquiera de los dos casos, se deberá examinar si alguna de las dos instrucciones
anteriores escribió en un registro utilizado como fuente en la instrucción actual. En cuyo caso el
multiplexor deberá seleccionar es registro de resultado (salida de ALU) apropiado en lugar del bus.
Como la ALU opera en una única etapa de la segmentación, no se requiere ningún retardo por
combinación de cualquier conjunto de instrucciones que operen sobre esta ALU de punto fijo.
También aparecería un riesgo cuando tuviésemos dos instrucciones que pretendieran leer y
escribir sobre una misma posición de memoria. En nuestro caso, para DLX este riego no existe pues
los accesos a memoria se mantienen siempre en orden; este riego no se puede dar.
Los fallos de acceso a cache podrían también desordenar las referencias a memoria si se
permitiera que el procesador siguiese trabajando con instrucciones posteriores. Pero en DLX, cuando
esto ocurre, detenemos la segmentación por completo, haciendo que la ejecución de la instrucción
que causo fallo se prolongue todos los ciclos de reloj que haga falta.
En ocasiones puede ser necesario adelantar el resultado de una unidad funcional a otra unidad
funcional. Por ejemplo, analicemos las siguientes instrucciones:
ADD R1, R2, R3
SW 25(R1), R1
El resultado de la suma almacenado en R1, cuando está a la salida de la ALU ya se puede
utilizar para el cálculo de la siguiente instrucción, y a su vez este valor será adelantado al MDR
(Registro de Datos de Memoria) para que sea almacenado en una dirección de memoria el contenido
del registro R1.
Clasificación:
Pero en cualquier procesador segmentado genérico, los riesgos por dependencia de datos se pueden
clasificar en tres tipos, atendiendo al orden de acceso de lectura y escritura de las instrucciones. Sean
dos instrucciones, primero i y luego j; entonces la clasificación podría ser esta:
RAW (Read After Write): una instrucción j intenta leer antes de que la instrucción i realice
la escritura. El resultado es que se lee un valor no correcto (ya hemos visto ejemplos antes).
WAR (Write After Read): una instrucción j escribe un valor antes de que la instrucción i lo
lea. Esto en DLX no ocurre, pues las lecturas se realizan antes en ID y las escrituras después
en WB. Ocurre cuando hay instrucciones que escriben anticipadamente el resultado, como
por ejemplo cuando se autoincrementa un registro en cálculo de una dirección.
WAW (Write After Write). Es cuando las dos instrucciones, tanto i como j, realizan una
escritura por ejemplo en un registro; pero la instrucción j lo realiza antes que la i por hacerlo
en segmentos anteriores. Ocurre en segmentaciones que escriben en más de una etapa.
Observar el detalle de cómo funciona la unidad de detección de riesgos: En el ciclo 3 de reloj se está
ejecutando la instrucción “SUB R2, R1, R3” que inicializa el registro R2. Cuando esta instrucción
pasa en el ciclo 4 al segmento MEM, entrará en EXE la instrucción “ADD R4, R2, R5” que
necesitará recibir de forma adelantada el contenido de R2, pues el valor leído en el banco de registros
no es el correcto.
Inevitables:
Pero no todos los riesgos son inevitables. Cuando leemos un dato de memoria y lo cargamos en un
registro, el registro no estará correctamente accesible hasta después del ciclo de acceso a memoria.
Analicemos por ejemplo la siguiente secuencia de código:
LW R1,32(R6)
ADD R4,R1,R7
SUB R5,R1,R8
AND R6,R1,R7
Ciclos de Reloj
Instrucción 1 2 3 4 5 6 7 8 9
LW R1,32(R6) IF ID EX MEM WB
ADD R4,R1,R7 IF ID EX MEM WB
SUB R5,R1,R8 IF ID EX MEM WB
AND R6,R1,R7 IF ID EX MEM WB
nop IF ID EX MEM WB
Pero podemos acortar el tiempo de detención si hacemos que la ALU lea directamente desde
el MDR. Es también un adelantamiento de los datos, con lo cual el multiplexor de entrada de la ALU
ya no tendrá 3 sino 4 entradas a seleccionar. Con ello ya solo será necesario, para este caso,
introducir un ciclo de espera, como muestra la figura siguiente.
Ciclos de Reloj
Instrucción 1 2 3 4 5 6 7 8 9 10
LW R1,32(R6) IF ID EX MEM WB
ADD R4,R1,R7 IF ID detención EX MEM WB
SUB R5,R1,R8 IF detención ID EX MEM WB
AND R6,R1,R7 detención IF ID EX MEM WB
nop IF ID EX MEM WB
Generalmente, cuando tenemos una instrucción del tipo A = B + C hay una probabilidad bastante
alta de que se produzca una detención debido a la carga del segundo dato. Sin embargo podemos
evitar con facilidad que se produzca un retraso en el almacenamiento del resultado, si adelantamos la
salida de la ALU al registro MDR.
Ciclos de Reloj
Instrucción 1 2 3 4 5 6 7 8 9
LW R1,B IF ID EX MEM WB
LW R2,C IF ID EX MEM WB
ADD R3,R1,R2 IF ID detención EX MEM WB
SW A,R3 IF detención ID EX MEM WB
El valor del MDR es adelantado para ADD. Para SUB y para AND ya se lee bien del banco
de registros en el segmento ID de ambas instrucciones.
Lo que hemos tenido que realizar es una espera en la segmentación que se conoce como
burbuja (“bubble”) o detención de cauce (“pipeline stall”)
El proceso que permite que una instrucción se desplace desde la etapa de decodificación de la
instrucción (ID) a la de ejecución (EX) se le llama
emisión de la instrucción (“instruction issue”)
y la instrucción sobre la que se ha realizado este proceso se dice que ha sido emitida (“issued”).
Para la segmentación de enteros sobre DLX (sin punto flotante) todos los riesgos por
dependencias de datos pueden ser comprobados durante la fase ID. Con ello se consigue reducir la
complejidad del hardware, pues nunca una detención de una instrucción interferirá en el estado de la
máquina, ya que los parámetros característicos de la misma solo pueden ser modificados en los
últimos 3 segmentos.
Para detectar estos riesgos inevitables, necesitamos añadir hardware de detección de riesgos en el
segmento ID de nuestro procesador:
De forma que se mirará si la instrucción que está en EXE tiene previsto escribir en memoria, a
continuación si va a escribir en memoria se analizará en registro destino de la instrucción para luego
compararlo con los dos registros fuente de la instrucción que se está decodificando en ID.
Si se cumple que hay coincidencia con alguno de los dos registros fuente, se introducirá una “nop”
en la ejecución segmentada, simulando una especie de “burbuja” como hemos visto antes.
Problema: Sea un procesador segmentado en el cual el 20% de las instrucciones son de carga.
Además, después de una instrucción de carga, en el 50% de los casos hay una instrucción que accede
al dato cargado. Ello determina que en la ejecución segmentada de las instrucciones será necesario
introducir un retardo de 1 ciclo de reloj.
Cuan más rápido (en este caso más lento) es el procesador real aquí presentado respecto a uno
ideal (sin retardos y con CPI = 1).
Solución: Para saber la rapidez deberemos hacer el cociente entre los CPI (Instrucciones Por Ciclo),
es decir:
Rapidez = CPIreal / CPIideal
El CPIideal es 1.
1) El 20% de las instrucciones son de carga y de ellas el 50% produce retardo, es decir, el 10% de las
instrucciones produce retardo.
2) En plena segmentación, si de cada 10 instrucciones tengo un retardo, entonces estas 10
instrucciones tardarán 11 ciclos de reloj.
CPIreal = 11/10=1,1
Problema: Realizar un programa que realice la multiplicación de dos vectores de n datos y almacene
el resultado sobre un tercer vector de datos. Completar el código.
; VECTORES.S
;Datos a partir de esta dirección
.data 0x2000
n: .word 8, 0
datosX: .double 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, …
datosY: .double 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, …
datosZ: .space 64
.text 0x100
...
Solución:
; VECTORES.S : Z(i) = X(i) * Y(i).
.text 0x100
addi R1, R0, 0
lw R8, n
Esta inclusión no influía en el tiempo de ejecución del programa, pero si en la longitud del
código generado.
De todas formas, tanto si el hardware detecta el interbloqueo y detiene la segmentación como
si no, el rendimiento mejora si el compilador planifica la ejecución de las instrucciones.
Comentarios: . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .
. . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .
. . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .
. . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .
. . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .
. . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . . . . .. . . . . . .. . . . . . .