epelpad

El post que buscas se encuentra eliminado, pero este también te puede interesar

Arquitectura y organizacion de computadoras 2


<<< Post anterior


Todo esto esta colgado también acá

Algoritmos de sustitución:

Ya vimos los métodos para saber que bloques están en cache, ahora tenemos que ver como decidir que bloques nos conviene que estén en la cache. Por ejemplo imaginemos que tenemos una correspondencia directa, en determinada linea X de la cache tenemos un bloque de memoria al que el procesador uso recientemente, ahora el procesador requiere otro bloque de memoria que le corresponde la linea X de la cache, a la lógica de la cache no le queda otra que sacar el bloque actual y poner el nuevo. Pero con las otras 2 correspondencias la lógica de la cache tiene varios lugares para poner ese bloque que el procesador requiere. En esta parte vamos a ver los algoritmos usados para decidir que linea sacar de la cache para alojar el nuevo bloque requerido.

Probablemente el mas efectivo el LRU (Last Resently Used) "utilizado menos recientemente". En este algoritmo se reemplaza el bloque que se ha mantenido mas tiempo en la cache sin haberse referenciado. Esto es fácil de implementar en la correspondencia asociativa por conjuntos de dos vías, solo necesitamos 1 bit extra por linea, cuando una linea es referenciada se pone ese bit extra de esa linea en 1, y el de la otra vía en 0. Cuando necesitamos guardar un nuevo bloque, es tan simple como elegir la linea que posea el bit extra en 0.

Otra posibilidad es el FIFO (FIrst In First Out) "primero en entrar, primero en salir" En este algoritmo se reemplaza el bloque que ha estado mas tiempo en la cache, esto es implementado fácilmente mediante una técnica cíclica "buffer circular".

Otra podría ser LFU (Last Frequently Used) "menos frecuentemente usado", en este caso se sustituye la linea que posee menos referencias hechas, para esto se tendría que implementar un contador.

Otra técnica no basada en el grado de utilización seria en elegir la linea aleatoriamente (al azar). Estudios realizados indican que las prestaciones de esta técnica son levemente inferiores a las descriptas anteriormente basadas en el grado de utilización.

Política de escritura:


Un problema que todavía no se ha mencionado es el tema de la validez de los datos un bloque de memoria principal respecto a la linea correspondiente en cache.

Imaginemos una linea de cache la cual a sido modificada por el procesador, ahora el procesador requiere un bloque de memoria el cual va a ser alojado en esa linea modificada de la cache. La lógica de la cache debe actualizar el bloque de memoria principal correspondiente a la linea modificada antes de alojar el nuevo bloque.

Bien con el problema ya descripto, vamos a explicar algunas técnicas de escrituras que difieren en su prestación y costo de implementación.

Existen 2 grandes problemas a resolver. Primero, mas de un dispositivo puede tener acceso a la memoria principal, por ejemplo imaginemos un modulo de E/S que accede para lectura a la memoria principal, si la dirección accedida esta en cache y fue modificada, el dato que se lleva el modulo de E/S va a ser erróneo. Ahora imaginemos que el modulo de E/S va a realizar una escritura, y la dirección en cuestión esta en cache y fue modificada, cual es el dato valido?, el de la cache o el del modulo de E/S?.

Una vez que una dirección se ha modificado en la cache, la dirección correspondiente de memoria deja de tener validez.

Otro problema mas complejo se da en sistemas con varios procesadores en que cada uno posee su propia cache. El hecho de modificar una dirección de la cache, no solo invalida la dirección correspondiente en la memoria principal, sino que también podría invalidad datos de las otras caches.

La técnica mas sencilla es la llamada "escritura inmediata", todas las escrituras se hacen tanto en cache como en memoria principal. Para los sistemas con varias unidades procesador-cache, estos pueden monitorizar el trafico hacia memoria y detectar modificaciones en direcciones que dichas caches contienen, para así mantener la coherencia de datos. La principal desventaja de esta técnica es que aumenta considerablemente el trafico a través del bus, hacia la memoria principal, lo cual podría producir un cuello de botella en el sistema.

Otra técnica es la llamada "post-escritura", el la cual se minimizan las escrituras en memoria. En esta técnica la cache dispone de un bit extra por linea de cache, en el momento de modificar un bloque, esta modificación solo se hace en la cache, además de modificar el bloque, se utiliza ese bit extra para marcar que el bloque ha sido modificado. Recién en el momento de sustituir el bloque de la cache, se chequea este bit extra para saber si se ha modificado el contenido, si se ha modificado, antes de reemplazar el bloque se actualiza la memoria principal.

Como una parte de los datos de memoria no son validos porque todavía no se han actualizado, los accesos de los módulos de E/S deben hacerse a través de la cache para chequear primero si están ahí, y entonces usar información valida. Esto hace que la circuitería tenga que ser mas compleja, y existe la posibilidad de que se genere un cuello de botella.

