繁体   English   中英

如何在C#中清空/清空Windows READ磁盘缓存?

[英]How to empty/flush Windows READ disk cache in C#?

如果我试图确定驱动器的读取速度,则可以编写例程以将文件写入文件系统,然后再将这些文件读回。 不幸的是,由于Windows会进行磁盘读取缓存,因此无法提供准确的读取速度。

有没有一种方法可以刷新C#/ .Net中驱动器的磁盘读取缓存(或使用Win32 API调用),以便我可以直接从驱动器读取文件而无需对其进行缓存?

康斯坦丁:谢谢! 该链接具有一个命令行EXE,可以执行我正在寻找的测试。

我还在该页面下找到了指向该页面上另一篇更有趣的文章(Word和PDF)的链接: 顺序文件编程模式和.NET的性能。

在本文中,它讨论了非缓冲文件的性能(现在,没有读/写缓存-只是原始磁盘性能。)

直接从文章引用:

在V2 .NET框架中没有简单的方法来禁用FileStream缓冲。 必须直接调用Windows文件系统以获得未缓冲的文件句柄,然后将结果“包装”到FileStream中,如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);

使用FILE_FLAG_NO_BUFFERING标志调用CreateFile()告诉文件系统绕过该文件的所有软件内存缓存。 作为第三个参数传递给FileStream构造函数的'true'值指示流应拥有文件句柄的所有权,这意味着在关闭流时,文件句柄将自动关闭。 在此过程之后,将以与其他任何方式相同的方式读取和写入未缓冲的文件流。

Fix的响应几乎是正确的,并且比PInvoke更好。 但是它有错误并且不起作用...

要打开不带缓存的文件,需要执行以下操作:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;

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

几个规则:

  1. blockSize必须与硬盘驱动器群集大小对齐(大多数情况下为4096)
  2. 文件位置更改必须与簇大小对齐
  3. 您读/写的内容不能少于blockSize或不与其大小对齐的块

而且请不要忘记-还有HDD Cache(它比OS缓存更慢且更小),因此您无法将其关闭(但有时FileOptions.WriteThrough有助于不缓存写入操作)。 使用这些选项,您没有理由进行刷新,但请确保已正确测试了这种方法不会减慢万一缓存实现的速度。

为什么要DIY?

如果您只需要确定驱动器速度,而不是真的对学习如何从.NET刷新I / O缓冲区不感兴趣,则可以使用http://research.microsoft.com/barc/Sequential_IO/中的 DiskSpd实用程序。 它具有带/不带缓冲区刷新的随机/顺序模式。

该页面还包含一些与I / O相关的研究报告,您可能会觉得有用。

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

我找到了这篇文章,这似乎是一个复杂的程序,因为您还必须刷新其他缓存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM