【发布时间】:2011-01-20 03:40:17
【问题描述】:
我有一个程序,它一次加载一个文件(从 10MB 到 5GB)一个块(ReadFile),并为每个块执行一组数学运算(基本上计算哈希)。
计算哈希后,它将有关块的信息存储在 STL 映射中(基本上是<chunkID, hash>),然后将块本身写入另一个文件(WriteFile)。
就是这样。该程序将导致某些 PC 窒息和死亡。鼠标开始卡顿,任务管理器需要超过 2 分钟才能显示,ctrl+alt+del 没有响应,运行程序很慢...... 工作。
我已经尽我所能来优化程序,并对所有对象进行了三次检查。
我做了什么:
- 尝试了不同的(强度较低的)哈希算法。
- 将所有分配切换到 nedmalloc 而不是默认的 new 运算符
- 从 stl::map 切换到 unordered_set,发现性能仍然很差,所以我再次切换到 Google 的 dense_hash_map。
- 将所有对象转换为存储指向对象的指针而不是对象本身。
- 缓存所有读写操作。我没有读取文件的 16k 块并对其执行数学运算,而是将 4MB 读入缓冲区并从 there 读取 16k 块。所有写入操作都相同 - 它们在写入磁盘之前合并为 4MB 块。
- 使用 Visual Studio 2010、AMD Code Analyst 和 perfmon 运行广泛的分析。
- 将线程优先级设置为 THREAD_MODE_BACKGROUND_BEGIN
- 将线程优先级设置为 THREAD_PRIORITY_IDLE
- 在每个循环之后添加了一个 Sleep(100) 调用。
即便如此,在某些情况下,应用程序仍会导致某些机器上的系统范围挂起。
Perfmon 和 Process Explorer 显示 CPU 使用率最低(睡眠时),磁盘没有持续的读取/写入,很少出现硬页面错误(在 5GB 输入文件上的应用程序生命周期中只有大约 30k 页面错误),虚拟内存很少(从不超过 150MB),没有泄漏的句柄,没有内存泄漏。
我测试过的机器运行 Windows XP - 包括 Windows 7、x86 和 x64 版本。没有一个内存小于 2GB,尽管在内存较低的情况下问题总是会加剧。
我不知道下一步该做什么。我不知道是什么原因造成的——罪魁祸首是 CPU 还是内存。 CPU 因为没有睡眠和在不同的线程优先级下,系统性能会发生显着变化。内存,因为在使用 unordered_set 与 Google 的 dense_hash_map 时,问题发生的频率存在巨大差异。
真正奇怪的是什么?显然,NT 内核设计应该防止这种行为发生永远(用户模式应用程序将系统驱动到这种极差的性能!?)......但是当我编译代码并在 OS X 或 Linux 上运行它(它始终是相当标准的 C++),即使在 RAM 很少且 CPU 较弱的糟糕机器上也能表现出色。
接下来我该怎么做?当所有的指标都表明应用程序本身并没有做任何极端的事情时,我怎么知道 Windows 在幕后做了什么导致系统性能下降?
欢迎任何建议。
【问题讨论】:
-
会不会是其他软件造成的?喜欢杀毒软件?
-
分析是否突出了任何特定于 Windows 的瓶颈?
-
+1 对于一个解释清楚的问题,有背景等。
-
@C.罗斯:谢谢。我试图尽可能详细,因为这是我曾经见过的最奇怪的问题,而且我在我的时间里遇到了一些非常奇怪的事情!
-
@Timo Geusch:不。唯一特定于 Windows 的瓶颈是 RtlEnterCriticalSection,应该忽略它。
标签: c++ windows performance optimization kernel