Con*_*ngo 6 c++ windows winapi visual-studio-2010
如果我在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.
Run Code Online (Sandbox Code Playgroud)
(专家额外) 实验方法
我编写了一个测试C++项目来分配100MB的数据,使WorkingSet超过100MB(在Process Explorer中查看),然后释放该内存.但是,一旦我释放了内存,操作系统就会将WorkingSet重新调整为16MB.如果你愿意,我可以提供我用过的测试C++项目.
为什么Windows提供对SetProcessWorkingSetSizeEx()的调用,如果它看起来不起作用?我一定做错了什么.
下图显示了当绿线(工作集)从50MB下降到30MB时,软页面错误(红色峰值)数量急剧增加.

更新
最后,我们最终忽略了这个问题,因为它不会对性能产生太大影响.
更重要的是,SetProcessWorkingSetSizeEx并没有控制当前工作集,并且不以任何方式软页面错误有关.它所做的只是通过阻止当前的WorkingSet被分页到硬盘驱动器来防止硬页面错误.
换句话说,如果想要减少软页面错误,SetProcessWorkingSetSizeEx绝对没有效果,因为它指的是硬页面错误.
在"Windows via C/C++"(Richter)中有一篇很棒的文章,介绍了Windows如何处理内存.
页面错误的发生率很低,并且是可以预料到的。实时应用程序、高端游戏、高强度处理和蓝光播放都可以全速运行,不会出现页面错误。页面错误并不是应用程序缓慢的原因。
要找出应用程序速度缓慢的原因,您需要对应用程序进行一些应用程序分析。
具体回答你的问题 - 当你刚刚有 GC.Collect() 时发生的页面错误不是页面输入错误,它们是由于 GC 刚刚分配而导致的需求清零页面错误一个新的巨大的需求归零页面块,用于将您的对象移动到其中。需求零页面不会从页面文件中得到服务,并且不会产生磁盘成本,但它们仍然是页面错误,因此它们显示在图表上。
一般来说,Windows 比您更擅长管理系统资源,并且它的默认设置针对正常程序的一般情况进行了高度调整。从您的示例中可以清楚地看出您正在使用垃圾收集器,因此您已经将处理工作集和虚拟内存等任务转移给 GC 实现。如果 SetProcessWorkingSetSize 是一个可以提高 GC 性能的良好 API 调用,那么 GC 实现就会做到这一点。
我给您的建议是分析您的应用程序。托管应用程序速度减慢的主要原因是编写了糟糕的托管代码,而不是 GC 减慢了速度。提高算法的大O性能,通过使用Future和BackgroundWorker之类的东西来卸载昂贵的工作,并尽量避免对网络进行同步请求——但最重要的是,让你的应用程序快速运行的关键是对其进行分析。
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |