Pregunta

Si intento determinar la velocidad de lectura de una unidad, puedo codificar una rutina para escribir archivos en un sistema de archivos y luego volver a leer esos archivos.Desafortunadamente, esto no proporciona una velocidad de lectura precisa porque Windows realiza almacenamiento en caché de lectura en disco.

¿Hay alguna manera de vaciar el caché de lectura del disco de una unidad en C#/.Net (o quizás con llamadas a la API de Win32) para poder leer los archivos directamente desde el disco sin que se almacenen en el caché?

¿Fue útil?

Solución

¿Por qué hacerlo tú mismo?

Si sólo necesita determinar la velocidad de la unidad y no está realmente interesado en aprender cómo vaciar los buffers de E/S desde .NET, puede usar la utilidad DiskSpd desde http://research.microsoft.com/barc/Sequential_IO/.Tiene modos aleatorios/secuenciales con y sin vaciado de búfer.

La página también tiene algunos informes de investigación relacionados con E/S que pueden resultarle útiles.

Otros consejos

Constantino:¡Gracias!Ese enlace tiene un EXE de línea de comandos que realiza las pruebas que estaba buscando.

También encontré un enlace fuera de esa página a un artículo más interesante (en Word y PDF) en esta página: Patrones de programación de archivos secuenciales y rendimiento con .NET

En este artículo, se habla del rendimiento de archivos sin búfer (es decir, sin almacenamiento en caché de lectura/escritura, solo rendimiento del disco sin formato).

Citado directamente del artículo:

No hay una forma simple de deshabilitar el búfer de FilEnstream en el marco .NET V2.Uno debe invocar el sistema de archivos de Windows directamente para obtener un identificador de archivo tombinado y luego 'envolver' el resultado en una corriente de archivo de la siguiente manera en C#:

    [DllImport("kernel32", SetLastError=true)]
    static extern unsafe SafeFileHandle CreateFile(
        string FileName,           // file name
        uint DesiredAccess,        // access mode
        uint ShareMode,            // share mode
        IntPtr SecurityAttributes, // Security Attr
        uint CreationDisposition,  // how to create
        uint FlagsAndAttributes,   // file attributes
        SafeFileHandle  hTemplate // template file  
        );

    SafeFileHandle handle = CreateFile(FileName,
                            FileAccess.Read,
                            FileShare.None,
                            IntPtr.Zero,
                            FileMode.Open,
                             FILE_FLAG_NO_BUFFERING,
                            null);

    FileStream stream = new FileStream(handle, 
                    FileAccess.Read, 
                    true, 
                    4096);

Llamar a createFile () con el indicador FILE_FLAG_NO_BUFFERING le dice al sistema de archivos que omite todo el almacenamiento en caché de memoria de software para el archivo.El valor 'verdadero' aprobado como el tercer argumento al constructor de FileStream indica que la secuencia debe tomar posesión del mango del archivo, lo que significa que el mango del archivo se cerrará automáticamente cuando la secuencia esté cerrada.Después de este Hocus-Pocus, la transmisión de archivos tombinada de la ONU se lee y escribe de la misma manera que cualquier otra.

La respuesta de Fix fue casi correcta y mejor que PInvoke.pero tiene errores y no funciona...

Para abrir un archivo sin almacenamiento en caché, es necesario hacer lo siguiente:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;

FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize,
    FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions);

Pocas reglas:

  1. blockSize debe estar alineado con el tamaño del clúster del disco duro (4096 la mayor parte del tiempo)
  2. El cambio de posición del archivo debe estar alineado con el tamaño del grupo.
  3. no puedes leer/escribir menos que blockSize o el bloque no está alineado con su tamaño

Y no lo olvide: también existe la caché de disco duro (que es más lenta y más pequeña que la caché del sistema operativo) que no puede desactivar con eso (pero a veces FileOptions.WriteThrough ayuda a no almacenar en caché las escrituras).Con esas opciones, no tiene motivos para vaciar, pero asegúrese de haber probado adecuadamente que este enfoque no ralentizará las cosas en caso de que su implementación de caché sea más lenta.

const int FILE_FLAG_NO_BUFFERING = 0x20000000;
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,64 * 1024,
(FileOptions)FILE_FLAG_NO_BUFFERING | FileOptions.Asynchronous
& FileOptions.SequentialScan);

encontré este artículo y parece que este es un programa complicado porque también tienes que vaciar otros cachés.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top