miércoles, 4 de agosto de 2010

Estructura de computadores

Arquitectura Von Neumann
Así se conoce la forma de estructuración utilizada en los ordenadores actuales; desde 1945 con UNIVAC, se utiliza la arquitectura diferenciadora entre hardware y software que él creó (Von Neumann es junto con Alan Turing padre de la informática moderna, y curiosamente el gran precursor de los virus informáticos en sus estudios sobre autómatas autorreproductores que John Conway continuó en 1970 con el juego "Life", antecesor a su vez de los algoritmos genéticos). Según esta arquitectura, una definición adecuada para un computador sería la siguiente:
Máquina programada de propósito general capaz de realizar una serie de operaciones básicas siguiendo un conjunto de instrucciones que le son proporcionadas a través de un programa encaminado a resolver un problema.
Los elementos básicos de un computador propuestos por Von Neumann y que se utilizan en la actualidad son los siguientes:
-Memoria: Su misión consiste en servir de almacenamiento de la información dentro del computador, sean programas o datos, y sin hacer distinción entre código y datos (no hay una memoria para datos y otra para código ejecutable, está unificada).
-Dispositivos de E/S (Entrada/Salida): Engloban todos aquellos periféricos como puedan ser ratones, monitores, teclados,… es decir, todo lo que proporcione datos al computador o a través de lo cual salgan de él.
-BUS de comunicaciones: Las operaciones de accesos a datos, de manejo de periféricos y otras, han de realizarse a través de un BUS (hilos de comunicación); su misión engloba por ejemplo la transferencia de datos entre memoria y procesador.
-CPU - Unidad Central de Proceso (Central Processing Unit): Es la encargada de controlar y ejecutar todas las funciones del computador. Es la que determina en qué condición se ejecuta el código y como han de mandarse los datos, generando además todas las señales de control que afectan al resto de las partes.
Memoria
Jerarquía de memoria
La memoria en un computador se organiza en varios niveles que se organizan en forma piramidal, en el pico aquello que es más rápido y también más escaso (registros) y en la base lo más lento pero al tiempo más abundante (discos):

Pirámide de memorias (según su velocidad y tamaño)
Los registros pertenecientes al microprocesador son los más rápidos (con un tiempo de acceso que suele estar entre 1 y 5 nanosegundos) aunque por su coste el tamaño es reducido (normalmente no más que 256 bytes). La memoria caché, más lenta, tarda entre 5 y 20 ns (tiempo de acceso) pero con un tamaño mayor que a pesar de todo pocas veces sobrepasa el megabyte. La memoria principal, lo que solemos conocer como RAM, tiene ya un tamaño bastante mayor - las configuraciones standard de PCs difícilmente bajan ya de los 128Mb - pero al tiempo un acceso más lento (entre 60 y 200 nanosegundos). Finalmente, con la memoria secundaria hacemos referencia normalmente al disco duro, que es utilizado por el ordenador como memoria virtual.
Entre los distintos niveles de la jerarquía, ha de haber una correspondencia en los datos. Un nivel superior, más pequeño que el inferior, contendrá información proveniente de este nivel más grande que él, información a la que quiere acceder más deprisa. Por ejemplo, cuando accedemos a una base de datos, esta se carga en memoria para que podamos accederla a más velocidad; sin embargo, si modificamos valores de estos datos en memoria, tendremos que hacer una actualización desde la memoria al disco duro para que los cambios sean permanentes; así pues, siempre que modifiquemos algo en un nivel de la jerarquía, tarde o temprano habrá que transferir estos cambios a los niveles inferiores hasta llegar a la base de la pirámide.
Del mismo modo sucede en la relación entre memorias caché y principal; en la memoria caché se van a cargar partes de la memoria principal que se supone van a ser más utilizadas que otras, con lo cual cuando se produzca una modificación de lo que contiene la caché, habrá que actualizar de alguna manera la memoria principal.
Podríamos decir lo mismo de la relación entre caché y registros del micro, pero estos registros han de ser descritos más adelante en detalle pues su importancia va a ser capital para la programación en lenguaje ensamblador.
Es ya cosa de la implementación de cada procesador, decidir cuales son las políticas de extracción (decidir qué información se sube al nivel superior y cuando) y de reemplazo (decidir qué porción de la información de ese nivel superior ha de ser eliminada).
Memoria virtual
En un sistema dotado de memoria virtual, dos niveles de la jerarquía de memoria son tratados hasta cierto punto como si fueran uno sólo; esto es, las memorias principal y secundaria (memoria RAM y disco duro generalmente) se acceden mediante lo que denominamos direcciones virtuales (no olvidemos en cualquier caso que un programa ha de residir en memoria principal para ejecutarse, al igual que los datos para ser accedidos o modificados).
Para llevar a cabo esta labor, al ejecutarse un programa se asignará un espacio virtual a este, espacio que no va a compartir con ningún otro programa y gracias al cual tampoco va a ver a ningún otro programa más que al propio sistema operativo. Es decir, supongamos que tengo tres programas ejecutándose, P1, P2 y P3, y que nuestro sistema virtual maneja direcciones desde la 0x00000000 a la 0xFFFFFFFFh (en numeración hexadecimal). Cada uno de estos tres programas podrá ocupar la parte que quiera de esta memoria virtual, y aunque dos de ellos ocuparan la misma dirección virtual no se "pisarían" dado que son procesador y sistema operativo quienes mediante la MMU (Memory Management Unit) deciden a qué parte física de la memoria principal (o a qué zona de la memoria secundaria) corresponde la dirección virtual (ojo, el espacio virtual 0x00000000 a 0xFFFFFFFFFh es independiente en cada uno de los programas). Es por ello, que excepto por mecanismos que se implementen a través del sistema operativo, el código y datos de un programa no podrá ser accedido desde otro.
En cualquier caso, un programa no puede acceder a *todo* el espacio virtual, sino a la parte que le reserva el sistema operativo (volveremos a esto cuando hablemos sobre procesos en la parte dedicada a SSOO), ya que parte de él estará ocupado por código perteneciente al propio sistema operativo.
Por último, destacar que este espacio virtual se divide en páginas virtuales, cada una normalmente de 4Kb de tamaño; sobre estas se mantendrá una tabla de páginas, una estructura que contiene la información acerca de donde residen las páginas de un programa en ejecución. Si se intenta acceder en lectura o escritura sobre una página que está en la memoria principal no habrá problemas y la MMU traducirá la dirección virtual a la posición física en memoria. Sin embargo, si se intenta acceder a una página que resida en el disco duro, se generará un fallo de página y se cargarán esos 4Kb que estaban en el disco duro sobre la memoria principal, pudiendo, ahora sí, leer o escribir sobre la información contenida en ella.