En sistemas con mas de una unidad procesador-cache, no solo alcanza con mantener la coherencia entre la cache modificada y la memoria principal, sino que además hay que mantener la coherencia entre la información de las cache, a un sistema que tiene en cuenta este punto se le dice que mantiene la coherencia de cache.Entre las técnicas usadas pala lograr esto se encuentran:

Vigilancia del bus con escritura inmediata:


Todas las caches monitorean las lineas de direcciones del bus, cuando una cache detecta que se ha modificado un bloque de memoria que ella posee, procede a invalidar su linea de cache.

Transparencia hardware:

Se utiliza hardware adicional, cada ves que una cache es modificada, este hardware se encarga de mantener la coherencia con la memoria principal y otras caches.

Memoria excluida de cache:


Con esta técnica solo una porción de la memoria principal es compartida por los procesadores, esta memoria no es transferible a la cache, por lo cual cada vez que se accede a la memoria compartida por parte de un procesador, quiere decir que antes se ha producido un fallo en la cache, porque es imposible que que la memoria compartida se encuentre en cache

Tamaño de linea:

Cuando el procesador requiere acceder a una palabra de la memoria principal, el sistema lleva a la cache no solo esa palabra sino también las palabras de su vecindad, lo que se llama bloque, para aprovechar el principio de localidad. Bien, ahora, cual sera la cantidad óptima de palabras que deba contener ese bloque?. Al ir aumentando la capacidad de palabras de la linea de cache va a ir aumentando la tasa de aciertos, por el hecho de tener mas palabras próximas a la referenciada, con posibilidad de ser usadas, pero al pasar un cierto numero de palabras, la proximidad se va haciendo mas lejana, y así empieza a reducirse la tasa de aciertos, en ese punto seria mas conveniente reemplazar la linea.

Dos factores entran en juego en este tema:
Primero es que cuanto mas grande sean los bloque menor sera el numero de estos que entren en la cache. Y el hecho de que halla menos bloques, produce que este permanezca menos tiempo en cache, por sera reemplazado por otro mas rápidamente, no pudiéndose aprovechar completamente el principio de localidad.
Segundo, es que cuando mas palabras tenga el bloque, mas lejana va ha ser la proximidad de las palabras extra con respecto a la requerida en consecuencia menos probable va a ser que sea requerida en corto plazo.

Es difícil establecer un numero de palabras óptimo, por haber muchas variables en juego, pero parecería que un tamaño entre 4 y 8 unidades direccionables seria próximo a lo óptimo.


Numero de caches:

Debido al aumento logrado en la integración de los circuitos, se ha logrado reducir considerablemente los tamaños de las caches, lo que permitió incorporarlas dentro del mismo procesador, reduciendo los tiempos de acceso hasta hacerlos casi nulos.

Luego se incorporo un segundo nivel de cache, mejorando aun mas los tiempos promedio de acceso a datos e instrucciones alojados en memoria principal.

Además de incorporar 2 niveles de cache, se ha hecho normal particionar la cache y dedicar una a almacenar datos y otra a almacenar instrucciones.

Las caches unificadas presentas 2 grandes ventajas, la primera es el tema del balanceo según las necesidades, por ejemplo supongamos el caso ficticio que el procesador requiera de memoria principal solo instrucciones, nada de datos, en el caso de cache partida, una dedicada a datos y otra a instrucciones, tendríamos la cache de datos casi sin uso, en cambio, si no estuviera particionada, el solo uso de la cache balancea según las necesidades la cantidad de instrucciones o datos cargados en la cache. La otra ventaja mas obvia es que solo habría que diseñar e implementar una sola cache.

Pese a esto la tendencia se fue incrementando para el lado de las caches partidas, esto se debe principalmente para explotar mas la técnica de ejecución de tareas en paralelo. En procesadores que se implementa segmentación de cause "Pipelining" , dentro del procesador se realizan en paralelo distintas tareas, y se pueden llegar a requerir en un mismo momento datos e instrucciones. Con la cache partida se elimina la competencia por el acceso a ella, por ejemplo el pre-captador de instrucciones podría tratar de acceder a la cache en busca de futuras instrucciones, y no podría hacerlo, porque la ALU en ese momento esta haciendo uso ella para obtener operandos.


Registros:

Primero recordemos las cosas que debe poder hacer la CPU:

* Captar instrucciones: La CPU lee una instrucción de memoria.
* Interpretar una instrucción: La instrucción debe ser decodificada, para saber que acciones se deben realizar.
* Procesar datos: La ejecución de una instrucción puede requerir que se realice alguna operación aritmética o lógica.
* Escribir datos: La instrucción puede requiere que se escriban datos en memoria o en algún modulo de E/S.

