【问题标题】:Is Boost Pool free efficiency O(n) or O(1)Boost Pool 效率是 O(n) 还是 O(1)
【发布时间】:2011-03-13 08:52:53
【问题描述】:

最近我发现了 Boos Pool 库并开始将其改编为我的代码。库提到它缺少的一件事是一个基类,它将覆盖任何类的新/删除运算符并使用池进行内存管理。我编写了自己的实现并通过一些元模板编程,它实际上看起来非常不错(通过简单地从基类派生来支持大小在 1 到 1024 字节之间的任何类)

我提到这些事情是因为到目前为止这真的很酷也很令人兴奋,然后我发现了这个post from Boost mailing list。似乎有些人真的对 Pool 库进行了抨击,特别指出了他们所说的在 O(n) 时间内运行的 free() 方法的效率低下。我单步执行了代码,发现这是该方法的实现:

void free(void * const chunk)
{
  nextof(chunk) = first;
  first = chunk;
}

对我来说,这看起来像 O(1),我真的没有看到他们在谈论的低效率。我确实注意到的一件事是,如果您使用多个 singleton_pool 实例(即不同的标签和/或分配大小),它们都共享相同的互斥锁(更准确地说是关键部分),这可以进行一些优化。但如果您使用常规堆操作,它们将使用相同形式的同步。

那么其他人是否认为池库效率低下且过时?

【问题讨论】:

  • nextof(void*)的实现是什么?
  • 像往常一样,拥有一个或多个互斥体是一种权衡。如果您有 很多 个池,您会得到一种内存碎片,因为它们会将自己的内存留给自己。
  • @Null nextof(...) 是一个单行 reinterpret_cast

标签: c++ optimization memory-management boost malloc


【解决方案1】:

在我看来,免费的时间确实是固定不变的。也许这篇文章的作者指的是ordered_free,它有这个实现:

void ordered_free(void * const chunk)
{
  // This (slower) implementation of 'free' places the memory
  //  back in the list in its proper order.

  // Find where "chunk" goes in the free list
  void * const loc = find_prev(chunk);

  // Place either at beginning or in middle/end
  if (loc == 0)
    (free)(chunk);
  else
  {
    nextof(chunk) = nextof(loc);
    nextof(loc) = chunk;
  }
}

其中find_prev如下

template <typename SizeType>
void * simple_segregated_storage<SizeType>::find_prev(void * const ptr)
{
  // Handle border case
  if (first == 0 || std::greater<void *>()(first, ptr))
    return 0;

  void * iter = first;
  while (true)
  {
    // if we're about to hit the end or
    //  if we've found where "ptr" goes
    if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr))
      return iter;

    iter = nextof(iter);
  }
}

【讨论】:

  • 让我感到困惑的部分是,我阅读了整个 boost 邮件列表线程,并且有几个人(即不仅仅是一种意见)对 Pool 库使用了非常强大的语言。他们没有说不要使用“有序”功能,他们只是说库不好,Boost 需要有人来编写 Pool2。
  • 我也遇到了 boost::object_pool::free 非常慢的问题。性能问题确实似乎与 find_prev() 中的线性搜索有关。在我的示例中,尝试从 450 万个池中释放 40 万个对象大约需要半小时。我可能需要将休眠对象保留在池中,直到整个池被释放。
猜你喜欢
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 2013-05-04
  • 2021-10-22
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
  • 2011-08-15
相关资源
最近更新 更多