C++ で次の呼び出しを使用すると、プロセスの WorkingSet が 100MB を下回らないことが予想されます。
ただし、この呼び出しを行っても、OS はワーキング セットを 16 MB に戻します。
WorkingSet を 100MB に設定すると、ソフト ページのページ フォールトがなくなるため、アプリケーションの速度が劇的に向上します (下の図を参照)。
私は何を間違っていますか?
SIZE_T workingSetSizeMB = 100;
int errorCode = SetProcessWorkingSetSizeEx(
GetCurrentProcess(),
(workingSetSizeMB - 1) * 1024 * 1024), // dwMinimumWorkingSetSize
workingSetSizeMB * 1024 * 1024, // dwMaximumWorkingSetSize,
QUOTA_LIMITS_HARDWS_MIN_ENABLE | QUOTA_LIMITS_HARDWS_MAX_DISABLE
);
// errorCode returns 1, so the call worked.
(専門家向けの追加) 実験方法論
100MB のデータを割り当てて WorkingSet を 100MB (Process Explorer 内で表示) を超えるテスト C++ プロジェクトを作成し、そのメモリの割り当てを解除しました。ただし、そのメモリの割り当てを解除するとすぐに、OS は WorkingSet を 16 MB に戻しました。ご希望であれば、私が使用したテスト C++ プロジェクトを提供できます。
Windows が SetProcessWorkingSetSizeEx() の呼び出しを提供しているのに、機能していないように見えるのはなぜですか? 私は何か間違ったことをしているに違いない。
下の図は、緑の線 (ワーキング セット) が 50MB から 30MB に減少したときのソフト ページ フォールト (赤いスパイク) の数の劇的な増加を示しています。
アップデート
結局、パフォーマンスにそれほど影響を与えなかったため、問題を無視することになりました。
さらに重要なことに、SetProcessWorkingSetSizeEx は現在の WorkingSet を制御せず、ソフト ページ フォールトとはまったく関係がありません。現在の WorkingSet がハード ドライブにページ アウトされるのを防ぐことで、ハード ページ フォールトを防ぐだけです。
つまり、ソフト ページ フォールトを減らしたい場合、SetProcessWorkingSetSizeEx はハード ページ フォールトを参照するため、まったく効果がありません。
「Windows via C/C++」(Richter) には、Windows がメモリをどのように扱うかについての優れた記事があります。