Para realizar estas tareas, la CPU requiere de la capacidad de poder almacenar algunos datos temporales, para eso necesita de una pequeña memoria interna, la cual ya hemos nombrado, que son los registros.

Arquitectura y organizacion de computadoras 2

Estos registros están el lo mas alto de la jerarquía de memoria, por lo cual son a los que se accede mas rápidamente, las mas pequeñas, y las mas caras.
Se las dividen en 2 grupos:
Registros visibles al usuario: Permiten a los programadores de bajo nivel, hacer uso de ellas.
Registros de control y estado: Son usados por la unidad de control para controlar la CPU, y son también usados por programas privilegiados del sistema operativo, para controlar la ejecución de programas.

Registros visibles al usuario:

Estos registros pueden ser referenciados por medio de lenguaje de maquina, y podemos clasificarlos de la siguiente forma:

* De uso general.
* Datos.
* Direcciones.
* Código de condición.

Un registro de uso general se puede usar para cualquier cosa, este uso esta estrechamente ligado al repertorio de instrucciones. Por ejemplo hay instrucciones que permiten direccionar una posición de memoria usando cualquier registro, mientras hay otras instrucciones que trabajan con registros específicos. La ventaja de un registro de uso general, es la flexibilidad en el trabajo que le da al programador, la desventaja de un registro general y a su ves ventaja de un uso especifico (datos o direcciones) esta en que las instrucciones no debe especificar en que registro se encuentra el dato o dirección, el registro ya esta implícito con la instrucción, ya se sabe que para determinada instrucción, hay que usar determinado registro, lo que hace a la instrucción mas corta.
También existen instrucciones de direccionamiento que hacen uso de un registro determinado, pero ese registro además se le puede dar otro uso, seria de uso mas o menos general.

Un tema importante a tener en cuenta es la cantidad de registros de uso general, esta cantidad afectara a la longitud de las instrucciones, ya que mas registros requieren mas bits para poder identificarlos, por lo cual en las instrucciones necesitaran mas bits en el campo del operando.
También debemos tener en cuenta el tamaño del registro, Los de direcciones deben poder contener la dirección mas alta, los de datos deben poder contener los valores de los distintos tipos de datos. En algunos sistemas se permite el uso de dos registros como si fuera uno solo para aumentar su capacidad.
La ultima clasificación de los registros visibles al usuario son los que almacenan los códigos de condición o "Flags". Estos flags son bits, que utiliza el hardware de la CPU para indicar algún tipo de información adicional al resultado de la operación que acaba de realizar, por ejemplo, si realizo una operación aritmética, los flags nos van a indicar, si hubo carry, overflow, si fue positivo, negativo, nulo, la paridad, etc. Son de mucho uso para corroborar resultados. Muchas veces también se realizan operaciones y solo se miran los flas, por ejemplo en operaciones de salto o bucles, se toma la decisión de saltar o volver a ejecutar el bucle luego de hacer una comparación "=", en la ALU realizaríamos una resta de los 2 operandos y solo habría que chequear el flag que nos indica si el resultado fue cero. O por ejemplo si la comparación que hiciéramos fuera un "A<B" , en la ALU haríamos A-B y solo habría que chequear el flag que nos indica si el resultado fue negativa, en si el resultado no nos interesa.
Estos registros son visibles al programador o parcialmente visibles, pero no se pueden modificar. Hay ciertas instrucciones como las de llamada a subrutina, que hacen una copia de estos registros, luego durante la ejecución de la subrutina la CPU hace uso de estos registros, y cuando se retorna al programa que llamo a la subrutina, se vuelven a poner los mismos valores en estos registros para asi poder continuar con la ejecución tal cual como lo venia haciendo antes de la llamada a subrutina.
En otras máquinas, cuando se llama a la subrutina, el resguardo de los flags no se hace automáticamente por la CPU, en esos casos es responsabilidad del programador.

Registros de control y estado:

Estos registros se usan para controlar el funcionamiento de la CPU, en general no son visibles al usuario, y , algunas de ellas pueden ser visibles por instrucciones de máquina ejecutadas en modo de control o de sistema operativo.
Los mas importantes son:

* PC - Contador del programa (Program counter): Contiene la dirección de la próxima instrucción a captar.
* IR - Registro de instrucción (Instruction register) Contiene la ultima instrucción captada.
* MAR - Registro de dirección de memoria (Memory address register) Contiene la dirección de una posición de memoria.
* MBR - Registro intermedio de memoria (Memory buffer register) Contiene la palabra de datos a escribir, o la que se a leído ultima.

arquitectura

En este gráfico podemos apreciar un poco mas en detalle la estructura interna de la CPU, se pueden ver las conexiones internas, un bus interno, las conexiones de datos de los registros, y las conexiones de la unidad de control para indicarle al los registros, que operación queremos realizar (lectura o escritura) también se pueden ver los flags.



