C# で Windows READ ディスク キャッシュを空/フラッシュする方法は?
質問
ドライブの読み取り速度を確認したい場合は、ファイルシステムにファイルを書き込み、それらのファイルを読み取るルーチンをコーディングできます。残念ながら、Windows はディスク読み取りキャッシュを行うため、これでは正確な読み取り速度は得られません。
C# / .Net (または Win32 API 呼び出しを使用して) でドライブのディスク読み取りキャッシュをフラッシュし、キャッシュされずにドライブからファイルを直接読み取ることができるようにする方法はありますか?
解決
なぜDIYなのか?
ドライブ速度を決定するだけでよく、.NET から I/O バッファをフラッシュする方法を学ぶことにあまり興味がない場合は、DiskSpd ユーティリティを使用することもできます。 http://research.microsoft.com/barc/Sequential_IO/. 。バッファフラッシュありとなしのランダム/シーケンシャルモードがあります。
このページには、役立つと思われる I/O 関連の調査レポートもいくつか掲載されています。
他のヒント
コンスタンティン:ありがとう!このリンクには、私が探していたテストを実行するコマンドライン EXE があります。
このページには、そのページからさらに興味深い記事 (Word および PDF) へのリンクも見つかりました。 .NET を使用したシーケンシャル ファイル プログラミング パターンとパフォーマンス
この記事では、バッファリングされていないファイルのパフォーマンスについて説明します (つまり、読み取り/書き込みキャッシュはなく、生ディスクのパフォーマンスのみです)。
記事から直接引用:
V2 .NETフレームワークでFilestreamバッファリングを無効にする簡単な方法はありません。Windowsファイルシステムを直接呼び出して、UNバッファーファイルハンドルを取得し、次のように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番目の引数として渡された「真」の値は、ストリームがファイルハンドルの所有権を取得する必要があることを示しています。つまり、ストリームが閉じたときにファイルハンドルが自動的に閉じられます。このHocus-Pocusの後、UNバッファーファイルストリームは、他と同じ方法で読み取りおよび書き込まれます。
Fix の応答はほぼ正しく、PInvoke よりも優れていました。しかし、バグがあります そして機能しません...
キャッシュなしでファイルを開くには、次の操作を行う必要があります。
const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;
FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize,
FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions);
いくつかのルール:
- blockSize は、ハード ドライブ クラスタ サイズに合わせて調整する必要があります (ほとんどの場合 4096)。
- ファイル位置の変更はクラスタ サイズに合わせて行う必要があります
- blockSize 未満の読み取り/書き込み、またはブロックのサイズが整っていない場合は読み取り/書き込みできません。
そして、忘れないでください。HDD キャッシュ (OS キャッシュよりも遅く、サイズも小さい) もあります。これをオフにすることはできません (ただし、書き込みをキャッシュしない場合は FileOptions.WriteThrough が役立つ場合があります)。これらのオプションを使用すると、フラッシュする理由はありませんが、キャッシュの実装が遅い場合に備えて、このアプローチによって処理が遅くならないことを適切にテストしてください。
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);
見つけました これ の記事によると、他のキャッシュもフラッシュする必要があるため、これは複雑なプログラムであるようです。