Bienvenido Invitado
El registro es completamente gratuito y podrás acceder a todas las partes de la web
Puedes registrarte aquí
|
 |
Admins |
|
krixer |
|
|
IVAJ |
|
|
JimmyJazz |
|
 |
Conectados |
9 |
 |
Invitados: |
9 |
 |
Miembros Online |
0 |
| No hay miembros conectados |
|
|
 |
Foros M-E |
 |
|
Moderado por:
krixer, JimmyJazz
|
|
|
JimmyJazz
|
Enviado: 04.01.2008, 18:38
|
Admin
Karma: 9
Total: 8
Registrado: jun. 2007
Mensajes: 88
Estado: Desconectado Ultima visita: 06.08.08
|
Saludos!
Hoy pongo una pequeña sesión de teoria sobre optimización de procesadores, creo que os gustará! Saludos!!
INTRODUCCIÓN
Los procesadores al ejecutar cada instrucción deben realizar una serie de operaciones, que son:
Instruction Fetch (IF) -> El procesador recibe de memoria la instrucción a ejecutar.
Instruction Decode (ID) -> El procesador decodifica la instrucción para saber que es lo que debe hacer.
Operand Fetch (OF)-> El procesador le pide a memoria los datos necesarios para ejecutar la instrucción.
Execute (EX) -> El procesador ejecuta la instrucción.
Write Back (WB) -> En caso de que haya un resultado, el procesador lo escribe en memoria.
Los primeros procesadores ejecutaban las instrucciones de manera que hasta que no terminaba completamente la instrucción actual, no comenzaba a ejecutar la siguiente. Para cada paso de los anteriores el procesador necesitaba muchos ciclos de reloj, especialmente en los pasos en los que se accedía a memoria ya que la velocidad a la que la memoria puede transferir un dato es mucho más lenta que la del procesador por lo que este perdía tiempo esperando a que la memoria le proporcionara el dato solicitado...
Esta arquitectura se denominaba Von Newman y los ciclos necesarios para ejecutar cada instrucción se disparaban y esto no gustaba para nada a los diseñadores de procesadores así que se procedió a buscar una solución.
PIPELINE Y SUPERPIPELINE
El objetivo del pipeline es independizar cada uno de los pasos nombrados anteriormente de manera que parezca una cadena de montaje, cuando el circuito encargado de pedir una instrucción ha terminado(IF) y comienza la decodificación de ésta instrucción(ID), en vez de dejar ocioso el circuito que se encarga del IF, mientras se realiza ID empieza otro IF y así sucesivamente con el resto de etapas. El objetivo esto es que los ciclos por instrucción (CPI) se aproximen lo máximo posible a 1, es decir que a cada ciclo de reloj, finalize la ejecución de una instrucción.
Pero no todo es felicidad con el Pipeline, surgen varios problemas que se van solucionando y aquí están:
El primer problema que surge es el llamado cuello de botella. La etapa más lenta limita la frecuencia de trabajo, por muy rápido que decodifiquemos y ejecutemos instrucciones, si a la hora de pedir las instrucciones a ejecutar o los datos necesarios para la ejecución tardan mucho en llegar se nos irían acumulando instrucciones decodificadas por ejecutar o al revés, tendriamos el circuito de decodificación sin hacer nada durante mucho tiempo mientras el circuito del IF espera que le vayan llegando las instrucciones de memoria. La solución a este fue subdividir la etapa más lenta en varias.
Otro problema que surge es suministrar instrucciones y datos al procesador desde memoria a la velocidad que las necesita y para solucionar este problema surge la memoria caché de datos y de instrucciones, actualmente la caché de nivel 1 de todos los procesadores está separada para instrucciones y para datos, de manera que el circuito destinado a realizar el IF busca instrucciones en la caché de instrucciones y el circuito destinado a realizar el OF busca instrucciones en la caché de datos. Tened en cuenta que la caché que aparece en las especificaciones de un procesador en la tienda siempre es la de nivel 2 y en caso de tenerla la de nivel 3. La de nivel uno suele ser muy pequeña, entre los 56 y 512 KB y esta a su vez está dividida en dos, una mitad para instrucciones y la otra para datos.
Siguiente problema, imaginad que hay varias instrucciones i1, i2, i3, i4… y una de ellas es una suma, en cada ciclo accedemos a memoria para coger la instrucción, pero que creéis que utiliza el procesador para calcular la dirección de memoria a la que tiene que acceder para coger la instrucción? Efectivamente, ¡el sumador! ¡pero el sumador lo está utilizando a la vez la etapa de ejecución para hacer una suma! La solución a este problema es duplicar o triplicar los recursos (2 sumadores, 2 restadores, 2 multiplicadores, dos ALUs…), pero también es necesario duplicar los buses porque pensad que a la vez que entran instrucciones de memoria, a lo mejor entran datos o a lo mejor queremos escribir un resultado en memoria! Hoy en día el ejemplo que he puesto del sumador no es válido ya que los circuitos encargados de acceder a memoria poseen un sumador interno totalmente independiente del sumador de la ALU*, pero ya me habeis entendido :P.
*ALU: Arithmetic Logic Unit / Unidad aritmético lógica. Es un circuito integrado en los microprocesadores que es capaz de realizar todas las operaciones aritméticas básicas (suma, resta, multiplicación y división) y lógicas (OR, AND, NOT, XOR...) y otras extra como Shift Logical y Shift Arithmétical. La mayor parte de instrucciones que ejecuta el procesador utilizan la ALU y aquí teneis la explicación de que las matemáticas sean la base de la informática.
Un problema más que apareció fué que hasta el momento los procesadores se diseñaban pensando en realizar instrucciones muy complejas y venían con una gran variedad de ellas y estas instrucciones llamadas CISC (Complex Instruction Set Computer ) eran de ejecución muy lenta por lo que se creó el primer procesador RISC (Reduced Instruction Set Computer) que poseía una colección de instrucciones muy limitadas pero de ejecución muchisimo más rápida permitiendo subdividir en más etapas los accesos a memoria. Se puso de moda la fabricación de procesadores RISC y se dejaron de lado los CISC, pero no tardaron en darse cuenta de que por muy rápida que fuese la ejecución, si necesitaban 10 instrucciones para hacer lo que un CISC podía hacer con una, realmente no conseguían gran cosa en la mejora del rendimiento a parte de que los programas ocupaban mucha más memoria (Por la época 2 MB de RAM era hablar de un supercomputador de gama alta). Hoy en día los procesadores son una fusión entre RISC y CISC.
Si os fijais, al hacer todo esto de la cadena de montaje, si suponemos que tenemos un pipeline de 10 etapas, durante los 10 primeros ciclos el procesador no ha hecho nada aparentemente,digo aparentemente porque en realidad se está llenando el Pipeline, pero a partir del décimo ciclo de reloj en el cual terminará la ejecución de la primera instrucción después de pasar por todas las etapas del Pipeline (o no*) tras cada ciclo de reloj se terminará de ejecutar una instrucción y tenemos aproximadamente una instrucción por ciclo o un ciclo por instrucción (CPI) que es como se mide realmente.
Una mejora del Pipeline es el Superpipeline que simplemente consiste en fraccionar cada una de las etapas al máximo consiguiendo frecuencias de reloj de procesador mucho más elevadas y debido a esto la frecuencia del sistema y la del procesador se independizan ya que el procesador se vuelve mucho más rápido que el resto de elementos.
SUPERESCALARES
Este sistema consiste en aumentar las etapas de ejecución de manera que varias instrucciones se ejecutan simultáneamente. A medida que aumentaba el número de transistores en el procesador esto se iva haciendo factible, tenemos varias unidades de ejecución, las vamos ocupando y según vayan quedando libres ponemos a ejecutar otra instrucción, pero esto que parece tan sencillo para nosotros como es cambiar de cola cuando el cajero de al lado tiene menos gente para el procesador es muy complejo. Esto lo administra un chip llamado unidad de Dispatch, que es muy complejo y muy caro por lo que normalmente los procesadores tienen 3 unidades de ejecución como mucho, pero si cada unidad de ejecución tiene Pipeline estamos aumentando la eficiencia del procesador muchísimo. Observad; 3 unidades de ejecución con 10 etapas de pipeline, a partir del décimo ciclo tenemos 0,3 ciclos por instrucción!!
Esto generó a su vez un problema llamado Issuing o de dependencia de datos. Existen tres tipos de dependencia de datos: RAW, WAR y WAW.
RAW (Read After Write): Imaginad estas instrucciones
i1-> R2=R3+R1
i2-> R5= R2xR1
si os fijais, para realizar la segunda instrucción utilizamos de operando R2, pero R2 se calcula en la instrucción anterior. Si las dos instrucciones se ejecutan a la vez tendremos un problema y es que la instrucción 2 no podrá ejecutarse hasta que no termine totalmente la ejecución de i1.
WAR (Write After Read): ahora pongamos este ejemplo
i1 -> R1=R2+R3
i2 -> R3=R5xR7
aquí lo que puede pasar es que i1 se retrase en su ejecución por ejemplo por el problema de dependencias anterior y que i2 termine su ejecución antes.Que pasa: En i1 queremos calcular R2+ R3 pero si terminamos antes la instrucción 2 si os fijais modificamos el valor de R3 y a la hora de hacer R1=R2+R3, el valor que obtendremos en R1 será incorrecto. En este caso el procesador debería retrasar la ejecución de i2 hasta que i1 no terminase.
WAW(Write After Write): también explicaremos esto con un ejemplo
i1 -> R3=R1+R2
i2 -> R3=R5xR6
imaginad que por un problema de dependencia de datos RAW i1 se retrasa y i2 terminara antes. R3 primero valdría R5xR6 y luego al terminar i1 R3 valdría R1+R2 machacando el R5xR6. Y direis y que? Pues a ver, en un programa, si tu pones un determinado orden de ejecución es por algo y el valor correcto de un registro o de una posición de memoria es SIEMPRE el último modificado. Si en tu programa R3 quedaba modificado por ultima vez con R5xR6, pues a la hora de ejecutarse lo correcto es que en R3 al final quede R5xR6 y no R1+R2. Entendeis? Este tipo de dependencia es un poco xungo dexplicar, si alguien tiene alguna duda que lo ponga en el foro y lo intento explicar de nuevo.
Ahora explicaré las soluciones que se pusieron a estos problemas de dependencia de datos. Primero se intentaron buscar soluciones dinámicas, es decir, que durante la ejecución del programa el procesador se encargara de detectar las dependencias de datos y las solucionara. Esto era muy costoso y complicado de hacer además de consumir muchos recursos del sistema y a parte suponía que cada vez que se ejecutaba un programa con este tipo de problemas de dependencia el procesador tenía que volver a solucionarlos aunque no fuera la primera vez que ejecutara el programa, esto no gustó nada a los diseñadores y buscaron otra posible solución.
Esta solución fué estática, es decir se utilizaba durante el tiempo de compilación. El propio compilador se encargaaa de detectar posibles dependencias e introduce instrucciones NoP (No Operar) en el código para que el procesador no haga nada mientras termina la instrucción que debe terminar primero y también reordenaba las instrucciones, por eso programadores cuidado al debugar un programa si os lo encontrais un poco cambiado es que el compilador a solucionado alguna dependencia y tendreis alguna cosilla cambiada de orden o NoPs por en medio!
Actualmente se utilizan algoritmos de predicción, soluciones estáticas y soluciones dinámicas en combinación para solucionar estos problemas ya que si solo utilizaramos la solución del compilador, nuestros programas estarian llenos de No Operar y el procesador pasaría mucho tiempo ocioso por lo que se utilizan algoritmos de predicción para intentar adivinar si una instrucción fuera de salto y no perder tiempo ejecutando y el procesador mira de solucionar algunas dependencias para no estar mucho tiempo seguido sin hacer nada.
Anexo aquí: http://modding-espanol.com/module-pnForum-viewtopic-topic-73-start-0.html
PD. Podeis copiar el texto a otras webs si lo deseais, pero siempre, haciendo referencia al Autor y a la web de donde lo habeis sacado, en este caso, JimmyJazz y Modding-Espanol.com. Gracias

