web-dev-qa-db-ja.com

ファイルシステムのキャッシュを無効にするにはどうすればよいですか?

アプリケーションの「コールドブート」起動パフォーマンスを測定/最適化したいのですが、実際の再起動なしでこれを行うことは困難です。これは明らかに理想的なソリューションではありません。

システム全体のファイルキャッシュを無効にして、マップされたページアクセスが実際にディスクアクセスを引き起こし、プログラムの起動にかかる時間を測定できるようにする方法はありますか?

情報:

私はかなり必要ですFSCTL_DISMOUNT_VOLUMEの機能ですが、システムボリューム用です。

31
user541686

少なくともWindows7では、ボリュームハンドルなしで開こうとしているようですFILE_SHARE_WRITE共有権限ファイルシステムキャッシュが無効になります作成に失敗しました

したがって、この目的のためにCreateFileを呼び出すだけのプログラムを作成しました。

プログラムのBase64エンコーディング*:

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SmaD+lp3RGaDeAI6dT0Pt1AEZoXSdAxmg/pcdS5mOUgGdShqXFlqLmaJjdj//f9miY3a//3/WWpcZomN3P/9/1lqBGaJjd7//f9Zi9APtwAz/2Y7x3QWD7fAZomETdj//f9BQkIPtwJmO8d17VdXagNXM8BqAWaJhE3Y//3/agGNhdj//f9Q/1Xgg/j/dAlQ/1Xc6b8AAAD/VTBqIIvQWYlVcDvRD4SsAAAAg/oFD4SjAAAAakVYanJmiUUAWGpvi/hmiX0CZol9BF9qJWaJfQaL+GaJfQiL+WaJfQpfamRmiX0MX2pjZol9Dov5Zol9EF9qZWaJfRKL+2aJfRRfamFmiUUaZol9Fl9qaVhqbmaJRRxYamdmiUUeWGolZolFIFhqc2aJRSRYZolFJmoKWGaJRSgzwGaJRSqLRfxmiU0ii010Zol9GP80iI1FAFJQVv9VbIPEEP9FdItFdDtF+A+MfP7//4tFcF9eW4PFeMnDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAQAYAAAAGAAAgAAAAAAAAAAABAAAAAAAAQABAAAAMAAAgAAAAAAAAAAABAAAAAAAAQAJBAAASAAAAFggAABlAQAA5AQAAAAAAAA8YXNzZW1ibHkgeG1sbnM9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206YXNtLnYxIiBtYW5pZmVzdFZlcnNpb249IjEuMCI+DQogIDx0cnVzdEluZm8geG1sbnM9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206YXNtLnYzIj4NCiAgICA8c2VjdXJpdHk+DQogICAgICA8cmVxdWVzdGVkUHJpdmlsZWdlcz4NCiAgICAgICAgPHJlcXVlc3RlZEV4ZWN1dGlvbkxldmVsIGxldmVsPSJyZXF1aXJlQWRtaW5pc3RyYXRvciIgdWlBY2Nlc3M9ImZhbHNlIj48L3JlcXVlc3RlZEV4ZWN1dGlvbkxldmVsPg0KICAgICAgPC9yZXF1ZXN0ZWRQcml2aWxlZ2VzPg0KICAgIDwvc2VjdXJpdHk+DQogIDwvdHJ1c3RJbmZvPg0KPC9hc3NlbWJseT5QQURQQURESU5HWFhQQURESU5HUEFERElOR1hYUEFERElOR1BBRERJTkdYWFBBRERJTkdQQURESU5HWFhQQURESU5H

ソース:

// Usage: ClearCache C: D:
#include <tchar.h>
#include <stdio.h>
#include <windows.h>

int _tmain(int argc, LPTSTR argv[]) {
    LPCTSTR DOS_PREFIX = _T("\\\\.\\");
    for (int i = 1; i < argc; i++) {
        LPTSTR arg = argv[i];
        LPTSTR path = (LPTSTR)calloc(
            _tcslen(arg) + _tcslen(DOS_PREFIX) + 1, sizeof(*arg));
        __try {
            if (_istalpha(arg[0]) && arg[1] == _T(':') &&
               (arg[2] == _T('\0') ||
                arg[2] == _T('\\') && arg[3] == _T('\0')))
            { _tcscat(path, DOS_PREFIX); }
            _tcscat(path, arg);
            HANDLE hFile = CreateFile(path,
                FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
            if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); }
            else {
                DWORD le = GetLastError();
                if (le != ERROR_SHARING_VIOLATION && le != ERROR_ACCESS_DENIED)
                {
                    _ftprintf(stderr, _T("Error %d clearing %s\n"), le, argv[i]);
                    return le;
                }
            }
        } __finally { free(path); }
    }
    return 0;
}

*楽しみのために、実行可能ファイルを分解して何をするかを理解できるかどうかを確認してください。それはあなたの典型的な実行可能ファイルではありません。 :)

33
Mehrdad

これを行うための簡単なコマンドラインユーティリティを作成しました: FlushFileCache

文書化されていないNtSetSystemInformation関数に依存しており、他のさまざまなメモリプールもフラッシュできます。

5
Eric Grange

ダビデが言ったこと。必要なGB数の大きなファイルを作成し、ファイルキャッシュをリセットするたびに、ファイルのコピーを作成します。次に、古いファイルを必ず削除してください。

したがって、BIGFILE1.DATを作成し、それをBIGFILE2.DATにコピーしてから、BIGFILE1.DATを削除します(これにより、ディスクとキャッシュから削除されます)。次回は、プロセスを逆にします。

補遺:

もう1つのオプションは、マップされたファイルを取得して新しいファイルにコピーし、古いファイルを削除して、新しいファイルの名前を古いファイルに戻すことです。キャッシュはファイルによってバックアップされます。ファイルが「なくなる」と、キャッシュもなくなります。

これらのファイルを識別でき、それらがシステム/他の実行中のプログラムによって共有されていない場合、これはスクリプトを作成するのが簡単で、理想的には、6Gのファイルをコピーするよりも高速に実行する必要があります。

2
Will Hartung

このソリューションはうまく機能しました: https://stackoverflow.com/a/7113153/9136

より具体的には、私はこれを行っています:

// open with FILE_FLAG_NO_BUFFERING 
auto hFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);

/// check
if (hFile == INVALID_HANDLE_VALUE){
    //_tprintf(TEXT("Terminal failure: unable to open file \"%s\" for read.\n"), argv[1]);
    cout << "error" << endl;
    return;
}

// close
CloseHandle(hFile);

// now open file with regular C++ API, and caching disabled
ifstream file(path, ios::binary | ios::ate);
0
Markus

VMを使用して、VMの起動直後にスナップショットを作成できます。スナップショットからの再開は、再起動よりも高速です。

0
John