c++ - 在 C++ 中,有什么方法可以强制进程的 WorkingSet 为 1GB?

标签 c++ windows visual-studio-2010 winapi

如果我在 C++ 中使用以下调用,我希望进程的 WorkingSet 永远不会低于 100MB。

但是,即使我进行此调用,操作系统仍将工作集缩减为 16MB。

将 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.

(专家额外) 实验方法论

我编写了一个测试 C++ 项目来分配 100MB 的数据以使 WorkingSet 超过 100MB(在 Process Explorer 中查看),然后释放该内存。但是,一旦我释放该内存,操作系统就将 WorkingSet 缩减为 16MB。如果您愿意,我可以提供我使用的测试 C++ 项目。

为什么 Windows 提供对 SetProcessWorkingSetSizeEx() 的调用,如果它似乎不起作用?我一定是做错了什么。

下图显示了当绿线(工作集)从 50MB 下降到 30MB 时,软页面错误(红色尖峰)的数量急剧增加。

Example showing the increase in soft page faults when the WorkingSet is reduced too low

更新

最后,我们忽略了这个问题,因为它对性能影响不大。

更重要的是,SetProcessWorkingSetSizeEx 控制当前的 WorkingSet,并且 以任何方式与软页面错误相关。它所做的只是通过防止当前 WorkingSet 被分页到硬盘驱动器来防止硬页面错误。

换句话说,如果要减少软页错误,SetProcessWorkingSetSizeEx 完全没有作用,因为它指的是硬页错误。

“Windows via C/C++”(Richter)中有一篇很棒的文章介绍了 Windows 如何处理内存。

最佳答案

页面错误很便宜并且是可以预料的。实时应用程序、高端游戏、高强度处理和蓝光播放都可以在页面错误的情况下全速运行。页面错误不是您的应用程序运行缓慢的原因。

要找出您的应用程序运行缓慢的原因,您需要对您的应用程序进行一些应用程序分析。

具体回答你的问题 - 当你刚刚有一个 GC.Collect() 时发生的页面错误不是页面错误,它们是由 GC 引起的需求归零页面错误刚刚分配了一个新的巨大的需求归零页面 block 来将您的对象移动到。请求零页不从您的页面文件中得到服务并且不会产生磁盘成本,但它们仍然是页面错误,因此它们显示在您的图表上。

作为一般规则,Windows 比您更擅长管理系统资源,并且它的默认设置针对普通程序的一般情况进行了高度调整。从您的示例中可以清楚地看出您正在使用垃圾收集器,因此您已经将处理工作集和虚拟内存等的任务卸载到 GC 实现中。如果 SetProcessWorkingSetSize 是提高 GC 性能的良好 API 调用,那么 GC 实现会做到这一点。

我对您的建议是分析您的应用。托管应用程序运行缓慢的主要原因是编写糟糕的托管代码——而不是 GC 拖慢了您的速度。提高算法的 big-O 性能,通过使用 Future 和 BackgroundWorker 之类的东西来卸载昂贵的工作,并尽量避免对网络进行同步请求——但最重要的是,让你的应用程序快速运行的关键是 profile 它。

关于c++ - 在 C++ 中,有什么方法可以强制进程的 WorkingSet 为 1GB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12228321/

相关文章:

objective-c - 在 Windows 上使用 objective-c 进行 GUI 编程?

node.js - 从nodejs调用Windows SetWinEventHook

c# - 以编程方式将用户控件添加到工具箱时出现问题

c++ - 将 GMP 添加到自己的库

c++ - 在类构造函数中定义结构变量的参数

python - 编译 Mozilla Firefox 时创建 ./config.data 失败

c# - Visual Studio 2010 C# 智能感知代码片段的有用列表

c++ - 将 CMAKE 变量添加到 KDevelop 中的项目

c++ - 使用 Eclipse GUI 远程调试 C++ 应用程序

windows - 始终将 Windows 中的特定文件类型保存到一个位置?