En un modelo muy simplificado, 1 bit indica si la página pertenece al disco duro o a la memoria, y su dirección real (física)
La aplicación práctica la hemos visto todos en sistemas como Linux o Windows; se reserva un espacio de tamaño variable como "memoria virtual" (el término es en realidad incorrecto tal y como se utiliza en Windows, ya que la memoria virtual abarca la RAM que tenemos y lo que asignemos para disco duro), y esto nos va a permitir como gran ventaja cargar programas más grandes que la memoria que tenemos. Evidentemente, si arrancamos diez programas que ocupan 20Mb cada uno en memoria y nuestra memoria es tan sólo de 128Mb no vamos a poder tenerlos a la vez en memoria, con lo cual el sistema de memoria virtual se hace necesario. Lo mismo sucedería, si intentamos cargar un programa que necesita 140Mb de memoria.
Así pues, aquellos programas que estemos utilizando residirán en la memoria virtual, y aquellos que no, en el disco duro. Cuando utilicemos los otros, las partes menos utilizadas de la memoria principal pasarán al disco duro, y se cargarán desde él las que estemos utilizando.
Dispositivos de E/S
Existen de entrada (ratón, teclado, scanner), de salida (monitor), y que cumplen ambas cosas (discos duros, disketeras, módems). Los conocemos más como "periféricos", y en realidad cualquier cosa, desde un detector de movimiento a una cámara de video, pueden utilizarse como dispositivos de E/S.
La tarea más compleja respecto a estos dispositivos, es su control mediante el microprocesador; por ejemplo un módem conectado al puerto serie de un PC ha de ponerse de acuerdo con el procesador respecto a la forma de intercambiar sus datos o la velocidad con la que lo hace. Se necesita que haya una coordinación entre ambos para que uno lea a la misma velocidad a la que el otro escribe, y para interpretar adecuadamente los datos transmitidos. Además, el procesador debe de mantener una jerarquía dando prioridad antes a unos periféricos que a otros (atender una petición del disco duro puede resultarnos más importante que atender una del teclado).
Control de dispositivos de E/S
Existen tres modos básicos de realizar operaciones de E/S: programada, por interrupciones y por DMA (direct memory access):
*La E/S programada exige que el procesador esté pendiente de las operaciones realizadas por los periféricos; por ejemplo, en caso de controlar mediante este sistema un disco duro, la CPU tendría que ordenar la lectura de disco y estar pendiente mediante comprobaciones de si esta lectura ha sido realizada hasta que esto sea así; este es el método menos efectivo, puesto que mientras la CPU está haciendo estos chequeos para saber si la operación ha concluido no puede hacer otras cosas, lo cual reduce mucho su efectividad.
*Con un sistema de E/S por interrupciones, el procesador se "olvida" una vez mandada en nuestro ejemplo esa órden de lectura de disco, y sigue ejecutando las instrucciones del programa actual. Cuando esta operación haya terminado, y en general cuando un periférico tiene datos dispuestos para enviar o recibir, se generará lo que se conoce como "interrupción"; esto es, que la ejecución del programa por el procesador se detiene, y salta a una rutina de tratamiento de interrupción que hace lo que tenga que hacer con esos datos. Salta a la vista, que este sistema (utilizado con frecuencia) es mucho más efectivo que la E/S programada, puesto que libera al procesador de estar pendiente de la finalización de las operaciones de E/S.
*Finalmente, la E/S por DMA libera por completo al procesador no sólo de la tarea de control sobre estas operaciones como ya hacía el sistema por interrupciones, sino también del tener que preocuparse por la transferencia de los datos. Parte de la memoria virtual se "mapea" sobre el periférico; esto es, si por ejemplo tenemos una pantalla de 80x25 caracteres, en memoria se reservará una zona de 80x25 bytes tales que cada uno representará un carácter (que se halla en ese momento en la pantalla). Así pues, para escribir o leer lo que hay en pantalla en lugar de tener que estar el procesador enviando órdenes, se realizaría de forma transparente, de modo que leyendo de la memoria se leería directamente del monitor, y escribiendo en ella se modificaría lo que está escrito sobre él.
Buses de comunicación
Todas las operaciones mencionadas, han de realizarse a través de un BUS. Básicamente, tendremos tres tipos de buses:

