0

我在 32 位 linux 上使用 boost 线程已经有一段时间了,到目前为止,我对它们的性能非常满意。最近该项目转移到 64 位平台,我们看到内存使用量大幅增加(从大约 2.5gb 到 16-17gb)。我做了分析,发现 boost 线程是巨大分配的来源。每个线程分配大约 10 倍于它在 32 位上所做的工作。

我使用 valgrind 的地块进行了分析,并在单独的测试应用程序中仅使用 boost 线程确认了该问题。我也尝试使用 std::threads 代替,这些并没有表现出大的内存分配问题。

我想知道是否有其他人看到过这种行为并知道问题出在哪里?谢谢。

4

2 回答 2

3

这里没有问题。这是虚拟内存,每个 64 位进程可以在每个现代操作系统上分配 TB 的虚拟内存。它基本上是免费的,没有理由关心它使用了多少。

它基本上只是为线程堆栈保留的空间。如果需要,您可以通过更改默认堆栈大小来减少它。但绝对没有理由这样做。

于 2012-08-27T01:25:12.433 回答
3

1.每个线程的堆栈大小

使用 pthread_attr_getstacksize 查看。使用 boost::thread::attributes 来改变 (pthread_attr_setstacksize)。

2. glibc 的 malloc 中每个线程的 pre-mmap

boost.thread 的 gdb 示例

0  0x000000000040ffe0 in boost::detail::get_once_per_thread_epoch() ()  
1  0x0000000000407c12 in void boost::call_once<void (*)()>(boost::once_flag&, void (*)()) [clone .constprop.120] ()  
2  0x00000000004082cf in thread_proxy ()  
3  0x000000000041120a in start_thread (arg=0x7ffff7ffd700) at pthread_create.c:308  
4  0x00000000004c5cf9 in clone ()  
5  0x0000000000000000 in ?? ()  

您将data=malloc(sizeof(boost::uintmax_t));在 get_once_per_thread_epoch ( boost_1_50_0/libs/thread/src/pthread/once.cpp )中发现

继续

1  0x000000000041a0d3 in new_heap ()  
2  0x000000000041b045 in arena_get2.isra.5.part.6 ()  
3  0x000000000041ed13 in malloc ()  
4  0x0000000000401b1a in test () at pthread_malloc_8byte.cc:9  
5  0x0000000000402d3a in start_thread (arg=0x7ffff7ffd700) at pthread_create.c:308  
6  0x00000000004413d9 in clone ()  
7  0x0000000000000000 in ?? ()  

在 new_heap 函数 ( glibc-2.15\malloc\arena.c ) 中,它将为 64 位操作系统中的每个线程预先映射 64M 内存。换句话说,每个线程将使用64M + 8M(默认线程堆栈)= 72M

glibc-2.15\ChangeLog.17  
2009-03-13  Ulrich Drepper  <drepper@redhat.com>  
  * malloc/malloc.c: Implement PER_THREAD and ATOMIC_FASTBINS features.  
  * malloc/arena.c: Likewise.  
  * malloc/hooks.c: Likewise. 

http://wuerping.github.io/blog/malloc_per_thread.html

于 2013-05-06T12:12:28.380 回答