Almacenamiento en búfer de archivo

En este tema se describen las distintas consideraciones para el control de la aplicación del almacenamiento en búfer de archivos, también conocido como entrada y salida de archivos no almacenados en búfer (E/S). Normalmente, el sistema controla el almacenamiento en búfer de archivos en segundo plano y se considera parte del almacenamiento en caché de archivos en el sistema operativo Windows a menos que se especifique lo contrario. Aunque los términos almacenamiento en caché y almacenamiento en búfer se usan a veces indistintamente, en este tema se usa el término almacenamiento en búfer específicamente en el contexto de explicar cómo interactuar con los datos que no se almacenan en caché (almacenados en búfer) por el sistema, donde en gran medida está fuera del control directo de las aplicaciones en modo de usuario.

Al abrir o crear un archivo con la función CreateFile , se puede especificar la marca FILE_FLAG_NO_BUFFERING para deshabilitar el almacenamiento en caché del sistema de los datos que se leen o escriben en el archivo. Aunque esto proporciona control completo y directo sobre el almacenamiento en búfer de E/S de datos, en el caso de archivos y dispositivos similares, hay requisitos de alineación de datos que se deben tener en cuenta.

Nota

Esta información de alineación se aplica a la E/S en dispositivos como archivos que admiten la búsqueda y el concepto de punteros de posición de archivo (o desplazamientos). En el caso de los dispositivos que no buscan, como canalizaciones con nombre o dispositivos de comunicaciones, la desactivación del almacenamiento en búfer puede no requerir ninguna alineación determinada. Las limitaciones o eficiencias que se pueden obtener por alineación en ese caso dependen de la tecnología subyacente.

 

En un ejemplo sencillo, la aplicación abriría un archivo para el acceso de escritura con la marca FILE_FLAG_NO_BUFFERING y, a continuación, realizaría una llamada a la función WriteFile mediante un búfer de datos definido en la aplicación. Este búfer local es, en estas circunstancias, eficazmente el único búfer de archivos que existe para esta operación. Debido al diseño de disco físico, el diseño del almacenamiento del sistema de archivos y el seguimiento de la posición del puntero de archivo de nivel del sistema, esta operación de escritura producirá un error a menos que los búferes de datos definidos localmente cumplan ciertos criterios de alineación, que se describen en la sección siguiente.

Nota

La explicación del almacenamiento en caché no tiene en cuenta ningún almacenamiento en caché de hardware en el propio disco físico, que no se garantiza que esté dentro del control directo del sistema en ningún caso. Esto no tiene ningún efecto en los requisitos especificados en este tema.

 

Para obtener más información sobre cómo FILE_FLAG_NO_BUFFERING interactúa con otras marcas relacionadas con la memoria caché, vea CreateFile.

Requisitos de alineación y acceso a archivos

Como se explicó anteriormente, una aplicación debe cumplir ciertos requisitos al trabajar con archivos abiertos con FILE_FLAG_NO_BUFFERING. Se aplican los siguientes detalles:

  • Tamaños de acceso a archivos, incluido el desplazamiento de archivo opcional en la estructura SUPERPUESTA , si se especifica, debe ser para un número de bytes que sea un entero múltiplo del tamaño del sector del volumen. Por ejemplo, si el tamaño del sector es de 512 bytes, una aplicación puede solicitar lecturas y escrituras de 512, 1024, 1536 o 2048 bytes, pero no de 335, 981 o 7 171 bytes.
  • Las direcciones del búfer de acceso a archivos para las operaciones de lectura y escritura deben estar alineadas en el sector físico, lo que significa alinearse en las direcciones en la memoria que son múltiplos enteros del tamaño del sector físico del volumen. En función del disco, es posible que este requisito no se aplique.

Los desarrolladores de aplicaciones deben tener en cuenta los nuevos tipos de dispositivos de almacenamiento que se introducen en el mercado con un tamaño de sector de medios físicos de 4096 bytes. El nombre del sector de estos dispositivos es "Formato avanzado". Dado que puede haber problemas de compatibilidad con la introducción directa de 4096 bytes como unidad de direccionamiento para el medio, una solución de compatibilidad temporal consiste en introducir dispositivos que emulen un dispositivo de almacenamiento del sector normal de 512 bytes, pero que hagan disponible información sobre el tamaño del sector verdadero a través de comandos ATA y SCSI estándar.

Como resultado de esta emulación, hay en esencia dos tamaños de sector que los desarrolladores deberán comprender:

  • Sector lógico: unidad que se usa para el direccionamiento de bloques lógicos para los medios. También podemos considerarlo como la unidad de escritura más pequeña que el almacenamiento puede aceptar. Esta es la "emulación".
  • Sector físico: unidad para la que se completan las operaciones de lectura y escritura en el dispositivo en una sola operación. Se trata de la unidad de escritura atómica y de qué E/S sin búfer tendrá que alinearse para tener características óptimas de rendimiento y confiabilidad.

La mayoría de las API de Windows actuales, como IOCTL_DISK_GET_DRIVE_GEOMETRY y GetDiskFreeSpace, devolverán el tamaño del sector lógico, pero el tamaño del sector físico se puede recuperar a través del código de control IOCTL_STORAGE_QUERY_PROPERTY , con la información pertinente contenida en el miembro BytesPerPhysicalSector de la estructura STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR . Para obtener un ejemplo, vea el código de ejemplo en STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR. Microsoft recomienda encarecidamente que los desarrolladores alineen la E/S sin búfer con el tamaño del sector físico, tal y como indica el código de control de IOCTL_STORAGE_QUERY_PROPERTY para ayudar a garantizar que sus aplicaciones estén preparadas para esta transición del tamaño del sector.

Windows Server 2003 y Windows XP: La estructura STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR no está disponible. Se introdujo con Windows Vista y Windows Server 2008.

Dado que las direcciones de búfer para las operaciones de lectura y escritura deben estar alineadas en el sector, la aplicación debe tener el control directo de cómo se asignan estos búferes. Una manera de alinear los búferes de sector es usar la función VirtualAlloc para asignar los búferes. Tenga en cuenta lo siguiente.

  • VirtualAlloc asigna memoria alineada en direcciones que son múltiplos enteros del tamaño de página del sistema. El tamaño de página es de 4096 bytes en x64 y x86 o 8 192 bytes para sistemas basados en Itanium. Para obtener más información, consulte la función GetSystemInfo .
  • El tamaño del sector suele ser de 512 a 4096 bytes para dispositivos de almacenamiento de acceso directo (unidades de disco duro) y 2048 bytes para CD-ROM.
  • Los tamaños de página y sector son potencias de 2.

Por lo tanto, en la mayoría de las situaciones, la memoria alineada con páginas también se alineará en el sector, ya que el caso en el que el tamaño del sector es mayor que el tamaño de página es poco frecuente.

Otra manera de obtener búferes de memoria alineados manualmente es usar la función _aligned_malloc de la biblioteca de Run-Time de C. Para obtener un ejemplo de cómo controlar manualmente la alineación del búfer, vea el ejemplo de código del lenguaje C++ en la sección Código de ejemplo de WriteFile.