2008-09-23 13 views
6

Si estoy tratando de 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 lee en caché el disco.Cómo vaciar/vaciar Windows ¿LEER el caché de disco en C#?

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

Respuesta

4

¿Por qué bricolaje?

Si solo necesita determinar la velocidad del disco y no está realmente interesado en aprender cómo eliminar los búfers de E/S de .NET, puede usar la utilidad DiskSpd desde http://research.microsoft.com/barc/Sequential_IO/. Tiene modos aleatorios/secuenciales con y sin lavado de buffer.

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

0

Encontré this artículo y parece que este es un programa complicado porque también tiene que enjuagar otros cachés.

12

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

También encontré un enlace de esa página a un artículo más interesante (en Word y PDF) en esta página: Sequential File Programming Patterns and Performance with .NET

En este artículo, se habla de rendimiento-buffered de archivos (OIA, ninguna de lectura/caché de escritura - el rendimiento del disco acaba de crudo)

Citado directamente desde el artículo:

no hay manera fácil de desactivar el almacenamiento en búfer FileStream en el marco V2 .NET.. Uno debe invocar el sistema de archivos de Windows directamente para obtener un identificador de archivo sin buffer y luego 'envoltura' el resultado en un FileStream como siguiente 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); 

llamadas CreateFile() con el indicador FILE_FLAG_NO_BUFFERING indica al sistema de archivos que omita todo el almacenamiento en memoria caché del software del archivo. El ‘verdadero’ valor pasado como el tercer argumento del constructor FileStream indica que la corriente debe tomar propiedad del identificador de archivo, lo que significa que el identificador de archivo se cerrará automáticamente cuando la corriente está cerrado. Después de hocus-pocus, el archivo sin buffer se lee y se escribe de la misma manera que cualquier otro.

+0

He votado esto, pero no funcionó después de las pruebas. Desafortunadamente, en ese momento ya era demasiado tarde para eliminar mi voto. El código no se compila (no puede pasar 'FileAccess.Read' y es similar a' CreateFile() 'y si escribe las enumeraciones el código no se ejecuta, no puede pasar' null' como hTemplate. – Oliver

+0

@Oliver : No he visto este código en (* mira mirar *) durante 7 años, así que las cosas probablemente han cambiado. Estoy bastante seguro de que funcionó hace 7 años con C# /. NET 2.0 en VS2005 (o tal vez VS2008, no estoy seguro de si ya había cambiado en ese momento.) Veré si puedo encontrar el código original que estaba usando en ese momento y publicar de nuevo si lo encuentro. – Pretzel

3
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); 
10

Respuesta de Fix era casi justo y mejor que PInvoke. Pero tiene errores y no funciona ...

Para abren archivos w/o el almacenamiento en caché uno tiene que hacer lo siguiente:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000; 

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

algunas reglas:

  1. blockSize debe ser el tamaño del clúster en el disco duro alineado (4096 la mayor parte del hora)
  2. cambio de posición del archivo debe ser el tamaño del clúster alineado
  3. no se puede leer/escribir menos tha n blockSize o no bloquear alineado a su tamaño

Y no se olvide - también hay HDD caché (que más lento y más pequeño que caché del sistema operativo) que no se puede apagar por eso (pero a veces FileOptions.WriteThrough ayuda para no escribir en caché). Con esas opciones, no tiene ninguna razón para enrojecer, pero asegúrese de haber probado adecuadamente que este enfoque no disminuirá la velocidad en caso de que la implementación de la memoria caché sea más lenta.

Cuestiones relacionadas