Procesador:



Ciclos de una instrucción:

Como ya hemos visto la función de un computador es la ejecución de un programa, el cual esta compuesto por un conjunto de instrucciones, y es el procesador el que se tiene que encargar de ejecutarlas. Dicha ejecución la voy a empezar a describir empezando por la forma mas simple, en 2 etapas, captación de la instrucción y ejecución de la instrucción, entonces la ejecución de un programa consta en la repetición del proceso de captación y ejecución de instrucciones.
Básicamente se capta la instrucción de memoria principal, se guarda el código de la instrucción en el registro IR,se incrementa el registro PC, la CPU interpreta la instrucción almacenada en IR y realiza las acciones necesarias para que se ejecute la acción requerida.

memoria

Como ya hemos visto anteriormente, en general las acciones que puede realizar la CPU se pueden agrupar en:

* Procesador-memoria:Transferencia de datos desde o hacia memoria.
* Procesador-E/S: Transferencia de datos desde o hacia el exterior a través de un modulo de E/S.
* Procesamiento de datos: Alguna operación aritmética o lógica con los datos.
* Control: Por ejemplo una instrucción de salto, que lo único que requiere es que se cambie el valor del registro PC.

Una instrucciones requieren una combinación de algunas.

Bueno, vamos a agregar algunas etapas

Computadoras

IAC - Instruction address calculation: En general consiste en sumar 1 al registro PC, pero no siempre. Supongamos que las instrucciones tienen un largo de 16 bits y la memoria esta direccionada de a 16 bits, en ese caso sumariamos 1 al PC, pero si la memoria estuviera direccionada de byte, cada instrucción ocuparía 2 posiciones de memoria, en ese caso tendríamos que sumar 2 al PC.
IF - Instruction fetch: La CPU lee la instrucción desde su posición en la memoria.
IOD - Instruccion operation decoding: Decodifica la instrucción para saber el tipo de operación a realizar y los operandos a utilizar.
OAC - Operand address calculation: Si el o los operandos se encuentran en memoria o se accede a ellos a través de E/S, se determina la dirección.
OF - Operand fetch: Se capta el operando de memoria o a través de E/S.
DO - Data operation: Se realiza la operación que requiere la instrucción.
OS - Operand store: Se almacena el operando en memoria o a través de E/S.

En el gráfico podes observar varias cosas, las etapas están dispuestas tal que en la parte de arriba están las etapas que requieren salir del procesador, y la la parte inferior están las etapas que se solucionan internamente.
Otra cosa para destacar son las flechas dobles en el momento de ir a buscar un operando o al almacenarlo, esto se debe porque hay instrucciones que requieren varios operandos y hay otras que generan mas de un resultado.
Por ultimo hay instrucciones que realizan una misma operación con distintos valores de un vector, por eso, al terminar de almacenar el resultado no captan la siguiente instrucción, en vez de eso, captan el próximo valor del vector realiza lo mismo con otros valores.


Interrupciones:

Para seguir con el ciclo de la instrucción voy a dar una idea de lo que es una interrupción, mas adelante la veremos con mas profundidad.
Una interrupción es un mecanismo, con el cual un modulo de E/S puede interrumpir el procesamiento normal de la CPU.
Esto sirve para mejorar el rendimiento del sistema. Este mecanismo puede llegar deshabilitarse si es necesario.

Ejemplo, ya sabemos que la mayoría de los dispositivos externos son las lentos que la CPU, imaginemos la CPU imprimiendo un documento

Procesador a 200 MHz (tiempo ciclo reloj = 5 ns; Ciclos por instrucción CPI = 2 , en promedio)
• Una instrucción tarda en promedio 2 x 5 ns = 10 ns =>lla computadora puede ejecutar ~100 Mips
Queremos imprimir un archivo de 10 Kbytes en una impresora láser de 20 páginas por minuto
• 1 página ≅ 3.000 caracteres (1 carácter = 1 byte)
• La impresora imprime 60.000 caracteres por minuto = 1 Kbyte/s

Hasta hora lo único que podíamos hacer era que la CPU envíe los datos que pudiera recibir la impresora y esperar que termine de imprimir o que solicite mas datos.

Sin interrupciones:

• La CPU entra en un bucle y envía un nuevo byte cada vez que la impresora está preparada para recibirlo.
• La impresora tarda 10 seg en imprimir 10 Kbytes
• La CPU está ocupada con la operación de E/S durante 10 seg.
(en ese tiempo la CPU podría haber ejecutado 1000 millones de instrucciones)

Con el uso de interrupciones la CPU no tiene que esperar, mandaría los datos a la impresora y seguiría haciendo alguna tarea productiva.

Con interrupciones:

