• No se han encontrado resultados

Eficiencia y performance

In document Conceptos de Sistemas Operativos (página 166-177)

Ahora que se ha discutido las opciones de asignación de bloques y administración del directorio, se verán sus efectos sobre la performance y eficiencia en el uso del disco. Los discos suelen ser el mayor problema en la performance del sistema ya que son lentos. En esta parte se verán algunas técnicas que mejoran la eficiencia y performance del almacenamiento secundario.

Eficiencia: el uso eficiente del espacio en disco es muy dependiente de los algoritmos de asignación del disco y directorio que se están usando. Por ejemplo, los inodes UNIX están preasignados en una partición. Aun un disco vació tiene un porcentaje de su espacio perdido para inodes. Sin embargo, preasignando los inodes y desparramarlos por la partición, se mejora la performance del sistema de archivo. Esta mejora es el resultado de los algoritmos de asignación y espacio libre de UNIX, el cual trata de mantener los bloques de datos cercanos al bloque inode del archivo para reducir el tiempo de búsqueda.

Como otro ejemplo, veamos nuevamente el esquema de clustering, el cual ayuda en la performance de la búsqueda del archivo y la transferencia del mismo, contra el costo de la fragmentación interna. Para reducir esta fragmentación, el BSD de UNIX varia el tamaño del cluster. Grandes clusters son usados cuando pueden ser llenados, y los pequeños clusters son usados para pequeños archivos y el último cluster de un archivo.

También se debe considerar los tipos de datos mantenidos en la entrada del directorio del archivo (inode). Comúnmente, el día de la última escritura se graba para proveer información al usuario y determinar si se le debe hacer al archivo una nueva copia de seguridad. Algunos sistemas también mantienen el día del último acceso. El resultado de mantener esta información es que cuando el archivo es abierto para lectura, se debe cambiar la entrada en el directorio para este archivo. Este cambio requiere que el bloque sea traído a memoria, cambiar la sección, y volver el bloque a disco (ya que las operaciones sobre discos ocurren solo en bloques o clusters). Esto puede provocar una ineficiencia cuando son muy frecuentes los accesos a archivos, por lo que se debe balancear su beneficio contra el costo de performance cuando se diseña el sistema de archivo.

Como ejemplo, consideremos como afecta a la eficiencia la elección del tamaño de los punteros usados para acceder a los datos. La mayoría de los sistemas usan o punteros de 16 bits o de 32 bits. Éstos tamaños de punteros limitan el largo del archivo a 216 (64K) o 232 bytes (4 Gb) respectivamente. Algunos sistemas implementan direcciones de 64 bits para incrementar este límite a 264 bytes, el cual es un número muy grande. Sin embargo, los punteros de 64 bits toman más espacio para almacenarse, por lo que hacen que los métodos de administración y asignación del espacio libre (listas enlazadas, catálogos, etc.) usen más espacio de disco.

Como otro ejemplo, consideremos la evolución del sistema operativo Solaris de Sun. Originalmente, muchas estructuras de datos eran de tamaño fijo. Estas estructuras incluían la tabla de procesos y la tabla de archivos abiertos. Cuando la tabla de procesos estaba llena, no se podían crear más procesos. Cuando la

tabla de archivos se llenaba, no se podían abrir más archivos. El sistema fracasaba al proveer servicio a los usuarios. El tamaño de estas tablas solo se podía incrementar si se recompilaba el kernel y reiniciando el sistema. Desde la liberación de Solaris 2, casi todas las estructuras del kernel son de asignación dinámica. Por supuesto, los algoritmos que manipulan éstas tablas son más complicados, y el sistema operativo es un poco más lento, ya que debe asignar y desasignar dinámicamente las entradas de las tablas.

Performance: Una vez que se seleccionan los métodos básicos de disco, existen aun varias formas de mejorar la performance. Como se vio, la mayoría de los controladores de disco incluyen memoria local para formar una cache en el controlador, el cual es suficientemente grande para almacenar pistas enteras a la vez. Una vez que la búsqueda se hizo, la pista es ubicada en la cache del disco comenzando en el sector que está debajo de la cabeza (aliviando el tiempo de latencia). Luego el controlador del disco transfiere cualquier sector pedido al sistema operativo, es decir, se transfiere desde el controlador a la memoria principal. Algunos sistemas mantienen una sección separada de la memoria principal destinada para cache de disco, donde los bloques son mantenidos bajo la suposición de que serán usados en poco tiempo. LRU es un algoritmo razonable para el reemplazo de bloques. Otros sistemas, (tal como la versión UNIX de Sun), tratan a toda la memoria física (es decir a la memoria principal) no usada como una pileta de buffers que esta compartida por el sistema de paginado y el sistema de caching de los bloques de disco. Un sistema que realiza muchas operaciones de I/O usara la mayor parte de su memoria como una cache de bloques, mientras que un sistema que ejecuta muchos programas usara la mayor parte de la memoria como espacio de paginado.

