2.1. Memoria Cache La memoria caché es una memoria auxiliar de acceso aleatorio de baja capacidad y muy rápida, que se añade entre la memoria principal y la UCP para mejorar el rendimiento de la estación de trabajo. En la memoria caché, el sistema guarda las posiciones de la memoria principal que más frecuentemente prevé que van a ser usadas, ganando mucha velocidad en el acceso a éstas. La memoria caché puede ser integrada, si está incluida en el propio procesador, o externa, si está fuera del procesador. Esta última es instalable por el usuario. La memoria caché en algunos sistemas se divide en caché de instrucciones y caché de datos. La arquitectura de la memoria caché puede ser mapeada directamente o responder a una arquitectura (caché secundario unificado, Harvard Architecture, etc.) que resuelve algunos de los inconvenientes que presenta la primera. En la arquitectura mapeada directamente cada dirección de la memoria principal se corresponde con una posición de la memoria caché. Pero cada posición de la caché puede aceptar datos de multitud de direcciones de la memoria principal, aunque no de más de una simultáneamente. Esta última circunstancia, la relación de varios a uno entre la memoria principal y la memoria caché puede ser causa de cuellos de botella en el acceso a datos. En informática, una caché, antememoria1 o memoria intermedia2 es un componente de hardware o software que guarda datos para que las solicitudes futuras de esos datos se puedan atender con mayor rapidez; Los datos almacenados en una caché pueden ser el resultado de un cálculo anterior o el duplicado de datos almacenados en otro lugar, generalmente, da velocidad de acceso más rápido. Se produce un acierto de caché cuando los datos solicitados se pueden encontrar en UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS esta, mientras que un fallo de caché ocurre cuando no están dichos datos. La lectura de la caché es más rápida que volver a calcular un resultado o leer desde un almacén de datos más lento; por lo tanto, cuantas más solicitudes se puedan atender desde la memoria caché, más rápido funcionará el sistema. Cuando hablamos de una caché de memoria nos referimos a la memoria de acceso rápido de una unidad central de procesamiento (CPU), que guarda temporalmente los datos recientes de los procesados (información).3 La memoria caché es un búfer especial de memoria que poseen las computadoras, que funciona de manera semejante a la memoria principal, pero es de menor tamaño y de acceso más rápido. Nace cuando las memorias ya no eran capaces de acompañar a la velocidad del procesador, por lo que se puede decir que es una memoria auxiliar, que posee una gran velocidad y eficiencia y es usada por el microprocesador para reducir el tiempo de acceso a datos ubicados en la memoria principal que se utilizan con más frecuencia. La caché es una memoria que se sitúa entre la unidad central de procesamiento (CPU) y la memoria de acceso aleatorio (RAM) para acelerar el intercambio de datos. Cuando se accede por primera vez a un dato, se hace una copia en la caché; los accesos siguientes se realizan a dicha copia, haciendo que sea menor el tiempo de acceso medio al dato. Cuando el microprocesador necesita leer o escribir en una ubicación en memoria principal, primero verifica si una copia de los datos está en la caché; si es así, el microprocesador de inmediato lee o escribe en la memoria caché, que es mucho más rápido que de la lectura o la escritura a la memoria principal.4 De forma similar, cuando hablamos de caché software hablamos de un espacio de memoria que contiene los datos calculados o copiados desde un espacio más lento. Un ejemplo habitual es hablar de la caché del navegador web, este espacio en disco contiene la información temporal descargada desde Internet o red interna, que por la naturaleza del sistema, siempre tendrá una velocidad más lenta que el disco físico de la máquina. Latencia Un recurso más grande incurre en una latencia (En redes informáticas de datos, la latencia de red es la suma de retardos temporales dentro de una red. Un retardo es producido por la demora en la propagación y transmisión de paquetes dentro de la red) significativa para el acceso, por ejemplo puede tomar cientos de ciclos de reloj para que un procesador moderno de 4 GHz llegue a tener disponible los datos de una DRAM. Esto se mitiga leyendo en grandes fragmentos y almacenando los datos temporalmente en una memoria más rápida o cercana al procesador, con la esperanza de que las lecturas posteriores sean más rápidas. La predicción o la obtención previa explícita (en inglés prefetching) también pueden adivinar de dónde vendrán las lecturas futuras y realizar las solicitudes con anticipación; si se hace correctamente, la latencia se reduce a ser casi despreciable. Ancho de banda El uso de una caché también permite un mayor rendimiento (en inglés se usa el término throughput) del recurso subyacente, mediante el empaquetado de múltiples transferencias de pequeñas en solicitudes más grandes y más eficientes. En el caso de DRAM, esto podría servirse por un bus más ancho. Imagínese un programa escaneando bytes en un espacio de direcciones de 32 bits, pero atendido por un bus de datos de 128 bits fuera de chip; los accesos de byte individuales sin caché solo permitirían usar 1/16 del ancho de banda total, y el 80% del movimiento de datos serían direcciones. Leer trozos más grandes reduce la fracción de ancho de banda requerida para transmitir información de dirección. La memoria caché puede ser de dos tipos: . UTELVT. 2018 Pág. 1 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Caché de lectura Cuando la UCP intenta realizar una operación de lectura sobre un dispositivo de memoria, principal o auxiliar (disco), antes comprueba si esa información existe ya en la memoria caché. En el caso de que así fuera, toma el dato de la memoria caché ahorrando tiempo de proceso y operaciones de entrada / salida. Si la información solicitada se encuentra en la memoria principal y no en la memoria caché, se recuperaría de la memoria principal y se escribiría también en la memoria caché para un posible uso posterior. Si la información no existiera en la memoria caché ni en la memoria principal, se recuperaría del disco a la memoria principal y se escribiría también en la memoria caché para un posible uso posterior. Si la memoria caché estuviera llena, escribiría también la información recuperada pero borraría la información que fue requerida hace más tiempo. El objetivo de la memoria caché en lectura es mejorar el rendimiento reduciendo el número de operaciones entrada / salida, para lo cual el sistema situará en el caché los datos más utilizados. Caché de escritura En este tipo de caché las operaciones de escritura no se apuntan directamente sobre memoria principal, sino que se escriben en memoria caché, con lo cual la operación de entrada / salida se da por finalizada y puede continuarse con el proceso de la siguiente instrucción. Posteriormente esta información se transfiere de forma asíncrona a memoria principal. El objetivo de la memoria caché en escritura es mejorar el rendimiento liberando lo antes posible las operaciones de escritura. Hay tres tipos de caché frecuentemente usados en computadoras personales: caché de disco, caché de pista y caché web. Caché de disco Es una porción de memoria RAM asociada a un disco, con el fin de almacenar datos recientemente leídos y agilizar su carga en el caso de que sean solicitados otra vez. Puede mejorar notablemente el rendimiento de las aplicaciones, dado que acceder a un byte de datos en RAM puede ser miles de veces más rápido que acceder a un byte del disco duro. Caché de pista Es una memoria de estado sólido tipo RAM cuyo uso generalmente se limita a las supercomputadoras por su costo tan elevado. Caché web Es la encargada de almacenar documentos web para reducir el ancho de banda consumido, la carga de los servidores y el retraso de las descargas. Existen 3 tipos de caché . UTELVT. 2018 Pág. 2 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS web: Privados que solo funcionan para un usuario, Compartidos sirven páginas a varios usuarios y Pasarela que funcionan a cargo del propio servidor original, de forma que los clientes no distinguen unos de otros. Composición interna Los datos en la memoria caché se alojan en distintos niveles según la frecuencia de uso que tengan. La información puede transferirse entre los distintos niveles de forma inclusiva o exclusiva: Caché Inclusivo: los datos solicitados se quedan en la memoria caché de procedencia, es decir, se mantiene una copia en dos o más niveles. Caché Exclusivo: los datos solicitados se eliminan de la memoria caché de procedencia una vez transferidos al nuevo nivel. Memoria caché nivel 1 (Caché L1) También llamada memoria interna3, se encuentra en el núcleo del microprocesador. Es utilizada para almacenar y acceder a datos e instrucciones importantes y de uso frecuente, agilizando los procesos al ser el nivel que ofrece un tiempo de respuesta menor. Se divide en dos subniveles: Nivel 1 Data Cache: se encarga de almacenar datos usados frecuentemente. Nivel 1 Instruction Cache: se encarga de almacenar instrucciones usadas frecuentemente. Memoria caché nivel 2 (Caché L2) Se encarga de almacenar datos de uso frecuente, es mayor que la caché L1, pero a costa de ser más lenta, aun así es más rápida que la memoria principal (RAM). Puede ser inclusiva y contener una copia del nivel 1 además de información extra, o exclusiva y que su contenido sea totalmente diferente de la cache L1, proporcionando así mayor capacidad total. Memoria caché nivel 3 (Caché L3) Es más rápida que la memoria principal (RAM), pero más lenta y mayor que L2, ayuda a que el sistema guarde gran cantidad de información agilizando las tareas del procesador. En esta memoria se agiliza el acceso a datos e instrucciones que no fueron localizadas en L1 o L2. Al igual que la L2, puede ser inclusiva y contener una copia de L2 además de información extra o, por el contrario, ser exclusiva y contener información totalmente diferente a la de los niveles anteriores, consiguiendo así una mayor capacidad total. Diseño En el diseño de la memoria caché se deben considerar varios factores que influyen directamente en el rendimiento de la memoria y por lo tanto en su objetivo de aumentar la velocidad de respuesta de la jerarquía de memoria. Estos factores son las políticas de ubicación, extracción, reemplazo y escritura. Política de ubicación Decide dónde debe colocarse un bloque de memoria principal que entra en la memoria caché. Las más utilizadas son: . UTELVT. 2018 Pág. 3 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Directa: al bloque i-ésimo de memoria principal le corresponde la posición i módulo n, donde n es el número de bloques de la memoria caché. Cada bloque de la memoria principal tiene su posición en la caché y siempre en el mismo sitio. Su inconveniente es que cada bloque tiene asignada una posición fija en la memoria caché y ante continuas referencias a palabras de dos bloques con la misma localización en caché, hay continuos fallos habiendo sitio libre en la caché. Asociativa: los bloques de la memoria principal se alojan en cualquier bloque de la memoria caché, comprobando solamente la etiqueta de todos y cada uno de los bloques para verificar acierto. Su principal inconveniente es la cantidad de comparaciones que realiza. Asociativa por conjuntos: cada bloque de la memoria principal tiene asignado un conjunto de la caché, pero se puede ubicar en cualquiera de los bloques que pertenecen a dicho conjunto. Ello permite mayor flexibilidad que la correspondencia directa y menor cantidad de comparaciones que la totalmente asociativa. Política de extracción La política de extracción determina cuándo y qué bloque de memoria principal hay que traer a memoria caché. Existen dos políticas muy extendidas: Por demanda: un bloque solo se trae a memoria caché cuando ha sido referenciado y no se encuentre en memoria caché. Con prebúsqueda: cuando se referencia el bloque i-ésimo de memoria principal, se trae además el bloque (i+1)-ésimo. Esta política se basa en la propiedad de localidad espacial de los programas. Política de reemplazo Determina qué bloque de memoria caché debe abandonarla cuando no existe espacio disponible para un bloque entrante. Básicamente hay cuatro políticas: Aleatoria: el bloque es reemplazado de forma aleatoria. FIFO: se usa el algoritmo First In First Out (FIFO) (primero en entrar primero en salir) para determinar qué bloque debe abandonar la caché. Este algoritmo generalmente es poco eficiente. Usado menos recientemente (LRU): sustituye el bloque que hace más tiempo que no se ha usado en la caché, traeremos a caché el bloque en cuestión y lo modificaremos ahí. Usado con menor frecuencia (LFU): sustituye el bloque que ha experimentado menos referencias. Véase también: Algoritmos de reemplazo de páginas Política de actualización o escritura Determinan el instante en que se actualiza la información en memoria principal cuando se hace una escritura en la memoria es ejecutada. Existen 2 casos diferentes: Sobre la memoria caché . Escritura Inmediata: Se escribe a la vez en memoria caché y memoria principal para mantener una coherencia en todo momento. Postescritura: El bloque donde se escribió queda marcado con un bit llamado bit de basura; cuando se reemplaza por la política de reemplazamiento se comprueba si el bit se UTELVT. 2018 Pág. 4 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS encuentra activado, si lo está, se escribe la información de dicho bloque en la memoria principal. Sobre la memoria principal Asignación en escritura: El bloque referenciado se copia de la memoria principal a la caché y después el bloque se envía a la CPU. No asignación en escritura: Envía el bloque directamente de la memoria principal a la CPU y al mismo tiempo la carga en la caché. Optimización Para una optimización en la manera en que se ingresa a la memoria caché y cómo se obtienen datos de ella, se han tomado en cuenta distintas técnicas que ayudarán a que haya menos reincidencia de fallos. Mejorar el rendimiento. Reducir fallos en la caché (miss rate). Reducir penalizaciones por fallo (miss penalty). Reducir el tiempo de acceso en caso de acierto (hit time). Reducción de fallos Tipos de fallos Existen 3 tipos de fallos en una memoria caché (se conocen como clasificación 3C): Forzosos (Compulsory o Cold): En el primer acceso a un bloque, este no se encuentra en la caché (fallos de arranque en frío o de primera referencia). Capacidad (Capacity): La caché no puede contener todos los bloques necesarios durante la ejecución de un programa. Conflicto (Conflict): Diferentes bloques deben ir necesariamente al mismo conjunto o línea cuando la estrategia es asociativa por conjuntos o de correspondencia directa (fallos de colisión). En un sistema multiprocesador, existen 2 tipos más de fallos (clasificación 5C5): Coherencia (Coherence): El bloque se encuentra en caché en estado inválido ante una lectura o sin permiso de escritura ante una escritura debido a la solicitud del bloque por otro procesador. Cobertura (Coverage): El bloque se encuentra en caché pero en estado inválido (sin permisos) debido a una invalidación emitida a causa de un reemplazo en el directorio, que causa la pérdida de la información de compartición. Técnicas para reducir fallos Existen diversas técnicas para reducir esos fallos en la caché, algunas son: Incrementar el tamaño del bloque. Ventajas: Se reducen los fallos forzosos como sugiere el principio de localidad espacial. Inconvenientes: Aumentan los fallos por conflicto al reducirse el número de bloques de la caché y los fallos de capacidad si la caché es pequeña. La penalización por fallo aumenta al incrementarse el tiempo de transferencia del bloque. Incremento de la asociatividad. Ventajas: Se reducen los fallos por conflicto. Inconveniente: Aumenta el tiempo de acceso medio al incrementarse el tiempo de acierto (multiplexión). También aumenta el coste debidos a los comparadores . UTELVT. 2018 Pág. 5 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Caché víctima. Consiste en añadir una pequeña caché totalmente asociativa (1-5 bloques) para almacenar bloques descartados por fallos de capacidad o conflicto. En caso de fallo, antes de acceder a la memoria principal se accede a esta caché. Si el bloque buscado se encuentra en ella, se intercambian los bloques de ambas cachés. Optimización del compilador. El compilador reordena el código de manera que por la forma en cómo se hacen los accesos, se reducen los fallos de caché. Reducción de tiempo de acceso Cachés pequeñas y simples. Las cachés pequeñas permiten tiempos de acierto reducidos pero tienen poca capacidad. En las cachés de correspondencia, la comprobación de la etiqueta y el acceso al dato, se hace al mismo tiempo. Evitar la traducción de direcciones. Evita la traducción durante la indexación de la caché (consiste en almacenar direcciones de la caché, evitando así la traducción de direcciones virtuales a físicas en caso de acierto) Escrituras en pipeline para aciertos en escritura rápidos. Consiste en crear un pipeline para las operaciones de escritura, de manera que la escritura actual se hace solapada en el tiempo con la comparación de etiquetas de la escritura siguiente6 2.2. Memoria Virtual. Memoria Virtual es el uso combinado de memoria RAM en la computadora y espacio temporero en el disco duro. Cuando la memoria RAM es baja, la memoria virtual mueve datos desde la memoria RAM a un espacio llamado archivo de paginación. El movimiento de datos desde y hacia los archivos de paginación crea espacio en la memoria RAM para completar su tarea. Si la computadora está falta de la memoria RAM necesaria para ejecutar una operación o programa, el sistema operativo Windows utiliza la memoria virtual para compensar. Mientras más memoria RAM su computadora tenga, más rápido ejecutarán los programas. Si la falta de memoria RAM hace su computadora más lenta, usted podría aumentar la memoria virtual para compensar. Sin embargo, su computadora puede leer datos en su memoria RAM más rápidamente que los datos en el disco duro, así que añadir memoria RAM es una mejor solución. En informática, la memoria virtual es una técnica de gestión de la memoria que se encarga de que el sistema operativo disponga, tanto para el software de usuario como para sí mismo, de mayor cantidad de memoria que esté disponible físicamente. La mayoría de los ordenadores tienen cuatro tipos de memoria: registros en la CPU, la memoria caché (tanto dentro como fuera del CPU), la memoria RAM y el disco duro. En ese orden, van de menor capacidad y mayor velocidad a mayor capacidad y menor velocidad. Muchas aplicaciones requieren acceso a más información (código y datos) que la que se puede mantener en memoria física. Esto es así sobre todo cuando el sistema operativo permite múltiples procesos y aplicaciones ejecutándose simultáneamente. Una solución al problema de necesitar mayor cantidad de memoria de la que se posee consiste en que las aplicaciones mantengan parte de su información en disco, moviéndola a la memoria principal cuando sea necesario. Hay varias formas de hacer esto. . UTELVT. 2018 Pág. 6 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Una opción es que la aplicación misma sea responsable de decidir qué información será guardada en cada sitio (segmentación), y de traerla y llevarla. La desventaja de esto, además de la dificultad en el diseño e implementación del programa, es que es muy probable que los intereses sobre la memoria de dos o varios programas generen conflictos entre sí: cada programador podría realizar su diseño teniendo en cuenta que es el único programa ejecutándose en el sistema. La alternativa es usar memoria virtual, donde la combinación entre hardware especial y el sistema operativo hace uso de la memoria principal y la secundaria para hacer parecer que el ordenador tiene mucha más memoria principal (RAM) que la que realmente posee. Este método es invisible a los procesos. La cantidad de memoria máxima que se puede hacer ver que hay tiene que ver con las características del procesador. Por ejemplo, en un sistema de 32 bits, el máximo es 232, lo que da 4096 Megabytes (4 Gigabytes). Todo esto hace el trabajo del programador de aplicaciones mucho más fácil, al poder ignorar completamente la necesidad de mover datos entre los distintos espacios de memoria. Aunque la memoria virtual podría estar implementada por el software del sistema operativo, en la práctica casi siempre se usa una combinación de hardware y software, dado el esfuerzo extra que implicaría para el procesador. Operación de la Memoria Virtual Cuando se usa memoria virtual, o cuando una dirección es leída o escrita por la CPU, una parte del hardware dentro de la computadora traduce las direcciones de memoria generadas por el software (direcciones virtuales) en: la dirección real de memoria (la dirección de memoria física). una indicación de que la dirección de memoria deseada no se encuentra en memoria principal (llamado excepción de memoria virtual) En el primer caso, la referencia a la memoria es completada, como si la memoria virtual no hubiera estado involucrada: el software accede donde debía y sigue ejecutando normalmente. . UTELVT. 2018 Pág. 7 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS En el segundo caso, el sistema operativo es invocado para manejar la situación y permitir que el programa siga ejecutando o aborte según sea el caso. La memoria virtual es una técnica para proporcionar la simulación de un espacio de memoria mucho mayor que la memoria física de una máquina. Esta "ilusión" permite que los programas se ejecuten sin tener en cuenta el tamaño exacto de la memoria física. La ilusión de la memoria virtual está soportada por el mecanismo de traducción de memoria, junto con una gran cantidad de almacenamiento rápido en disco duro. Así en cualquier momento el espacio de direcciones virtual hace un seguimiento de tal forma que una pequeña parte de él, está en memoria física y el resto almacenado en el disco, y puede ser referenciado fácilmente. Debido a que sólo la parte de memoria virtual que está almacenada en la memoria principal es accesible a la CPU, según un programa va ejecutándose, la proximidad de referencias a memoria cambia, necesitando que algunas partes de la memoria virtual se traigan a la memoria principal desde el disco, mientras que otras ya ejecutadas, se pueden volver a depositar en el disco (archivos de paginación). La memoria virtual ha llegado a ser un componente esencial de la mayoría de los sistemas operativos actuales. Y como en un instante dado, en la memoria sólo se tienen unos pocos fragmentos de un proceso dado, se pueden mantener más procesos en la memoria. Es más, se ahorra tiempo, porque los fragmentos que no se usan no se cargan ni se descargan de la memoria. Sin embargo, el sistema operativo debe saber cómo gestionar este esquema. La memoria virtual también simplifica la carga del programa para su ejecución, llamada reubicación, este procedimiento permite que el mismo programa se ejecute en cualquier posición de la memoria física. En un estado estable, prácticamente toda la memoria principal estará ocupada con fragmentos de procesos, por lo que el procesador y el S.O tendrán acceso directo a la mayor cantidad de procesos posibles, y cuando el S.O traiga a la memoria un fragmento, deberá expulsar otro. Si expulsa un fragmento justo antes de ser usado, tendrá que traer de nuevo el fragmento de manera casi inmediata. Demasiados intercambios de fragmentos conducen a lo que se conoce como hiperpaginación: donde el procesador consume más tiempo intercambiando fragmentos que ejecutando instrucciones de usuario. Para evitarlo el sistema operativo intenta adivinar, en función de la historia reciente, qué fragmentos se usarán con menor probabilidad en un futuro próximo (véase algoritmos de reemplazo de páginas). Los argumentos anteriores se basan en el principio de cercanía de referencias o principio de localidad que afirma que las referencias a los datos y el programa dentro de un proceso tienden a agruparse. Por lo tanto, es válida la suposición de que, durante cortos períodos de tiempo, se necesitarán sólo unos pocos fragmentos de un proceso. Una manera de confirmar el principio de cercanía es considerar el rendimiento de un proceso en un entorno de memoria virtual. El principio de cercanía sugiere que los esquemas de memoria virtual pueden funcionar. Para que la memoria virtual sea práctica y efectiva, se necesitan dos ingredientes. Primero, tiene que existir un soporte de hardware y, en segundo lugar, el S.O debe incluir un software para gestionar el movimiento de páginas o segmentos entre memoria secundaria y memoria principal. Justo después de obtener la dirección física, y antes de consultar el dato en memoria principal, se busca en memoria-cache. Si está entre los datos recientemente usados, la búsqueda tendrá éxito, pero si falla, la memoria virtual consultará la memoria principal ó, en el peor de los casos, el disco (swapping). Detalles La traducción de las direcciones virtuales a reales es implementada por una Unidad de Manejo de Memoria (MMU). El sistema operativo es el responsable de decidir qué partes de la memoria del programa es mantenida en memoria física. Además mantiene las tablas de traducción de . UTELVT. 2018 Pág. 8 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS direcciones (si se usa paginación la tabla se denomina tabla de paginación), que proveen las relaciones entre direcciones virtuales y físicas, para uso de la MMU. Finalmente, cuando una excepción de memoria virtual ocurre, el sistema operativo es responsable de ubicar un área de memoria física para guardar la información faltante, trayendo la información desde el disco, actualizando las tablas de traducción y finalmente continuando la ejecución del programa que dio la excepción de memoria virtual desde la instrucción que causó el fallo. En la mayoría de las computadoras, las tablas de traducción de direcciones de memoria se encuentran en memoria física. Esto implica que una referencia a una dirección virtual de memoria necesitará una o dos referencias para encontrar la entrada en la tabla de traducción, y una más para completar el acceso a esa dirección. Para acelerar el desempeño de este sistema, la mayoría de las Unidades Centrales de Proceso (CPU) incluyen una MMU en el mismo chip, y mantienen una tabla de las traducciones de direcciones virtuales a reales usadas recientemente, llamada Translation Lookaside Buffer (TLB). El uso de este buffer hace que no se requieran referencias de memoria adicionales, por lo que se ahorra tiempo al traducir. En algunos procesadores, esto es realizado enteramente por el hardware. En otros, se necesita de la asistencia del sistema operativo: se levanta una excepción, y en ella el sistema operativo reemplaza una de las entradas del TLB con una entrada de la tabla de traducción, y la instrucción que hizo la referencia original a memoria es reejecutada. El hardware que tiene soporte para memoria virtual, la mayoría de la veces también permite protección de memoria. La MMU puede tener la habilidad de variar su forma de operación de acuerdo al tipo de referencia a memoria (para leer, escribir, o ejecutar), así como el modo en que se encontraba el CPU en el momento de hacer la referencia a memoria. Esto permite al sistema operativo proteger su propio código y datos (como las tablas de traducción usadas para memoria virtual) de corromperse por una aplicación, y de proteger a las aplicaciones que podrían causar problemas entre sí. Paginación y memoria virtual La memoria virtual usualmente (pero no necesariamente) es implementada usando paginación. En paginación, los bits menos significativos de la dirección de memoria virtual son preservados y usados directamente como los bits de orden menos significativos de la dirección de memoria física. Los bits más significativos son usados como una clave en una o más tablas de traducción de direcciones (llamadas tablas de paginación), para encontrar la parte restante de la dirección física buscada. 2.3. Memoria Entrelazada. Para aumentar el ancho de banda de una memoria principal se puede descomponer en módulos con accesos independientes, de manera que se pueda acceder simultáneamente a una palabra de cada uno de los módulos. . UTELVT. 2018 Pág. 9 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Los procesadores de vector y de arquitectura paralela, con frecuencia requieren acceso simultáneo a la memoria desde 2 o más fuentes. En lugar de usar 2 canales de memoria para acceso simultáneo, puede dividirse la memoria en varios módulos conectados a canales de direcciones y datos comunes. Un módulo de memoria es un arreglo de memoria junto con sus propios registros de datos y direcciones. La siguiente figura muestra la unidad de memoria, con cuatro modulos. Cada arreglo de memoria tiene su propio registro de direcciones AR y registro de datos DR. Los registros de dirección reciben información de un canal de direcciones común y los registros de datos comunican con un canal de datos bidireccional. El sistema modular permite que un modulo empiece el acceso a memoria mientras que los otros módulos están en proceso de leer o escribir una palabra y cada modulo puede cumplir una solicitud de memoria independientemente del estado de otros modulos. . UTELVT. 2018 Pág. 10 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS 2.4. Detección y Corrección de Errores método Hamming Quién iba a decir que fuera un juego -como lo lees un juego- el algoritmo de Hamming, que lo que trata es de corregir errores, sea como un juego de deducción -como el juego del Cluedo o el Sudoku- donde nos dan una serie de pistas iniciales, y necesitamos descubrir quién es el malo o que número va en cada posición por descarte. Parece un sueño que si enviamos unos bits (una imagen, un audio, un texto, lo que sea) por Internet. Cuando llegue a su destino, y llegue mal (bits cambiados aleatoriamente; donde antes había un “1” ahora un “0”, y viceversa) por alguna causa -como una tormenta electromagnética por el camino entre el ordenador que lo envía y el que lo recibe- podamos corregir los errores que han ocurrido por el camino en el destino. Este algoritmo es, por así decirlo, un juego de detectives. Donde tenemos varias personas (los bits), y hay uno, varios o ningún malo (bits erróneos) entre ellas. A su vez tenemos varias pistas que van a hacer que descartemos a los buenos, hasta quedarnos con los malos; aunque ojo, también puede haber pistas que mientan. Realmente es bastante sencillo. . UTELVT. 2018 Pág. 11 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Es decir, hay unos bits que corrigen a otros. Estos bits que corrigen a otros se llaman “bits de redundancia”, pues son bits extra a la información para intentar corregir los errores o al menos comprobar que todo esté correcto. Un ejemplo en el mundo físico, sería como tener en un papel un texto cualquiera como “Mi mamá me mima”, y más abajo en el mismo papel la suma de todas las letras del texto “M=6, I=2, A=3, E=1” (es información repetida/redundante, pues ya está contenido en el dato). De este modo si se nos cae líquido encima de la tinta del texto haciendo ilegible algunas palabras del texto “Xi XaXá me Xima” (las “X” representan la ilegibilidad del texto); todavía podemos recuper ar el texto original con la suma de letras pues sabemos que hay 6 “Ms” y solo vemos legibles 2, por lo que se deduce que las letras ilegibles tienen que ser “Ms” también (lo mismo ocurriría si las equis “X” anteriores fueran letras y no borrones, la letra equis “X” no existe en las letras sumadas por lo que es una letra errónea). Al dato original más los “bits de redundancia” se les conoce como “Bloque del código” (en inglés “Block Code”). La “distancia mínima de Hamming” es muy interesante para corregir errores en bits (más información en el artículo de Hamming; te recomiendo que lo leas a continuación de éste artículo). Realmente sirve para corregir cualquier tipo de fichero (audio, imagen, etc) en informática, pues los bits son la base de cualquier fichero, y si los bits están correctos pues el fichero debería de estar correcto (debería, pues si, por ejemplo, con un ataque “man in the middle”, un tercero modifica el fichero por el camino del fichero durante el envío; este método corregirá los errores del fichero si llegan mal al destino entre el tercero y el destino, pero no detecta si el contenido ha sido modificado deliberadamente). Bit de paridad Un bit de paridad es un poco, con un valor de 0 o 1, que se agrega a un bloque de datos para fines de detección de errores. Le da a los datos un par o impar paridad, que se utiliza para validar la integridad de los datos. Los bits de paridad a menudo se usan en la transmisión de datos para garantizar que los datos no se corrompan durante el proceso de transferencia. Por ejemplo, cada bit de datos 7 puede incluir un bit de paridad (para un total de bits 8, o uno byte) Si la transmisión de datos protocolo se establece en una paridad impar, cada dato paquete debe tener una paridad impar. Si se establece en par, cada paquete debe tener una paridad par. Si se recibe un paquete con la paridad incorrecta, se generará un error y será necesario retransmitir los datos. El bit de paridad para cada paquete de datos se calcula antes de que se transmitan los datos. A continuación se muestran ejemplos de cómo se calcularía un bit de paridad utilizando configuraciones de paridad par e impar. Paridad impar: . Paridad par: Valor inicial: 1010101 (cuatro 1) Valor inicial: 1010101 (cuatro 1) Bit de paridad agregado: 1 Bit de paridad agregado: 0 Valor transmitido: 10101011 Valor transmitido: 10101010 Resultado: paridad impar (cinco 1) Resultado: paridad uniforme (cuatro 1) UTELVT. 2018 Pág. 12 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS El valor del bit de paridad depende de la paridad inicial de los datos. Por ejemplo, el binario El valor 10000000 tiene una paridad impar. Por lo tanto, se agregaría un 0 para mantener la paridad impar y se agregaría un 1 para dar al valor una paridad par. Si bien la verificación de paridad es una forma útil de validar los datos, no es un método infalible. Por ejemplo, los valores 1010 y 1001 tienen la misma paridad. Por lo tanto, si se transmite el valor 1010 y se recibe 1001, no se detectará ningún error. Esto significa que las comprobaciones de paridad no son 100% confiables al validar datos. Aún así, es poco probable que más de un bit sea incorrecto en un pequeño paquete de datos. Mientras solo se cambie un bit, se producirá un error. Por lo tanto, las comprobaciones de paridad son más confiables cuando se utilizan paquetes pequeños. Código Hamming Para empezar con cualquier juego necesitamos unas normas. Y las normas de Hamming son las tres siguientes (si estas instrucciones no te aclaran mira la imagen que viene después, y luego vuelve, lo vas a entender enseguida): 1. Utilizaremos como “bits de redundancia” los conocidos como “bits de paridad” para comprobar si hay errores o no (serán las pistas): “1” significa “impar”, y “0” significa “par” (el «Bit de Paridad» es la suma de “1s”; por ejemplo, la cadena de bits “1011” la suma de “1s” es 3, que es impar, por lo que el bit de paridad es “1”, Si tienes curiosidad tienes más información sobre «bits de Paridad» en este otro artículo sobre «Dígitos de control» haciendo click aquí). 2. Cada “bit de paridad” comprobará unos bits determinados, dependiendo de la posición que ocupe y siguiendo las normas del siguiente ejemplo. Por ejemplo, la posición es 4, desde está misma posición se seleccionarán 4, luego dejará 4 sin seleccionar, seleccionará los siguientes 4, para luego dejar los siguientes 4 sin seleccionar, y así hasta el infinito. Lo mismo para todas las posiciones que son potencias de dos (para la posición 1 es uno sí, uno no, uno sí, uno no, etc; ¿Y para la posición 2? Dos sí, dos no, dos sí, dos no; la cuatro te la he dicho antes, ¿Y para los siguientes 8, 16, 32, etc? es muy fácil). 3. De las anteriores selecciones el “bit de paridad” es de lo seleccionado la posición de número más pequeña (evidentemente, porque si el bit de paridad dice si es par o impar la suma de los “1s”, si se comprobara a sí mismo, entraríamos en un bucle infinito sin sentido), el resto son los bits que comprueba (que serán los que se sumen para saber si es par o impar). Siguiendo estas instrucciones podríamos dibujar hasta el infinito una matri z infinita. Pero vamos a reducirla hasta la posición 20 que puedes ver en la siguiente imagen (el resto hasta el infinito es igual . UTELVT. 2018 ). Pág. 13 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Verás que la cadena de bits se compone de bits de datos y bits de paridad mezclados (pero no revueltos ). Sabemos que los bits de paridad son las potencias de dos: 1, 2, 4, 8, 16 (el siguiente es 32, y el ejemplo solo tiene 20 bits, así que ya paro la cuenta). Al “ bit de paridad” en sí lo he llamado en la imagen “P” seguido de la posición que ocupa (por ejemplo, el que ocupa la posición 4, lo he llamado “P4”). No hay que confundir con las filas de bits que comprueba cada “bit de paridad” e incluyéndose así mismo; a cada fila de éstas la he denominado en la imagen como “fP” seguido de la posición en la que empieza (como “fP4”, que es la fila que comprueba el “bit de paridad” llamado “P4” e incluyéndose así mismo). Esto es una matriz vulgar y corriente, lo único que un poco más emocionante. Esta matriz se llama “Matriz de comprobación de paridad” (Parity-check Matrix) o “Matriz Síndrome” (Syndrome Matrix); a esta matriz a mí me gusta llamarla “Matriz de deducción” que suena mucho más misterioso y porque esta matriz nos servirá para deducir con las pistas los bits que están mal para poder corregirlos, o simplemente detectar si hay errores. Seguro que te has fijado en que encima de la “matriz síndrome” anterior aparece la palabra “Hamming(7,4)”. Lo he querido señalar porque es el código Hamming más típico. Aunque existen infinitos, pero siempre siguiendo las normas, otros podrían ser el: Hamming(3,1) Hamming(15,11): en la matriz de la anterior imagen llegaría justo hasta antes de la posición 16 Hamming(31,26): llegaría justo hasta la posición anterior a la 32 etc… Centrémonos en “Hamming(7,4)”, que quiere decir que por cada 7 bits que representan datos hay 4 que son bits de Datos y los (7 – 4 =) 3 restantes son “bits paridad”. Dicho de otro modo, si dividimos en cachos de 4 bits un vídeo/foto/audio/texto; obtendríamos, por ejemplo, un trozo que podría ser “1011”. . UTELVT. 2018 Pág. 14 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS A este cacho de 4 bits se le añaden 3 bits más que servirían para comprobar los datos (los “bits de paridad”). Para ello los ubicamos reservando los huecos para los “bits de paridad” de las posiciones 1, 2 y 4 (como en la “matriz síndrome” que vimos más arriba). Completamos las filas que comprobarán cada “bit de deducción” en la “matriz síndrome” (hasta la posición 7, no necesitamos más) con las normas antes descritas. Como puedes ver en la imagen siguiente (te recomiendo que ojees a la imagen siguiente a medida que lees este párrafo), tenemos 3 filas: “fP1”, “fP2” y “fP4”. Estas filas se pueden representar igualmente por conjuntos (pues cada fila contiene un conjunto/grupo de bits), y podemos ver que hay bits en algunas filas que comparten la misma posición (no confund as el “bit de paridad” como “P4”, con la fila que comprueba “fP4” en la que se incluye el propio “P4”, así como los datos de las posiciones 5, 6 y 7; así que nunca coincidirán las posiciones de los “bits de paridad”, pero sí de los bits que comprueba y esto veremos más adelante porqué es). De este modo, vemos que son conjuntos que represento con los mismos colores (o mismo “fP”) tanto en fila (en la imagen la “matriz síndrome” al a izquierda) como en círculo (en la imagen los círculos de colores): fP1 o Verde: con el “bit de paridad” P1, y las posiciones de datos 3, 5 y 7 fP2 o Rojo: con el “bit de paridad” P2, y las posiciones de datos 3, 6 y 7 fP4 o Azul: con el “bit de paridad” P4, y las posiciones de datos 5, 6 y 7 Solo nos queda calcular los “bits de paridad”. Simplemente sumamos los “1s” de cada fila, miramos si es par o impar (recordatorio: “par” = ”0”, e “impar” = “1”), y completamos el “bit de paridad”. En los conjuntos circulares he cambiado las posiciones de la anterior imagen por los bits pro piamente. . UTELVT. 2018 Pág. 15 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Ya tenemos la cadena de bits que incluye los datos y los “bits de comprobación” siguiendo “Hammin(7,4)”. Nombres de los grupos de bits Realmente al dato que se envía se llama “Mensaje” o “Secuencia de Datos”, que se convierte mediante el “Código de Hamming” a un “Bloque de código”. Si queremos enviar el “Bloque de código” por Internet al ordenador de, por ejemplo, un amigo, ya no se llamará “Bloque de código” sino que se llamará “Palabra del código”, pues se preparará (añadiendo otros bits con significado, cuyo significado dependerá del protocolo de la comunicación) para entrar en un canal de comunicación que es Internet. . UTELVT. 2018 Pág. 16 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Resumen de las palabras: “Mensaje” o “Secuencia de Datos” (en inglés, “Data Sequence”): normalmente el trozo de lo queremos enviar (por ejemplo, un fichero grande, dividido en pequeños trozos que son los mensajes) “Bloque del código” (“Block Code”): Por teoría de la codificación, el resultado de aplicar un codificador (como el código Hamming) al mensaje para que le añada bits de redundancia (como los bits de paridad). (Nota sobre la traducción: No traduzco «Block Code» a «Código del Bloque» y sí a «Bloque del código», pues un «Código corrector de errores» codifica los datos en bloques, por lo que uno de estos bloques pertenece a un «Código» que lo ha creado, y podemos decir que es un «Bloque del código») “Palabra del código” (“Code Word”): Por teoría de la comunicación, lo que queremos enviar por un canal de comunicación (como Internet), que normalmente va a ser un “Bloque de código” para corregir errores quien reciba la “Palabra del código” (Podría ser también un “Mensaje” la “Palabra del código”, aunque si llegan bits erróneos al receptor no habrá forma de corregirlos al no tener bits de redundancia). Buscar errores y corregirlos Ahora lo mismo, pero al revés ¡Que dé comienzo el juego de deducción! Supongamos que nos llega por Internet (o un dato de un disco duro) la siguiente cadena de bits, con bits de datos y “bits de paridad”. Tenemos que comprobar que esté bien el dato ante s de utilizarlo; no vaya a ser que por Internet debido a alguna interferencia se haya cambiado algún bit (o si estuviera en nuestro disco duro de plato, pudiera ser que se haya desmagnetizado algún bit; para los discos duros SSD podría ser que alguna celda de memoria estuviera defectuosa y no guardara bien algún bit, por ejemplo). Vamos, que queremos utilizar la siguiente cadena de bits y no sabemos si está correcto para poder utilizarlo ¡Comprobémoslo! . UTELVT. 2018 Pág. 17 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS No sabemos si tiene algún error o no, puede que esté correcto, puede que tenga algunos bits cambiados; tampoco sabemos si los que están mal son los bits que corresponden con los datos o los propios “bits de paridad” ¿Entonces, si está mal algún “bit de paridad” ya no podremos corregir o comprobar nada? También podemos saber si está mal algún “bit de paridad” e incluso corregirlo, veamos cómo. Lo primero que tenemos que hacer es rellenar la “matriz síndrome”. No rellenamos los “bits de paridad”, pues es lo que utilizamos para realizar las comprobaciones; es l o que tenemos que volver a calcular igual que antes. Al igual que hicimos anteriormente calculamos los “bits de paridad”. Una vez calculados comprobamos con los que ya tenía la cadena entera, miramos si coinciden. En el ejemplo podemos comprobar que hay 2 “bits de paridad” que no coinciden en las filas “fP2” (rojo) y “fP4” (azul), con lo que hay algo mal seguro. Pero, ¿qué bit está mal? Con lo que deducimos que . UTELVT. 2018 Pág. 18 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS el bit erróneo debe pertenecer a ambas filas (en este juego de deducción, con las pruebas hemos logrado reconocer al malo). Por lo que, si no es “0” el bit erróneo, debe ser “1” y lo corregimos. ¿El bit de la posición 7 no está también coincidiendo en las dos filas marcadas como erróneas? Ten en cuenta que el bit “1” de la posición 7 ya nos está diciendo la fila “fp1” (verde) que está bien. Solo el “0” de la posición 6 coincide con las filas “fP2” (rojo) y “fP4” (azul) únicamente; y es el que está mal. Una vez corregido podemos quitar los “bits de paridad” y obtener el dato en perfecto estado, así usarlo. Si era un trozo de una imagen, por ejemplo, después de comprobar el resto de cachos y componer todos los bits de la imagen, podemos ya por fin visualizarla sin ningún problema. ¿Y si el que está mal era un “bit de paridad”? Como el siguiente: Su “matriz síndrome” nos revelará que lo único que está mal es el propio “bit de paridad”. Pues como hemos dicho más arriba, los “bits de paridad” no son coincidentes con bits de otras filas; por lo que si el error lo tiene el “bit de paridad” siempre va a estar en soledad. Sabiendo que está mal podremos corregirlo o no, lo que nos importa es el dato realmente que está correcto. . UTELVT. 2018 Pág. 19 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS ¿El código de Hamming hasta cuantos bits puede corregir? Evidentemente si todos son erróneos, es imposible corregir nada, pues es otra cosa diferente que se validaría como correcta (Si tenemos una puerta a la que le falta una bisagra la podemos arreglar; lo que no podemos es suponer que una manzana es una puerta en mal estado e intentar “arreglarla” poniéndole una bisagra, pues una manzana es otra cosa, no es una puerta). Para saber cuántos bits se pueden corregir se necesita la “Distancia de Hamming” (la veremos en otro artículo) Hamming extendido También se utiliza el “Hamming Extendido” para asegurar una mejor detección. Simplemente consiste en añadir una fila adicional completa, y un nuevo bit de paridad en la primera posición. Nota sobre la Matriz síndrome anterior: La puedes utilizar para practicar código Hamming al imprimirla (en blanco y negro al ser posible) y escribir encima. Un ejemplo del código Hamming Extendido aplicado con lo antes visto sería: . UTELVT. 2018 Pág. 20 UNIVERSIDAD TÉCNICA “LUIS VARGAS TORRES” DE ESMERALDAS Para terminar, fíjate bien que ya no sería “Hamming(7,4)”, sino “Hamming(8,4)” (4 bits de datos más 4 bits de paridad). . UTELVT. 2018 Pág. 21