La impresora genera una interrupción cada vez que está preparada para recibir un nuevo byte.
• Si la gestión de interrupción (ATI) tiene 10 instrucciones (salvar contexto, comprobar estado, transferir byte, restaurar contexto, rti)
• Para transferir 10 Kbytes tenemos que ejecutar 10.000 veces la ATI
⇒ ejecutar 100.000 instrucciones para atender al periférico ⇒ la CPU tarda 0,001 seg.
• La CPU está ocupada con la operación de E/S durante 0,001 seg.
• La E/S por interrupciones reduce en 10.000 veces el tiempo que la CPU está ocupada gestionando la impresora.

Esta diferencia es tan marcada porque el periférico es realmente muy lento, con periféricos rápidos, solo con las interrupciones no alcanza para solucionar el problema.

cache

En este gráfico se muestra el tiempo que utiliza la CPU en el periférico, la linea punteada nos marca en que se estaría utilizando el CPU.
Cuando se atiende, un periférico el procesador ejecuta un programa que atiende al modulo de entrada salida, este programa se carga, prepara lo necesario para que se pueda realizar la operación requerida con el periférico, seguido a esto se ejecuta la instrucción solicitada, cuando termina el periférico su tarea, en algunos casos el programa cargado puede realizar alguna otra tarea relacionada, para el lado del periférico o para el lado de los buses, por ejemplo mandar información de algún error que se halla detectado en el periférico, para luego proseguir con la ejecución del programa original.
Se puede ver, en la primera sección, que mientras esta funcionando el periférico (entre los círculos 4 y 5) el CPU no hace nada, solo espera que termine, en cambio se puede apreciar en la segunda seccione del gráfico, que luego de que el programa que atiende la E/S pone en funcionamiento el periférico, el procesador dedica su tiempo en procesar el programa original hasta que reciba una nueva interrupción, las 2 cruces identifican las interrupciones.
Bien, que sucedería si ocurre una interrupción mientras se esta ejecutando una interrupción?
Hay 2 alternativas, la primera es que mientras se esta atendiendo una interrupción se desactivan las demás, luego que se termina de atender la interrupción el procesador, antes de proseguir con la ejecución del programa principal, chequea si hay alguna interrupción pendiente, y así las va ejecutando secuencialmente.
La desventaja es que no se tiene en cuenta ninguna prioridad, y es necesario porque hay peticiones que en la que es importante atenderlas rápidamente y hay otras que no.
La otra alternativa es que las interrupciones tengan prioridad, entonces, si una interrupción es interrumpida por otra que posee mayor prioridad, se almacena el contexto de ejecución de la interrupción en curso, se carga el PC con la nueva dirección y se empieza a ejecutar las instrucciones del programa que atiende la nueva interrupción, al terminar se continua atendiendo la interrupción anterior, y cuando se termina de atender esta, se vuelve a la ejecución del programa principal.

organizacion

En la primera parte del gráfico se muestra como seria una atención secuencial de interrupciones, y en la segunda parte muestra el procesamiento de interrupciones anidadas, una dentro de otra, obviamente la interrupción "Y" es de mayor prioridad que la "X", en caso contrario, el gráfico hubiese sido similar al de la primera parte.

Sabiendo un poco de las interrupciones ahora podemos agregar una nueva etapa al ciclo de la instrucción básico.

cpu

En este gráfico podemos ver que si las interrupciones están deshabilitadas, el ciclo es igual, pero si están habilitadas antes de captar la próxima instrucción, chequea si hay alguna interrupción pendiente, si lo hay, en la etapa "Check for Interrupt" el procesador guardara el contexto (registro que contiene los flags, registro PC, etc) cargara en el registro PC la dirección donde esta el programa que atiende la interrupción, y empezara a captar y ejecutar las instrucciones del programa de atención a la interrupción.

También vamos a agregar la etapa de detección de interrupciones el gráfico mas detallado:

procesador

A esto faltaría agregarle una etapa.

Las instrucciones pueden contener uno, varios o ningún operando, este operando puede pasado de distintas modos de direccionamiento, los mas comunes son:

* Direccionamiento inmediato: El valor del operando se encuentra incluido en la instrucción.
* Direccionamiento directo: En la instrucción se encuentra la dirección efectiva en donde se encuentra el operando o el registro donde se encuentra el operando.
* Direccionamiento indirecto a través de registro: En la instrucción se hace referencia implícitamente o explícitamente al registro en donde se encuentra la dirección efectiva del operando.
* Direccionamiento indirecto a través de memoria: En la instrucción se encuentra la dirección en donde se encuentra el operando, este operando contiene la dirección de donde se encuentra el valor a procesar.

y otros modos y subdivisiones de cada uno, que no vienen al caso explicar ahora como, con desplazamiento, usando la pila, estos direccionamientos varían según el procesador.

Sabiendo esto podemos ver que faltaría una etapa para acceder al valor del operando en los direccionamientos indirectos.

Registros

Flujo de datos:

Veamos un poco como se usan los buses en el ciclo de una instrucción:

buses

Ciclo de captación: En el momento de captar la próxima instrucción, s toma la dirección contenida en el PC y se coloca en el MAR, luego la unidad de control manda señal de lectura por el bus de control, y entonces la memoria coloca en el bus de datos la información requerida. A continuación el MBR copia la información que se encuentra en el bus de datos al cual esta conectado, y como paso final el dato contenido en MBR pasa a IR.

Arquitectura y organizacion de computadoras 2

Ciclo indirecto: Si el operando utiliza direccionamiento indirecto, entonces se toma los N bits mas a la derecha del registro MBR, los cuales corresponden a la dirección de referencia del operando, estos bits se pasan al MAR, la unidad de control manda señal de lectura, la memoria pone los datos solicitados en el bus de datos, la MBR capta la información del bus de datos




El ciclo de ejecución no tan fácil y predecible como los dos anteriores, todo depende de la instrucción que el ciclo de captación halla dejado en IR, son muchas las posibilidades de flujos posibles.
En cambio, el ciclo de interrupción es predecible como los 2 primeros.

arquitectura

Ciclo de interrupción: Antes de atender a la subrutina que atenderá la interrupción, el contexto del CPU debe guardarse (flags y PC), para eso la unidad de control coloca en MAR la dirección en donde hace el resguardo de esos datos, podría ser la pila, luego de esto se coloca el dato a guardar en MBR, la unidad de control envía señal de escritura, la memoria detecta la señal y copia en la dirección que se encuentra en el bus de direcciones el dato que se encuentra en el bus de datos, dependiendo del tamaño del dato a guardar puede que este proceso ser repita mas de una vez. Luego de eso, se coloca en el PC la dirección donde comienza la subrutina de atención a la interrupción, gracias a lo que se realizo, en el próximo ciclo se empezara a captar instrucciones de la rutina de atención a la interrupción.



Segmentación de cauce:


Las técnicas de organización se fueron implementando a medida que la tecnología fue avanzando y permitieron ponerlas en practica.
La de segmentación de instrucciones es una técnica muy usada hoy en día.
Que es la segmentación de instrucciones?. Para explicarlo recordemos primero el ciclo de la instrucción, abarca varias etapas, en las cuales se realizan distintas tareas, bien, como son distintas, las realizan generalmente distintas partes del procesador, por ejemplo, la parte de ejecución la va a realizar la ALU, pero en la etapa de captación la ALU no interviene, este es el punto, mientras una parte del procesador esta trabajando, hay otras que no. La técnica de segmentación de cause intenta que trabajen las distintas partes del procesador en paralelo.
Por ejemplo cuando la etapa de ejecución recibe la instrucción, la etapa de captación se libera y podría empezar a captar la próxima instrucción.
Es muy gráfico y simple verlo haciendo una analogía con una linea de montaje de un producto en una fabrica, en la cual el producto va pasando por distintas etapas y en cada una se le hace algo al producto, no es necesario que el producto termine de pasar por todas las etapas para poder ingresar un nuevo producto a la linea de montaje.
Otro ejemplo podría ser un lavadero de ropa.

memoria

Lavado Secuencial

Computadoras

Lavado Segmentado
Gracias a la cátedra de arquitectura por las diapositivas que les tomo prestadas!!!

Los dibujitos vendrían a ser las tres etapas, lavado, secado y planchado.

El tema es hacer tareas en simultaneo en las cuales no se superpongan unidades funcionales.
Cuanto mas se pueda sementar el ciclo de instrucción mas beneficioso seria.
No todas las instrucciones utilizan todas las etapas, por ejemplo un movimiento de datos no utilizaría la etapa de ejecución, ni tampoco las etapas consumen la misma cantidad de tiempo, pero para simplificar la implementación, todas las instrucciones pasan por todas las etapas y todas las etapas duran lo que tarda la etapa mas lenta.
Teóricamente el incremento de la productividad es proporcional al numero de etapas, digo teóricamente porque el uso de segmentación trae aparejado muchos contratiempos que le van a bajar un poco ese rendimiento teórico.
Otra cosa a tener en cuenta es que la instrucción va a tardar lo mismo en ejecutarse, la diferencia esta en que el procesador va a ser mas productivo.
Bien, ahora vamos a determinar las etapas de nuestro cause:

FI - Fetch instruction: Captar la siguiente instrucción.
DI - Decode instruction: Determinar la operación a realizar, y los campos de operando.
CO - Calculate operands: Se calcula la dirección efectiva de los operandos.
FO - Fetch operands: Se captan los operandos de memoria, los que están en registros no son necesarios captarlos
EI - Execute instruction: Realizar la operación indicada en la instrucción.
WO - Write operand: Almacenar el resultado en memoria.