Algunos sistemas optimizan sus cache de disco (en memoria principal, es decir, la parte de la memoria destinada para los bloques) usando diferentes algoritmos de reemplazo, dependiendo del tipo de acceso al archivo. Un archivo que esta siendo leído o escrito secuencialmente no deberá tener un algoritmo de reemplazo LRU, ya que el bloque más recientemente usado será el último. En cambio, el acceso secuencial puede ser optimizado por las técnicas conocidas como free-behind y read-ahead. Free-behind elimina un bloque desde el buffer tan pronto como se pide el siguiente bloque. El bloque anterior es probable que no se use nuevamente por lo que gasta espacio de buffer. Con read-ahead, un bloque pedido y una subsecuencia de bloques son leídos y puestos en dicha cache de disco, ya que es probable que ésta subsecuencia se pida luego de usar el primer bloque. Recuperar todos éstos bloques de una sola transferencia ahorra gran cantidad de tiempo.

Otro método usado para mejorar la performance de la memoria principal es común en computadoras personales. Una sección de memoria es seteada aparte y tratada como un disco virtual, o un disco RAM. En este caso, el driver del dispositivo del disco RAM acepta todas las operaciones estándar de disco, pero realiza todas estas operaciones en la sección de memoria, en lugar de en el disco. Ante esto, se pueden ejecutar todas las operaciones de memoria sobre este disco RAM y, excepto por la gran velocidad, los usuarios no notaran una diferencia. Desafortunadamente, los discos RAM son útiles para almacenamiento temporario, ya que una falla de energía o un reinicio del sistema las borrara. Comúnmente, los archivo temporarios tales como los archivos intermedios de compiladores se almacenan ahí.

La diferencia entre un disco RAM y una cache de disco es que los contenidos del disco RAM son totalmente controlados por el usuario, mientras que la cache de disco esta totalmente controlada por el sistema operativo (ambas están en la memoria principal). Por ejemplo, una disco RAM estará vacío hasta que el usuario (o programas) creen archivos allí. La figura 11.9 muestra una posible ubicación de cache en un sistema.

Recuperación

Ya que tanto los archivos como los directorios son mantenidos en memoria principal y en disco, se debe tener seguridad de que fallos en el sistema no provocaran perdidas de datos o inconsistencia.

Chequeo de consistencia: Como se vio, parte de la información del directorio esta en memoria principal (cache) para aumentar la velocidad de acceso. La información del directorio en la memoria principal es generalmente información más actualizada de la que esta en disco, ya que las escrituras de la información del directorio en la cache al disco no necesariamente ocurre tan pronto como el cambio toma lugar.

Consideremos el posible efecto de una caída del sistema. En este caso, la tabla de archivos abiertos generalmente se pierde, y can ésta, todos los posibles cambios realizados a los directorios de archivos abiertos. Esto puede dejar al sistema de archivos en un estado inconsistente. El actual estado de los archivos no es el que esta descrito en la estructura de directorio. Frecuentemente, se corre un programa especial en el momento de reinicio para chequear alguna inconsistencia de disco.

El chequeo de consistencia compara el dato en la estructura de directorio con el dato en los bloques de disco, y trata de arreglar cualquier inconsistencia que encuentre. Los algoritmos de asignación y administración de memoria libre dictan que tipos de problemas se pueden encontrar y como se pueden arreglar con éxito éstos problemas. Por ejemplo, si se usa la asignación enlazada y hay un enlace desde un bloque al siguiente, entonces el archivo completo puede ser reconstruido a partir de los bloques de datos, y la estructura de directorio puede ser recreada. La perdida de un entrada de directorio completa en un sistema de asignación indexada podría ser desastrosa, ya que un bloque de dato no tiene conocimiento de otro. Por esta razón, UNIX almacena en cache (memoria principal) las entradas de directorio para lecturas, pero cualquier escritura de dato causara que el bloque inode sea escrito en disco antes de que aparezca en el correspondiente bloque de dato.

Backup y restauración: ya que los discos magnéticos a veces fallan, se debe tener mucho cuidado de no perder los datos para siempre. Con este fin, programas del sistema pueden ser usados para que realicen backups de datos desde el disco a otro dispositivo de almacenamiento, tal como discos blandos, discos magnéticos, o discos ópticos.

