3

当使用 new 或 malloc 分配内存时,分配器可能必须保护自己免受重入。我看到两种方法可以做到这一点:

  • 一个大互斥体。此解决方案简单但性能较差
  • 为每个线程保留一个内存池。性能很高,但池的大小可能难以评估。

我认为大多数分配器都使用第二种方法,但我找不到这方面的证据。

你知道哪个分配器使用哪个方法吗?这有什么标准吗?

4

3 回答 3

4

Google perf 工具提供了一个名为TCMalloc的分配器。这个分配器为每个线程使用一个内存池(=“线程缓存系统”)。文档显示了 glibc 2.3 的性能改进测量。

自 2.16 以来, Glibc为每个线程使用一个内存池

因此,现在没有更多的性能差异

Fedora [我们] 曾经有一段时间使用 tcmalloc 进行 QEMU。然后我们再次检查性能,发现 glibc 的原生 malloc 的 delta 基本上已经消失了

另请注意(在大多数情况下 = glibc malloc)提供的 C++new运算符调用malloc函数。libc

所以:

  1. 不,这种行为不规范
  2. 它仅(且仅当)您使用 glibc >= 2.16 时才使用每个线程的池,否则您可以尝试使用 TCMalloc 进行编译。
于 2018-08-06T14:10:24.710 回答
0

所有多线程程序分析,我用intel parallel studio(windows下)做的总是显示锁定事件和内核时间由于分配。这意味着 VS'08 编译器的 C++ 新版本主要使用互斥锁来保持内存连贯性。

每次在我开发的软件中出现问题时,我都会尝试使用 RIA 习惯用法并删除动态/共享内存,或者如果内存只能由线程本身使用,则使用 TLS 分配器。

于 2013-06-26T17:15:58.740 回答
0

C++17 开始指定线程应用程序中分配器的行为:

于 2016-12-01T10:41:37.683 回答