2008-09-23 6 views
6

드라이브의 읽기 속도를 결정하려는 경우 파일 시스템에 파일을 쓰고 그 파일을 다시 읽도록 루틴을 코딩 할 수 있습니다. 불행하게도, Windows는 디스크 읽기 캐싱을하기 때문에 정확한 읽기 속도를 제공하지 못합니다.C#에서 Windows READ 디스크 캐시를 비우거나 플러시하는 방법은 무엇입니까?

캐시되지 않고 드라이브에서 직접 파일을 읽을 수 있도록 C#/.Net (또는 Win32 API 호출)의 드라이브 읽기 캐시를 비울 수있는 방법이 있습니까?

답변

4

왜 DIY입니까?

드라이브 속도를 결정하고 .NET에서 I/O 버퍼를 플러시하는 방법을 배우고 싶지 않으면 DiskSpd 유틸리티를 http://research.microsoft.com/barc/Sequential_IO/에서 사용할 수 있습니다. 버퍼 플러시가 있거나없는 임의/순차 모드가 있습니다.

이 페이지에는 유용한 I/O 관련 연구 보고서가 있습니다.

0

나는 this 문서를 발견했으며 다른 캐시를 플러시해야하기 때문에이 프로그램은 복잡한 것처럼 보입니다.

12

콘스탄틴 : 감사합니다! 이 링크에는 내가 찾고있는 테스트를 수행하는 명령 행 EXE가 있습니다.

내가이 페이지에 (워드 및 PDF에서) 더 흥미로운 기사로 해당 페이지 오프 링크 발견 : Sequential File Programming Patterns and Performance with .NET

이 글에서를, 그것은 취소 버퍼 파일 실적 (IOW, 아니 읽기 /에 대해 이야기 쓰기 캐싱 - 그냥 원시 디스크 성능을) 기사에서 직접 인용

을 :

는 V2 .NET 프레임 워크에 파일 스트림 버퍼링을 해제하는 간단한 방법이 없다.. 하나는 되지 않은 버퍼 파일 핸들을 얻기 위해 직접 윈도우 파일 시스템을 호출해야하고 '랩' 로하여 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); 

를 CreateFile()를 호출 FILE_FLAG_NO_BUFFERING 플래그는 파일 시스템이 모든 소프트웨어를 무시하도록 지시합니다. 파일에 대한 메모리 캐싱. FileStream을 생성자 세 번째 인수로 전달 된 '진정한'값은 스트림이 스트림이 닫힐 때 파일 핸들이 가 자동으로 종료됩니다 을 의미하는 파일 핸들의 소유권을해야 함을 나타냅니다. 이 후 hocus-pocus 이후, 버퍼링되지 않은 파일 스트림은 다른 어떤 것과 마찬가지로 방법으로 읽고 쓰여집니다. 수정의

+0

나는 이것을 투표에 부쳤지 만, 테스트를 마친 후에는 작동하지 않았습니다. 불행히도 그 시점까지 투표를 삭제하기에는 너무 늦었습니다! 코드가 컴파일되지 않습니다 ('FileAccess.Read'와'CreateFile()'을 전달할 수 없으며 코드를 실행하지 않는 열거 형을 입력하면 hTemplate으로 'null'을 전달할 수 없습니다.) – Oliver

+0

@Oliver : 나는이 코드를 7 년 동안 보지 않았기 때문에 일이 아마 바뀌었을 것이다. 나는 7 년 전 C#/VS2005 (또는 VS2008, 내가 그 시점에서 전환했다는 것을 확신하지 못한다.) 나는 내가 원래의 코드를 찾았다면 그것을 볼 수있을 것이다. – 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

응답은 거의 오른쪽 PInvoke를보다 더했다. 그러나 버그가이며 작동하지 않습니다 ...

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000; 

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

몇 가지 규칙 :

는 캐싱 O를 한 다음 작업을 수행 할 필요가 승/파일을 열려면

  1. 블록 크기 정렬 된 하드 드라이브 클러스터 크기 (4096이어야 대부분의 시간)
  2. 파일 위치 변경 클러스터 크기가 맞춰져 있어야합니다.
  3. 당신은 더 적은 읽기/쓰기가 불가능합니다. N 블록 크기 또는 그것의 크기

에 정렬되지 않은 블록을 잊지 마세요 - 또한 HDD 캐시가 (이 느린 OS 캐시보다 작은) 당신이에 의해 해제 (하지만 때로는 수없는 FileOptions.WriteThrough 쓰기를 캐싱하지 않는 데 도움이 됨). 이러한 옵션을 사용하면 플러시 할 이유가 없지만 캐시 구현이 느릴 경우이 방법을 사용하면 속도가 느려지지 않는다는 것을 적절히 테스트했는지 확인해야합니다.