C/C++分配器在多线程环境下的性能如何



当使用new或malloc分配内存时,分配器可能必须保护自己不被重新进入。我看到了两种方法:

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

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

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

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

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

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

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

还要注意,C++new运算符调用libc提供的malloc函数(在大多数情况下为glibcmalloc)。

因此:

  1. 不,这种行为不规范
  2. 它仅在每个线程使用一个池(并且仅当)您使用glibc>=2.16时,否则您可以尝试使用TCMalloc进行编译

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

  • std::pmr::unsynchronized_pool_resource不是线程安全的,不能从多个线程同时访问
  • std::pmr::synchronized_pool_resource可以在没有外部同步的情况下从多个线程访问,并且可以具有特定于线程的池以降低同步成本。如果只从一个线程访问内存资源,那么非同步的_pool_resource会更有效率

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

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

相关内容

  • 没有找到相关文章