7

Windowsにそのファイルを強制的にキャッシュさせるバッチコマンドまたは何かがありますか? ゲームを開始する前に特定のゲーム ファイルをキャッシュに読み込むゲーム プリローダーを作成しようとしています。これを行う方法はありますか?

更新された int メイン コード:

int main(int argc, const char** argv)
{
if(argc >= 2) for(int i = 1; argv[i]; ++i) pf("C:\\Games\World_of_Tanks\res\packages\gui.pkg"[i]);
return 0;
}
4

1 に答える 1

15

必要なのは、ファイルを使用するReadFileかメモリ マッピングしてすべてのページにアクセスすることにより、ファイルをロードすることだけです (実際には、16 ページごとの割り当ての粒度で十分ですが、理論的にはすべてのページにアクセスする必要があります)。
メモリ マッピングは、データを保持するために余分なメモリを割り当てる必要がないため、より高速でキャッシュ フレンドリです (これは何の役にも立ちません!)。OS は、プロセスが認識できるキャッシュと仮想メモリに同じ物理メモリを再利用します。

Microsoft Office や Adob​​e Reader などのいくつかの主流アプリケーションは、まさにそれを行って起動を高速化しています。ログイン後、ハードディスクのライトが数十秒間点滅し続けるのは、これらの「遅延開始」サービスです。

ただし、Windows 1にそのように強制的にファイルをキャッシュさせることはできますが、ファイルを無期限にキャッシュに保持するように強制することはできないことに注意してください。十分な物理 RAM が利用できない場合、システムはアプリケーションの要求を満たすためにキャッシュの内容を破棄します。

EDIT:ファイルマッピングを使用した最小限の実装例:

#include <windows.h>
#include <cstdio>

void pf(const char* name)
{
    HANDLE file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if(file == INVALID_HANDLE_VALUE) { printf("couldn't open %s\n", name); return; };

    unsigned int len  = GetFileSize(file, 0);

    HANDLE mapping  = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0);
    if(mapping == 0) { printf("couldn't map %s\n", name); return; }

    const char* data = (const char*) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);

    if(data)
    {
        printf("prefetching %s... ", name);

        // need volatile or need to use result - compiler will otherwise optimize out whole loop
        volatile unsigned int touch = 0;

        for(unsigned int i = 0; i < len; i += 4096)
            touch += data[i];
    }
    else
        printf("couldn't create view of %s\n", name);

    UnmapViewOfFile(data);
    CloseHandle(mapping);
    CloseHandle(file);
}

int main(int argc, const char** argv)
{
    if(argc >= 2) for(int i = 1; argv[i]; ++i) pf(argv[i]);
    return 0;
}

プログラムは、コマンドラインで指定されたファイル名をプリフェッチしようとします。
コードはあまりきれいではありませんが、機能します。ANSIファイル名を使用し、開くことは成功したがマッピングが失敗した場合にファイルハンドルをリークします(しかし、ブレ...それは実際には問題ではありません.OSはプログラムの終了後にクリーンアップします-それが面倒な場合は、ハンドルをRAIIでラップします)。それもcaに限定されています。32 ビット ビルドのアドレス空間により 1.8GiB のファイル サイズ、それ以外の場合は により 4GiB に制限されGetFileSizeますが、これほど大きなファイルが本当に必要な場合は、簡単に修正できます。
代わりにvolatile、「結果」を返したり、消費したりしたいかもしれませんが、どちらの方法でも機能します (volatileディスクアクセスと比較して、パフォーマンスに測定可能な影響はありません!)。


1実を言うと、実際には Windows を強制することはできませんが、バッファなしの I/O を明示的に要求しない限り、Windows は常にそのように動作します。
理論的には、OS にページ強制的にメモリに読み込ませたり、メモリをロックして RAM に保持させたりすることもできますが、ワーキング セット クォータ (これは非常に小さく、それを変更するには管理権限が必要です) は通常は実行されません。これをさせてください。ただし、大量のメモリをロックすることは非常に悪い考えであるため、これは良いことです。

于 2013-11-07T01:16:05.307 に答える