Ir al contenido principal

Las regiones de memoria virtual suelen utilizarse como espacios de direcciones compartidos en las aplicaciones VOS. Se trata de una forma muy eficaz de permitir que varios procesos accedan al mismo conjunto de direcciones. La principal desventaja es que el espacio se limita a bastante menos de 2 GB debido a los límites de memoria virtual de VOS, y este uso reduce la memoria virtual disponible para otros fines.

El espacio de direcciones también se puede compartir a través del sistema de archivos asignando direcciones a un archivo binario y accediendo a ellas mediante operaciones de E/S de archivos. Esto elimina las restricciones de tamaño de las regiones de la máquina virtual y libera memoria que, de otro modo, estaría dedicada a la máquina virtual. También permite la coordinación mediante el bloqueo de regiones, pero resulta mucho más costoso que el acceso directo a la máquina virtual compartida, especialmente si implica operaciones reales de E/S de disco.

Las aplicaciones POSIX suelen utilizar archivos de flujo en modo binario para este fin, estableciendo el tamaño deseado del espacio de direcciones mediante ftruncate (utilizado por su capacidad para ampliar la ubicación del EOF) y, a continuación, situándose en las zonas del archivo desde las que se leen o escriben los datos. De este modo, el archivo sirve como almacén de respaldo para el espacio de direcciones y los procesos comparten dicho espacio utilizando interfaces orientadas a archivos, como fseek, fread y fwrite.

Antes de la introducción de los archivos de flujo de 64 bits (en la versión 17.2), esto podía resultar muy costoso en VOS, ya que los archivos de flujo normales no pueden ser dispersos, y ampliar el EOF implica asignar y escribir explícitamente bloques de ceros binarios. Por ejemplo, si el espacio de direcciones deseado fuera, digamos, de 2 GB, entonces VOS requeriría 524 288 bloques de almacenamiento en disco, aunque solo una pequeña parte de ese almacenamiento pudiera contener valores distintos de ceros binarios. Con los archivos de flujo de 64 bits, este tipo de aplicaciones ahora pueden ejecutarse de manera eficiente en VOS, requiriendo solo el espacio en disco que realmente se necesita. Las aplicaciones POSIX obtienen automáticamente las ventajas de los archivos de flujo de 64 bits cuando se compilan para gestionar archivos de gran tamaño; debe hacerlo para obtener estas ventajas de rendimiento, incluso si no se espera que los archivos superen los 2 GB. (Consulte el manual de referencia de OpenVOS POSIX.1, R502, «Porting Existing Applications to the 64-bit Stream File Environment» para obtener más información).

En las aplicaciones nativas de VOS, es decir, aquellas que utilizan interfaces s$, es posible un uso similar del espacio de direcciones compartido respaldado por archivos. VOS ofrece una serie de funciones que pueden reducir considerablemente las operaciones de E/S de disco al emplear esta técnica, lo que hace que el uso de la CPU sea, en esencia, el principal coste. La introducción de archivos de flujo dispersos de 64 bits en la versión 17.2 hace que este enfoque del espacio de direcciones compartido resulte aún más atractivo.

Archivos residentes en memoria y archivos RAM

Los archivos residentes en memoria se identifican mediante el comando `set_open_options`. Se reserva una parte configurable de la caché de disco para los archivos residentes en memoria. Dependiendo de la memoria física disponible y de otros usos de la caché, esta cantidad puede alcanzar los 9-10 GB. Una vez en la caché, los bloques de los archivos residentes en memoria no requerirán lecturas posteriores del disco, siempre y cuando el número total no supere esa parte de la caché. Si lo supera, los bloques a los que se haya accedido más recientemente conservarán esta ventaja.

Los archivos RAM son archivos que contienen datos no persistentes y resultan útiles cuando el archivo contiene datos que no es necesario guardar en el disco una vez que la aplicación ha terminado de utilizarlos. Se puede utilizar el comando `set_ram_file`, pero cualquier archivo para el que se llame a `s$delete_file_on_close` se trata automáticamente como un archivo RAM a partir de ese momento.
Aunque los archivos residentes en memoria no provocan lecturas de disco posteriores, los bloques se siguen escribiendo a intervalos regulares, y el número de bloques modificados permitidos en la caché está limitado, al igual que con cualquier otro archivo. Los límites de bloques modificados evitan la situación en la que podría ser necesario escribir millones de bloques al cerrar o vaciar el archivo —un archivo de 4 GB ocupa un millón de bloques—. Esta limitación puede ralentizar una aplicación que modifica datos más rápido de lo que se pueden escribir. Los archivos RAM evitan este tipo de ralentización, ya que sus datos nunca necesitan escribirse en el disco, incluso cuando el archivo está desactivado.

El uso de archivos RAM residentes en memoria proporciona un espacio de direcciones en la memoria caché que evita la mayor parte de las operaciones de E/S de disco; un espacio de direcciones que solo está limitado por el tamaño de la caché, el cual, a su vez, se basa en la memoria física disponible, no en la memoria virtual (el gestor de caché comparte direcciones de memoria virtual para acceder a la memoria física). Nota: un único espacio de direcciones basado en archivos puede crecer hasta 512 GB, pero cuando supera la parte de la caché residente en memoria, pierde las ventajas de E/S, al menos para aquellos bloques a los que no se ha hecho referencia recientemente.

Ejemplo

Se puede acceder al contenido de un archivo de flujo mediante s$seq_position con códigos de operación orientados a bytes y, a continuación, examinarlo o modificarlo utilizando s$read_raw/s$write_raw. Los archivos de flujo de 64 bits pueden alcanzar un tamaño de hasta 512 GB sin requerir un espacio de disco significativo, salvo en las regiones del archivo que se utilicen, es decir, aquellas a las que se haya asignado un valor distinto de cero.

Por ejemplo,

create_file scratch -organization stream64 -extent_size 256

Esto crea un archivo DAE-256 llamado «scratch»

archivo_ram_temporal

Esto permite que este archivo tenga acceso ilimitado a la caché, evitando cualquier limitación relacionada con el número de bloques modificados, y evitando por completo las escrituras en disco, salvo en segundo plano o cuando la caché se agota y se necesita para otros fines. Esto también se puede hacer mediante programación a través de s$set_ram_file. Cuando el último usuario que ha abierto el archivo lo cierra, los datos de la caché se descartan y nunca se producen escrituras en disco. El archivo debe estar vacío cuando se utiliza este comando.

set_open_options scratch -cache_mode memory_resident

Esto hace que se mantengan en la caché de forma indefinida el mayor número posible de bloques de este archivo. El número real depende del tamaño de la caché y del porcentaje de residencia en memoria, tal y como se establece en el comando set_tuning_parameters.

La siguiente secuencia muestra un ejemplo de uso programático (ilustrado mediante test_system_calls):

tsc: s$attach_port p scratch
tsc: s$open p -io_type update

Ahora, asigne un espacio de direcciones de unos 512 GB:

tsc: extend_stream_file p 549235720192 (s$control EXTEND_STREAM_FILE)

y utilizarlo para almacenar datos:

tsc: s$seq_position_x p bwd_by_bytes 3 (la posición actual tras la ampliación es EOF)
tsc: s$write_raw p END
tsc: s$seq_position_x p bof
tsc: s$write_raw p START
tsc: s$seq_position_x p fwd_by_bytes 2000
tsc: s$write_raw p 2000

Nota: s$seq_position también admite códigos de operación para situarse en desplazamientos de bytes absolutos.

El resultado es el siguiente: el archivo ocupa solo dos bloques de datos en el disco:

..dump_file scratch -brief

%swsle#Raid4>otto>d-3>nuevo>scratch 25-02-15 16:04:17 EST

Bloque número 1

000 53544152 54000000 00000000 00000000 |INICIO………..|
010 00000000 00000000 00000000 00000000 |…………….|
=
7D0 00000000 00323030 30000000 00000000 |…..2000…….|
7E0 00000000 00000000 00000000 00000000 |…………….|
=
FF0 00000000 00000000 00000000 00000000 |…………….|

Número de bloque 131870736

000 00000000 00000000 00000000 00000000 |…………….|
=
FF0 00000000 00000000 00000000 00454E44 |………….FIN|

Nota: los bloques 1 y 131870736 se encuentran en la caché y, por lo general, no se habrán escrito en el disco, aunque se les ha reservado espacio en disco por si fuera necesario hacerlo en caso de que los recursos de la caché se vieran saturados. El comando `dump_file` anterior muestra los bloques almacenados en la caché, no lee el disco.

Cuando un archivo RAM se desactiva (ya no está abierto en ningún proceso), VOS trunca el archivo (evitando escribir los bloques modificados en el disco) y libera todo el espacio en disco. En circunstancias normales, la secuencia anterior no generaría ninguna operación de E/S de disco, salvo las escrituras de los dos bloques del mapa de archivos, que finalmente se descartan.

tsc: s$close p

Ahora el archivo está vacío y no ocupa espacio en disco:

tsc: ..dump_file scratch

%swsle#Raid4>otto>d-3>nuevo>scratch 25-02-15 16:07:12 EST