Para minimizar la necesidad de copiado, podemos usar la información de cada entrada de archivo del directorio. Por ejemplo, si el programa que realiza el back up conoce cuando se hizo la última copia, y el último día que fue modificado el archivo, puede darse cuenta de que el archivo no fue modificado, por lo que no necesita copiarlo nuevamente.

Controlador Ram de disco Tabla de archivos abiertos Bloque de buffer Buffer de pistas Disco Memoria principal CPU

IV. Sistemas de I/O

Los dispositivos que se vinculan con una computadora son muy variados. Los dispositivos transfieren un carácter o un bloque de caracteres a la vez. Se los puede acceder solo secuencial o aleatoriamente. Transfieren datos sincrónica o asincrónicamente. Pueden ser compartidos o no. Pueden ser solo de lectura o de escritura-lectura. Varían en gran manera su velocidad. En muchas formas ellos son los componentes más lentos de la computadora.

Por la variación de todos éstos dispositivos, el sistema operativo necesita proveer una forma de funcionalidad para aplicaciones, que les permita controlar todos los aspectos de los dispositivos. Un objetivo clave del subsistema de I/O del sistema operativo es el de proveer una interfaz lo más simple posible al resto del sistema. Ya que los dispositivos son “el cuello de botella” de la performance, otro aspecto clave es optimizar la I/O para maximizar la concurrencia.

12. Sistemas de I/O

Los dos trabajos más importantes de una computadora son la I/O y el procesamiento. En muchos casos, el trabajo más importante es el de I/O, el cual incide en el procesamiento.

El rol del sistema operativo en computar la I/O es el de administrar y controlar las operaciones de I/O y los dispositivos de I/O. Primero, en este capítulo se describirá el hardware básico de I/O. Luego, se discutirán los servicios de I/O que brinda el sistema operativo, y la incorporación de estos servicios en la aplicación de interfase de I/O.

Vistazo

El control de los dispositivos conectados a la computadora es uno de los temas más importantes en el momento de diseñar el sistema operativo. Ya que los dispositivos de I/O varían en cuanto a su función y velocidad (considere un mouse, un disco duro, un CD-ROM), se necesita una gran variedad de métodos para controlarlos. Estos métodos forman el subsistema de I/O del kernel, el cual separa el resto del kernel de la complejidad de administrar los dispositivos de I/O.

La tecnología de los dispositivos de I/O muestra dos conflictos. Por un lado, se ve que se está estandarizando las interfaces de software y hardware. Esta tendencia ayuda a incorporar una generación de mejores dispositivos en computadoras y sistemas operativos ya existentes. Por otro lado, se ve un gran incremento de la variedad de dispositivos de I/O. Los elementos de hardware básicos, tales como puertos, buses, y controladores de dispositivos, proveen de una gran variedad de dispositivos de I/O. Para encapsular los detalles y las rarezas de cada dispositivo, el kernel del sistema operativo está estructurado para usar módulos device driver. Los drivers de dispositivos presentan una interfase uniforme de acceso al dispositivo al subsistema de I/O, así como las llamadas al sistema proveen una interface estándar entre la aplicación y el sistema operativo.

En este capítulo, se verán los mecanismos de hardware básicos que realizan la I/O, y la forma en que el sistema operativo organiza los dispositivos de I/O en categorías para formar una aplicación general de interfase de I/O. Se verán también los mecanismos del kernel que sirven de puente entre el hardware de I/O y software de aplicación.

Hardware de I/O

Las computadoras operan con una gran variedad de tipos de dispositivos. Los tipos generales incluyen dispositivos de almacenamiento (discos, cintas), dispositivos de transmisión (tarjetas de red, módems), y dispositivos de interfase humana (pantalla, teclado, mouse). Otros dispositivos son más especializados. A pesar de la increíble variedad de dispositivos de I/O que pueden ser usados con una computadora, solo se necesitan pocos conceptos para entender como se vinculan, y como el software puede controlar el hardware.

Un dispositivo se comunica con el sistema de la computadora enviando señales sobre un cable o aun sobre el aire. El dispositivo se comunica con la maquina por medio de un punto de conexión llamado puerto (por ejemplo, un puerto serial). Si uno o más dispositivos usan un conjunto de cables en común, la conexión se llama bus. En términos más específicos, un bus es un conjunto de cables con un protocolo bien definido que especifica el conjunto de mensajes que pueden ser enviados por él. En términos electrónicos, el mensaje es un conjunto de voltajes eléctricos que se le aplican al cable. Cuando el dispositivo A tiene un cable que se conecta con el dispositivo B, y B tiene un cable que se conecta con el dispositivo C, y el dispositivo C tiene un puerto en la computadora, este arreglo es llamado daisy chain. Esto usualmente opera como un bus. Los buses son muy usados en la arquitectura de la computadora. En la figura 12.1 se ve una estructura de bus típica de una PC. En ella se ve un bus PCI (el bus común del sistema), que conecta el subsistema de memoria del procesador a los dispositivos rápidos, y un bus de expansión que conecta dispositivos más lentos tal como el teclado y puertos seriales y paralelos. En la parte de arriba a la derecha de la figura, hay cuatro discos conectados juntos sobre un bus SCSI que esta conectado a un controlador SCSI.

Un controlador es una colección de componentes electrónicos que pueden operar un puerto, un bus, o un

dispositivo. Un controlador de puerto serial es un ejemplo de controlador de dispositivo simple. Es un único chip en la computadora que controla las señales sobre los cables de un puerto serial. En contraposición, un controlador de bus SCSI no es simple. Ya que el protocolo de SCSI es complejo, el controlador de bus SCSI es implementado como un circuito separado (un adaptador de host: host adapter) que se enchufa a la computadora. Éste típicamente contiene un procesador, micro código, y alguna memoria privada que le permite procesar los mensajes de protocolos SCSI. Algunos dispositivos tienen construidos sus propios controladores. Si se mira un drive de disco, se verá que tiene de un lado un circuito unido, el cual es el controlador de disco.

Para que el procesador pueda darle comandos y datos al controlador para conseguir la transferencia de I/O, el controlador tiene uno o más registros para datos y señales de control. El procesador se comunica con el controlador por medio de la lectura y escritura de patrones de bits en éstos registros. Una forma de que ocurra esta comunicación es a través del uso de instrucciones especiales de I/O que especifican la transferencia de un bit o palabra a una dirección de puerto de I/O. La instrucción de I/O activa las líneas de bus para seleccionar el dispositivo apropiado y mover los bits dentro y fuera del registro del dispositivo. Alternativamente, el controlador del dispositivo puede soportar el mapeo de memoria de I/O. En este caso, los registros de control del dispositivo son mapeados en el espacio de direcciones del

Monitor Controlador grafico Procesador Conexión entre el controlador y la memoria. Cache Memoria Controlador de disco IDE. Disco Disco Disco Disco Disco Disco Disco Disco Bus de expansión de interfase teclado Puerto en paralelo Puerto serial Bus de expansión Bus PCI Controlador SCSI Bus SCSI

procesador. La CPU ejecuta los pedidos de I/O usando las instrucciones de transferencia de datos estándar para leer y escribir los registros de control del dispositivo.

Típicamente, un puerto de I/O consiste de cuatro registros llamados registros de estado, de control, entrada de datos y salida de datos. El registro de estado contiene bits que pueden ser leídos por el host. Estos bits indican los estados tales como si el comando actual se completo, si hay un byte listo en el registro de entrada de dato para ser leído, y si se ha producido un error en el dispositivo. El registro de control puede ser escrito por el host para comenzar un comando o para cambiar el modo de un dispositivo. Por ejemplo, un cierto bit en el registro de control de un puerto serial elige entre la comunicación totalmente duplex y la comunicación semi duplex, otro habilita el chequeo de paridad, un tercer bit setea el largo de una palabra a 7 u 8 bits, y otros bits seleccionan una de las velocidades soportadas por el puerto serial. El registro de entrada de dato es leído por el host para conseguir la entrada, y el registro de salida de datos es escrito por el host para sacar la información. Los registros de datos son típicamente desde 1 a 4 bytes. Algunos controladores tienen chips FIFO que pueden mantener varios bytes de entrada y salida para extender la capacidad del controlador más allá del tamaño de los registros de datos.

Polling: un completo protocolo para la interacción entre el host y un controlador puede ser confuso, pero la noción general es simple. Dicha noción se verá con un ejemplo. Asumamos que dos bits son usados para coordinar la relación productor-consumidor entre el controlador y el host. El controlador indica su estado a través del bit busy en el registro de estado (se recuerda que un bit seteado significa que esta en 1, mientras que un bit limpio esta en 0). El controlador setea el bit de busy cuando esta ocupado trabajando, y limpia el bit de busy cuando esta listo para aceptar el siguiente comando. El host señala su deseo por medio de un bit command-ready en el registro de comando. El host setea el bit command-ready cuando un

In document Conceptos de Sistemas Operativos (página 166-177)