gpt4 book ai didi

c++ - 您如何确定由 'std::map' 创建的用于 'boost::pool_allocator' 的节点的大小(以跨平台方式)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:50 27 4
gpt4 key购买 nike

更新

根据评论、回答和其他研究,我得出的结论是 set 之间通常没有区别。和一个 map在节点开销方面。我接下来的问题是:

How do you determine node overhead for convenient use of boost::pool_allocator as a custom allocator?

并且,进一步的更新:节点开销可能永远不会超过 4 个指针的大小,因此只需清除 sizeof(T) 的 boost 池。 , sizeof(T)+sizeof(int) , sizeof(T) + 2*sizeof(int) , sizeof(T) + 3*sizeof(int)sizeof(T) + 4*sizeof(int) (或 int64_t 对于 64 位系统)应该没问题。这就是我实际在做的事情,而且很有效。


我想使用 boost memory pool通过避免调用这些对象的析构函数来管理数千万个大小相同的微小对象,而是在每个 strip 中包含许多实例的单个 strip 中释放内存。

我发布了 another question关于这个问题,这个问题的答案让我明白我真正需要回答的问题就是我在这里问的问题。

考虑以下代码:

class Obj { // ... has an operator<() ... };

typedef std::set<Obj, std::less<Obj>, boost::fast_pool_allocator<Obj>> fast_set_obj;

// Deliberately do not use a managed pointer -
// I will *NOT* delete this object, but instead
// I will manage the memory using the memory pool!!!
fast_set_obj * mset = new fast_set_obj;

// ... add some Obj's to 'mset'
mset->insert(Obj());
mset->insert(Obj());

// Do something desireable with the set ...
...

// All done.
// It's time to release the memory, but do NOT call any Obj destructors.
// The following line of code works exactly as intended.

boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(Obj const)>::purge_memory();

如果你进入purge_memory()最后一行代码的功能,你会看到fast_pool_allocator根据需要,很好地从系统中释放内存。 (没有调用 Obj 析构函数,因为如上面的链接问题所述,自定义分配器的工作只是分配和释放内存,调用构造函数或析构函数。)

它完全按照需要工作。太棒了!

但是,问题来了。如果更换 setmap , 然后尝试使用 boost::pool_allocator , 在调用 purge_memory()没有任何反应 !

typedef std::map<int, int, std::less<int>,
boost::fast_pool_allocator<std::pair<int const, int>>>
fast_map_obj;

// Ditto above: Deliberately do not use managed pointer
mast_map_obj * mmap = new fast_map_obj;

mmap[5] = Obj();
mmap[6] = Obj();

...

// Uh-oh. The following line of code DOES NOTHING, because I was using a map, not a set!

boost::singleton_pool<boost::fast_pool_allocator_tag,
sizeof(std::pair<int const, int>)>::purge_memory();

如前所述,最后一行代码什么都不做。原因是 boost::fast_pool_allocator是一个只响应对象并为其管理内存的单例 of a given size that is fixed at compile-time .这就是为什么 sizeof参数用于调用 purge_memory() 的表达式中- 它告诉 Boost Pool 代码 各种 不同 单例内存池要清除(假设请求的内存池由于先前已实例化而存在)。

不幸的是,因为选择要清除的内存池是大小相关的,关键管理内部对象的大小(即,在通过调用自定义分配的内存中创建和销毁)分配器)是已知的。可悲的是,对于 std::map , map 管理的内部对象的大小既不是 sizeof(Obj)也不sizeof(std::pair<int const, Obj>) .

我的问题是:如何严格、以跨平台的方式根据 C++11 标准工作,确定 std::map 内部管理的对象的大小?用于 boost::fast_pool_allocator

这可能吗?

最佳答案

问题是您不知道 set 用于节点的内部类型。

虽然我还没有弄清楚如何在编译时确定这一点,但您可以编写一个跟踪分配器,它在调用 allocate 时打印出 sizeof 节点类型,如:

template<typename T>
struct SimpleAllocator : private std::allocator<T>
{
using value_type = T;
using pointer = typename std::allocator<T>::pointer;
using size_type = typename std::allocator<T>::size_type;

pointer allocate(size_type n)
{
std::cout << "Allocator sizeof(T)==" << sizeof(T) << '\n';
return std::allocator<T>::allocate(n);
}

void deallocate(pointer p, size_type n)
{ return std::allocator<T>::deallocate(p, n); }
};

还有一个小测试程序(我正在测试一组整数):

std::set<int, std::less<int>, SimpleAllocator<int>> s;
s.insert(2);

在我的系统上,我得到以下输出:

Allocator sizeof(T)==32

关于c++ - 您如何确定由 'std::map' 创建的用于 'boost::pool_allocator' 的节点的大小(以跨平台方式)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22951378/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com