Ve lo que yo veo, siente como siento, salva como salvo, juzga como juzgo.
|
|
|
|
|
|
|
krixer
|
Enviado: 04.01.2008, 18:55
|
Admin
Karma: 7
Total: 8
Registrado: feb. 2007
Mensajes: 56
Estado: Desconectado Ultima visita: 24.09.08
|
Muy buen post JimmyJazz, PostIt!
|
|
|
|
|
|
|
CASSIUS
|
Enviado: 05.01.2008, 06:28
|
Modder
Karma: 2
Total: 5
Registrado: ene. 2008
Mensajes: 43
Estado: Desconectado Ultima visita: 24.02.08
|
HOLA
este es el tipo de informacion tecnica que cae muy bien.
exelente ojala no demore la continuacion.
CASSIUS
AMD PHENOM
¨un mundo nuevo no es mas que una nueva forma de pensar¨
|
|
|
|
|
|
|
JimmyJazz
|
Enviado: 07.01.2008, 00:19
|
Admin
Karma: 9
Total: 8
Registrado: jun. 2007
Mensajes: 88
Estado: Desconectado Ultima visita: 06.08.08
|
Apartado de Pipeline terminado, proximamente Superescalares.

Ve lo que yo veo, siente como siento, salva como salvo, juzga como juzgo.
|
|
|
|
|
|
|
Nuñez
|
Enviado: 07.01.2008, 04:13
|
Modder
Karma: 6
Total: 5
Registrado: dic. 2007
Mensajes: 43
Estado: Desconectado Ultima visita: 20.09.08
|
lo leere cuando tenga tiempo
|
|
|
|
|
|
|
JimmyJazz
|
Enviado: 07.01.2008, 23:17
|
Admin
Karma: 9
Total: 8
Registrado: jun. 2007
Mensajes: 88
Estado: Desconectado Ultima visita: 06.08.08
|
Superescalares terminado, proximamente procesadores VLIW

Ve lo que yo veo, siente como siento, salva como salvo, juzga como juzgo.
|
|
|
|
|
|
|
Eklipse
|
Enviado: 13.02.2008, 10:36
|
Modder
Karma: 8
Total: 4
Registrado: dic. 2007
Mensajes: 24
Estado: Desconectado Ultima visita: 28.04.08
|
Muy bueno el post!!!!
Un saludo
|
|
|
|
|
|
|
|
|
|
|
Temas: 99,
Mensajes: 403
Usuarios registrados | & | 0 invitado
Dadas para los 10 últimos minutos.
|
|
|
 |
|
 |
|
|