-BUS de datos: Transfiere información, como su propio nombre indica. Por ejemplo, un bus de datos une el procesador con los discos duros o la memoria, para que estos puedan ser accedidos y su información transferida de un lugar a otro.
-BUS de control: Transporta las señales que se utilizan para configuración y control; pueden ser por ejemplo señales que decidan qué periférico ha de transmitir en un determinado momento, indicaciones para la memoria RAM de si debe de leer o escribir, etc.
-BUS de direcciones: Su utilidad se hace patente en operaciones como accesos a memoria; transportaría la indicación acerca del lugar de donde hay que leer o escribir en la RAM, o en el acceso a un disco duro el lugar físico de este donde se quiere leer o escribir.
Estos buses se combinan constantemente para poder llevar a cabo satisfactoriamente las operaciones requeridas por el procesador central. En una lectura de memoria, la CPU mandaría señales para activar el proceso de lectura en la RAM, mientras que por el bus de direcciones viajaría aquella dirección de la que se quiere leer. Una vez llegados estos datos a la memoria, por el bus de datos viajaría hasta el procesador aquella información que se requirió en un principio.
CPU
Se trata del "gran cerebro" del computador, encargada del control de todo lo que sucede y de la ejecución del código. Se compone de tres partes principales; la ALU (Arithmethic-Logic Unit), la Unidad de Control y la Unidad de Registros.


Modelo sencillo de un procesador relacionado con memoria y dispositivos de E/S
La ALU (Unidad Aritmético-Lógica o Arithmethic-Logic Unit)
Su misión es la de realizar operaciones aritméticas. Dependen del diseño, aunque encontraremos como básicas suma y resta; puede que queramos disponer de otras más complejas como multiplicación y división (para ahorrar tiempo a la hora de hacer una suma reiterada en lugar de una multiplicación si no estuviera implementada, por ejemplo). Además, tendremos operaciones lógicas:
* AND: Un AND hecho a dos bits devuelve 1 sólo si los dos bits son 1 (por ejemplo, 011 AND 101 dará como resultado 001). Equivale al "Y" lógico (es decir, al resultado en lógica de algo como "se da X y se da Y", frase que sólo sería verdadera en caso de darse X e Y).
* OR: Un OR hecho a dos bits devuelve 1 si al menos uno de los dos bits implicado en la operación es 1 (un 011 OR 101 da como resultado 111). Equivale al "O" lógico (el resultado de algo como "se dan X, Y o ambos", sentencia cierta en caso de darse X, Y o ambos).
* XOR: Un XOR, (eXclusive OR, O exclusivo) da 1 operando sobre dos bits si uno de los dos bits es 1 y el otro 0 ( la operación 011 XOR 101 resulta 110). Este "O exclusivo" en lógica es el que se daría en un "X está vivo o está muerto"; una de las dos condiciones ha de cumplirse para que esta sentencia sea cierta.
* NOT: Esta operación trabaja con un sólo bit; lo que hace es invertirlo (así, NOT 011 dará 100 como resultado).
Las operaciones con la ALU se pueden indicar mediante una señal de control con los bits suficientes como para diferenciar entre los tipos de operación existentes. Es decir, si tenemos 2 bits para la señal de control, las posibilidades de estos bits serán "00-01-10-11", lo cual da como resultado una ALU que pueda hacer cuatro funciones distintas. Con 3 bits, tendríamos "000-001-010-011-100-101-110-111", es decir, 8 operaciones posibles.
Además de esta señal de control, tendremos dos entradas de datos; esto es, los operandos de la función que se va a realizar. Así, si queremos hacer un AND entre dos números, meteremos cada uno de ellos por una entrada de datos y seleccionaremos el AND. Por supuesto, habrá al menos una salida conectada para el resultado de la operación:

No hay comentarios:

Publicar un comentario