C++分配速度变慢的奇怪现象

9

请问为什么以下情况会发生:

我有两台电脑:

  1. 我的工作电脑
  2. 服务器

我维护一个C++程序(使用msvc 2005 c++编译),在服务器上运行速度过慢,但在我的电脑上却没有问题。

我进行了测量(使用GetThreadTimes等方法),可以明确地说瓶颈就在于内存分配(new/malloc)。而这种情况只出现在服务器上!

我认为这是由于内存碎片化导致的,因为第一次在服务器上运行程序实例时,它的表现良好,但当数据重新加载到内存中后(1-1.5百万个内存分配/释放),它开始在内存分配方面浪费时间。

如果我在两台电脑上都看到了由于内存碎片化而出现的相同行为,我也不会感到太惊讶,但事实并非如此:

  1. 在我的电脑上,内存分配占用时间的比例约为5%(不是精确值,但大致如此)。
  2. 在服务器上,这些内存分配占用时间的比例约为75%。

为什么C++内存分配在服务器上会变慢,而在我的工作电脑上却没有问题?两者之间有什么区别?可能与操作系统级的内存管理函数有关吗?因为在这两种情况下,C++级别的管理器是相同的。

以下是两台电脑的配置:

1. 我的电脑(内存分配约占5%):

OS Name:                   Microsoft Windows 7 Enterprise 
OS Version:                6.1.7600 N/A Build 7600
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Member Workstation
OS Build Type:             Multiprocessor Free
Registered Owner:          Windows User
Original Install Date:     16/09/2011, 19:37:43
System Boot Time:          05/04/2013, 11:58:11
System Model:              7304A58
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
                           [01]: Intel64 Family 6 Model 23 Stepping 10 GenuineIntel ~2642 Mhz
Windows Directory:         C:\Windows
System Directory:          C:\Windows\system32
Boot Device:               \Device\HarddiskVolume2
System Locale:             ru;Russian
Input Locale:              en-us;English (United States)
Total Physical Memory:     4,061 MB
Available Physical Memory: 872 MB
Virtual Memory: Max Size:  8,121 MB
Virtual Memory: Available: 4,579 MB
Virtual Memory: In Use:    3,542 MB
Page File Location(s):     C:\pagefile.sys

2). 服务器(分配占用约75%):

OS Name:                   Microsoft(R) Windows(R) Server 2003, Enterprise Edition
OS Version:                5.2.3790 Service Pack 2 Build 3790
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Member Server
OS Build Type:             Multiprocessor Free
Original Install Date:     11/12/2008, 01:22:57
System Up Time:            1 Days, 8 Hours, 35 Minutes, 52 Seconds
System Manufacturer:       HP
System Model:              ProLiant BL685c G5  
System Type:               X86-based PC
Processor(s):              4 Processor(s) Installed.
                           [01]: x86 Family 16 Model 2 Stepping 3 AuthenticAMD ~2210 Mhz
                           [02]: x86 Family 16 Model 2 Stepping 3 AuthenticAMD ~2210 Mhz
                           [03]: x86 Family 16 Model 2 Stepping 3 AuthenticAMD ~2210 Mhz
                           [04]: x86 Family 16 Model 2 Stepping 3 AuthenticAMD ~2210 Mhz
Windows Directory:         C:\WINNT
System Directory:          C:\WINNT\system32
Boot Device:               \Device\HarddiskVolume1
Total Physical Memory:     65,534 MB
Available Physical Memory: 61,284 MB
Page File: Max Size:       97,696 MB
Page File: Available:      93,445 MB
Page File: In Use:         4,251 MB
Page File Location(s):     C:\pagefile.sys
                           D:\pagefile1\pagefile.sys
                           D:\pagefile2\pagefile.sys
                           D:\pagefile3\pagefile.sys
                           D:\pagefile4\pagefile.sys
                           D:\pagefile5\pagefile.sys
                           D:\pagefile6\pagefile.sys
                           D:\pagefile7\pagefile.sys

非常感谢您解答这个问题。


你在两台机器上使用的是同一数据集吗? - nneonneo
不行,但是相当的。我的电脑有大约260,000个项目可以流畅地工作,服务器在大约350,000个项目时会遇到困难,即使在加载前100,000个项目时也会开始努力工作。 - Andrew Lebedeff
1个回答

4
问题可能是内存函数只使用一个互斥锁来锁定内存进行分配和释放。

2
MSVC++ 2005并不是最新版本,Server 2003也不是。Windows 7机器默认启用了低碎片堆。因此,这是一个相当可信的答案。我期望较新版本能更好地适应4x4核心机器。作为解决方法,尝试使用另一个分配器,例如jemalloc - MSalters
3
有趣。引用自该讨论串(https://dev59.com/RG445IYBdhLWcg3wcJ6O): "... 如果启用了低碎片堆,则操作系统堆函数的表现会相当出色,自Windows Vista起它是默认启用的(在Windows XP上,应用程序可以通过简单调用HeapSetInformation()来启用它)。而且启用LFH后,Windows堆的性能可与其他最快速度的分配器相媲美"。 - SChepurin
谢谢,我会考虑使用jemalloc,可能会有所帮助,但不确定我的上级是否会接受 :) - Andrew Lebedeff
非常感谢LFH。为了测试数百万个allocs,我写了一个小的分配测试,并在Windows XP上测试了MSVC++ 2005(手动设置LFH标志和不设置LFH标志)。速度差异为2-10倍。顺便说一句,MSVC++ 2010 CRT会自动设置此LFH标志,无需手动调用HeapSetInformation()。因此,这种效果发生在MSVC++ 2005 + Win XP或Win 2003服务器(旧操作系统)上。 - Andrew Lebedeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接