cache

Esta seria una situación óptima sin ninguna complicación, 9 instrucciones de 6 etapas, que si se ejecutaran en forma secuencial consumirían 54 unidades de tiempo, pero gracias a esta segmentación se requieren solo 14 unidades de tiempo.



Bien, veamos problemas, uno de los dos mas importantes serian los saltos.
No siempre la ejecución del programa es secuencial, los saltos condicionales, los saltos incondicionales, las llamadas a subrutina son un gran problema para la segmentacion de cause.
Imaginemos que en el cauce del gráfico anterior la instrucción 1 es una instrucción de salto condicional, la dirección de salto no se va a saber hasta que la instrucción pase por la etapa EI, el procesador seguirá cargando las instrucciones de forma secuencial, para cuando la instrucción 1 sabe a donde debe saltar para seguir captando instrucciones, ya se cargaron 4 instrucciones al cauce las cuales deben descartarse.

organizacion

En este caso la instrucción de salto seria la instrucción 3, y se deben descartar las instrucciones 4, 5, 6 y 7. Se desperdiciaron 4 ciclos.
Si el salto no se hubiese realizado, el gráfico seria igual al anterior.

El segundo problema es la dependencia de datos. Imaginemos que la primer instrucción es una suma, A + B=C, y la segunda es otra suma C + D=E.
La segunda instrucción no va a poder captar el operando C hasta que la primera instrucción almacene el resultado C en memoria.

En el próximo gráfico para mostrar la dependencia de datos el cauce que se toma es de 5 etapas pero mostrar la dependencia sirve, es lo mismo.

cpu

El gráfico esta tomado de un simulador MIPS64 (RISC), abajo pongo que se hace en cada etapa, las instrucciones LD leen un dato de memoria y lo guardan en un registro (lee el dato en la posición A de memoria y lo guarda en el registro R1), las SD al reves, toman el dato del registro y lo almacenan en memoria.
Donde dice RAW es que hay dependencia de datos (read after write) lectura antes de escritura, quiere decir que se esta intentando leer un dato que todavía no se escribió.

procesador

En este gráfico podemos apreciar un poquito mas de detalle, se puede ver que hay buffers intermedios entre las etapas llamados registros de segmentacion, además de esto hay circuitería dedicada a minimizar las dos dificultades antes mencionadas.



Según lo visto hasta ahora parecería que cuanto mas etapas mejor va a ser el rendimiento, pero los diseñadores se dieron cuenta de que no era así, porque?.
Primero, al agregar mas etapas estamos agregando mas buffer intermedios, los cuales adicionan tiempo, además que entre cada etapa ya hay una demora debido a funciones de preparación y distribución.
Segundo, con cada etapa que se agrega la circuitería para controlar las dependencias y otras para optimizar el uso del cause y aumenta enormemente la complejidad, pudiendo llegar al punto que esta circuitería sea mas compleja que la etapas mismas.
Por esta razón se busca un rendimiento óptimo con una complejidad moderada.



Tratamiento de las instrucciones de salto condicional:

Los tratamientos mas utilizados son:

* Flujos múltiples.
* Precaptar el destino de salto.
* Buffer de bucles.
* Predicción de saltos.
* Salto retardado.

Flujos múltiples: Esta implementación duplica la parte inicial del cauce, y en la etapa de captación, cuando se detecta una instrucción de salto, se comienza a captar por los dos cauces, en uno se capta como si el salto no se fuera a realizar, y en el otro cauce se capta como si el salto se fuera a producir. Pase lo que pase, ya están precaptadas las instrucciones de las 2 opciones posibles.
Con esta alternativa tenemos 2 problemas, el primer problema es que los 2 causes compiten por el acceso a memoria y registros. El segundo problemas es el siguiente: supongamos que ingresa una instrucción de salto, a partir de ahí se empieza a captar por los dos causes simultáneamente, ahora que pasa si ingresa en ese momento otra instrucción de salto antes de que se resuelva la primera. Se necesitaría otro cause adicional.

Precaptar destino de salto: En esta implementación además de captar la instrucción siguiente a la del salto, se precapta y se guarda la la instrucción del destino del salto, hasta que se decida si se salta o no. Si se produce el salto, el destino ya habra sido precaptado.

Buffer de bucles:
El buffer de bucles es una memoria de pequeña y muy rápida, la cual es controlada por la etapa de captación, en ella se almacenan las N ultimas instrucciones captadas. Entonces en el momento que se detecta que se va a producir el salto, el hardware comprueba si la dirección de salto se encuentra en el buffer, si se encuentra, la capta del buffer rápidamente, en vez de ir a memoria a buscarla.
Este buffer tiene tres utilidades:

1. Con el uso de precaptación, el buffer se adelanta y almacena las próximas instrucciones secuencialmente delante de la ultima captada. Con esto se logra que la etapa de captación tome las instrucciones del buffer en vez de hacerlo de memoria, reduciendo conciderablemente los tiempos de acceso.
2. Si se produce un salto con una dirección de destino próxima a la dirección actual, esta dirección va a encontrarse en el buffer.
3. Esta especialmente pensado para el tratamiento de bucles, si el buffer es lo suficientemente grande, todo el bucle entrara en el buffer, por lo cual el procesador va a tener que ir a memoria a buscar las instrucciones solo la primera vez, para las siguientes iteraciones tomara los datos del buffer.

Predicción de saltos: Existen diversas técnicas para predecir los saltos, algunas son:

* Predecir que nunca salta.
* Predecir que siempre salta.
* Predecir según el código de operación.
* Conmutado saltar / no saltar.
* Tabla de historia de saltos.

Las dos primeras son las mas fáciles, en la primera se decide no saltar nunca y precaptar lo que sigue a continuación de la instrucción de salto, y si al final se salta se descarta lo precaptado. La segunda es al revés de la primera se decide saltar siempre. Estas 2 técnicas en general tienen una tasa de acierto aproximadamente del 50%.
En la técnica de predecir según el tipo de instrucción, el procesador decide si salta o no, dependiendo de la instrucción de salto, con esta técnica se logra una tasa de acierto mayor al 75%.
Estas primeras tres técnicas son estáticas, las dos ultimas son dinámicas, registran algun tipo de información histórica de cuales fueron las decisiones tomadas con anterioridad. Por ejemplo si para almacenar el historial se dispone de un solo bit, solo podremos almacenar la ultima decisión tomada en el salto (se salto / no se salto)

Salto retardado: Usando esta técnica, la instrucción que le sigue secuencialmente a la instrucción de salto se ejecuta siempre, se salte o no se salte, dependiendo del procesador puede ser mas de una instrucción.
Queda poco legible el código utilizando esta técnica, porque después de la instrucción de salto va a ir una instrucción que normalmente estaría antes de la instrucción de salto. La ventaja es que la instrucción que se va a captar es útil, se salte o no se salte, no se va a descartar nunca.

14 comentarios - Arquitectura y organizacion de computadoras 2

araldir
Mas que interesante, cuando tenga un tiempo lo leo.
apulink
hermano se ve muy interesante, lo felicito porq puntos todavia no le puedo dar; me preguntaba si no sabes donde puedo descargar el libro de stallig
knysoft
buenisimo aporte , cosas como estan deben repetirse aqui. gracias pana...
softjarc
Muy bueno Me lo imprimo y lo leo Gracias
lopezstudio
genial, me viene super bien para la facu. te agradezco!!!
xmren
apulink dijo:hermano se ve muy interesante, lo felicito porq puntos todavia no le puedo dar; me preguntaba si no sabes donde puedo descargar el libro de stallig

Pasate por mi post: http://www.taringa.net/posts/ebooks-tutoriales/3506406/Organizaci%C3%B3n-y-arquitectura-de-computadores-W_-STALLINGS.html
nrctkno
apulink #2 - Más de 1 año hermano se ve muy interesante, lo felicito porq puntos todavia no le puedo dar; me preguntaba si no sabes donde puedo descargar el libro de stallig


Lo subí hace una semana:
http://www.taringa.net/posts/ebooks-tutoriales/4576490/Organizaci%C3%B3n-y-arquitectura-de-computadoras---Stallings.html

...porque los que te ofrecieron hasta ahora o bien no están en castellano o no están completos...
Si te sirvió comentá en mi post.
ACXtreme
disculpa la ignorancia pero porke arkitectura? de las computadoras claro, es ke necesito saber arkitectura y me aparece esto, ojala me ayuden adioz
Shadow_R
Muchas gracias no entendia bien 2 conceptos sobre el tratamiento de saltos y los explicaste mucho mejor que en las transparecias jajaja tengo que dar el final asiq me salvaste xD toma 10
FrozoneH
Una pregunta, espero me puedas ayudar.
En la universidad estamos llevando en el curso de Organización y Arquitectura de Computadoras programación en assembler sin tener ningún concepto previo del ensamblador y eso que toda programación la hemos visto orientada a objetos con obviamente lenguajes de alto nivel...
Entonces, ¿es propio de este curso llevar este tipo de lenguaje? ¿es...normal? ¿No se supone que deberíamos estudiar mas sobre el ensamblador antes de meternos de fondo a programar pics?
Buen post, espero me puedas ayudar.
Genitus
que buen post!!! Felicitaciones!!
sabes de donde puedo estudiar tambien pipeline, coherencia de cache y discos raids???
si tienes algun post por ahi te agradeceria q me digas!!!
muchas gracias denuevo y excelente pos
filas15
Gracais me sir ve mucho hermano 10+