9

ドライブの読み取り速度を判断しようとしている場合は、ファイルをファイル システムに書き込み、それらのファイルを読み戻すルーチンをコーディングできます。残念ながら、これは正確な読み取り速度を提供しません。これは、Windows がディスク読み取りキャッシュを行うためです。

C# / .Net (またはおそらく Win32 API 呼び出し) でドライブのディスク読み取りキャッシュをフラッシュして、ファイルをキャッシュせずにドライブから直接読み取ることができる方法はありますか?

4

5 に答える 5

14

コンスタンティン: ありがとう!そのリンクには、私が探していたテストを行うコマンドライン EXE があります。

そのページから、このページのより興味深い記事 (Word および PDF) へのリンクも見つけました: Sequential File Programming Patterns and Performance with .NET

この記事では、バッファリングされていないファイルのパフォーマンスについて説明します (つまり、読み取り/書き込みキャッシュはなく、生のディスク パフォーマンスのみです)。

記事から直接引用:

V2 .NET フレームワークで FileStream バッファリングを無効にする簡単な方法はありません。C# で次のように、Windows ファイル システムを直接呼び出して、バッファリングされていないファイル ハンドルを取得し、その結果を FileStream に「ラップ」する必要があります。

    [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 コンストラクターに 3 番目の引数として渡される「true」値は、ストリームがファイル ハンドルの所有権を取得する必要があることを示します。つまり、ストリームが閉じられると、ファイル ハンドルは自動的に閉じられます。このばか騒ぎの後、バッファリングされていないファイルストリームは、他のものと同じ方法で読み書きされます。

于 2008-09-24T17:30:10.920 に答える
12

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 キャッシュ (OS キャッシュよりも低速で小さい) もあります (ただし、FileOptions.WriteThrough は、書き込みをキャッシュしない場合に役立ちます)。これらのオプションを使用すると、フラッシュする理由はありませんが、キャッシュの実装が遅い場合に、このアプローチが速度を低下させないことを適切にテストしてください。

于 2009-09-03T15:31:05.293 に答える
4
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);
于 2008-12-21T19:37:49.850 に答える
4

なぜDIY?

ドライブ速度を決定する必要があるだけで、.NET から I/O バッファをフラッシュする方法を学ぶことにあまり関心がない場合は、http://research.microsoft.com/barc/Sequential_IO/の DiskSpd ユーティリティを使用できます。バッファ フラッシュの有無にかかわらず、ランダム/シーケンシャル モードがあります。

このページには、役立つと思われる I/O 関連の調査レポートもいくつかあります。

于 2008-09-23T19:16:12.887 に答える
-1

この記事を見つけましたが、他のキャッシュもフラッシュする必要があるため、これは複雑なプログラムのようです。

于 2008-09-23T17:17:36.090 に答える