你如何确定节点由'的std ::图“(在跨平台的方式)创建为使用”的boost :: pool_allocator“的大小? [英] How do you determine the size of the nodes created by a 'std::map' for use with 'boost::pool_allocator' (in a cross-platform way)?

查看:119
本文介绍了你如何确定节点由'的std ::图“(在跨平台的方式)创建为使用”的boost :: pool_allocator“的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新

每评论,答案,更多的研究,我得出的结论是,有典型之间的设置地图<无差异/ code>在节点开销方面。我下面的问题是真的:

Per comments, answer, and additional research, I have come to the conclusion that there is typically no difference between a set and a map in terms of node overhead. My question that follows is really:

你如何确定的使用方便节点开销
  的boost :: pool_allocator 作为一个自定义分配器?

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

和,进一步的更新:节点开销可能永远不会超过4个三分球的尺寸比较多,所以只是吹扫的sizeof Boost的游泳池(T) 的sizeof(T)+的sizeof(INT)的sizeof(T)+ 2 * sizeof的(INT)的sizeof(T)+ 3 * sizeof的(INT)的sizeof(T)+ 4 *的sizeof(INT)(或的int64_t 64位系统)应罚款。这就是我实际上做,和它的作品。

And, a further update: The node overhead is probably never going to be more than the size of 4 pointers, so just purging the Boost Pool for sizeof(T), sizeof(T)+sizeof(int), sizeof(T) + 2*sizeof(int), sizeof(T) + 3*sizeof(int) and sizeof(T) + 4*sizeof(int) (or int64_t for 64-bit systems) should be fine. That is what I am actually doing, and it works.

我想用一个提升内存池通过避免调用这些对象的析构函数,而是释放在含有以每幅许多情况下,单一的大片内存来管理数百万计的微小,相同大小的物体。

I want to use a boost memory pool to manage tens of millions of tiny, identically-sized objects by avoiding calls to the destructors of these objects, and instead freeing the memory in single swaths containing many instances per swath.

我发布<一个href=\"http://stackoverflow.com/questions/22942255/how-to-$p$pvent-destructors-from-being-called-on-objects-managed-by-boostfast-p\">another问题这个问题,而这个问题的答案使我明白,这个问题我的真正的需要回答的是一个我是问在这里。

I posted another question about this issue, and the answer to that question has led me to understand that the question I really need to answer is the one I am asking here.

考虑以下code:

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() code的最后一行的功能,您将看到 fast_pool_allocator 很好地前进到释放从系统存储器中,正如所希望的。 (否的OBJ 析构函数被调用,因为作为链接的问题上面提到,自定义分配器的工作就是只是以分配和释放内存, 不可以调用构造函数和析构函数)。

If you step into the purge_memory() function of the last line of code, you will see that the fast_pool_allocator nicely proceeds to free the memory from the system, just as desired. (No Obj destructors are called, because as noted in the linked question above, the job of the custom allocator is just to allocate and free memory, not to call constructors or destructors.)

它根据需要pcisely工作$ P $。太棒了!

It works precisely as desired. Great!

然而,这就是问题所在。如果更换设置地图,然后尝试使用的boost :: pool_allocator 什么也没有发生在调用 purge_memory()

However, here is the problem. If you replace the set with a map, and then try to use the boost::pool_allocator, nothing happens in the call to 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();

如前所述,code最后行什么也不做。其原因是,在的boost :: fast_pool_allocator 是一个单只响应,并管理内存,对象<一个href=\"http://www.boost.org/doc/libs/1_55_0/libs/pool/doc/html/boost_pool/pool/pooling.html#boost_pool.pool.pooling.simple\"被固定在编译时的给定大小的相对=nofollow>。这就是为什么的sizeof 参数在调用 purge_memory()除权pression使用 - 它告诉升压池code的其中各种的不同的的单身内存池的清洗(假设请求的一个存在由于previously已实例化)。

As noted, the last line of code does nothing. The reason is that the boost::fast_pool_allocator is a singleton that only responds to, and manages memory for, objects of a given size that is fixed at compile-time. This is why the sizeof argument is used in the expression that calls purge_memory() - it tells the Boost Pool code which of the various different singleton memory pools to purge (assuming the requested one exists due to previously having been instantiated).

不幸的是,因为选择要被清除的存储器池大小依赖性,它是<青霉>临界的该内部对象的尺寸管理(即创建,并在通过调用定制分配的内存被破坏分配器)是已知的。可悲的是,为的std ::地图,由地图管理的内部对象的大小既不是的sizeof(OBJ)也不的sizeof(性病::对&LT; INT常量,OBJ&GT;)。

Unfortunately, because the memory pool selected to be purged is size-dependent, it is critical that the size of the internal objects managed (i.e., created and destroyed in memory allocated via calls to the custom allocator) is known. Sadly, for std::map, the size of the internal objects managed by the map is neither sizeof(Obj) nor sizeof(std::pair<int const, Obj>).

我的问题是:你如何严格,并于根据C ++ 11标准工作的一个跨平台的方式,确定由 STD内部管理对象的大小::地图为使用的boost :: fast_pool_allocator

My question is: How do you rigorously, and in a cross-platform way that works according to the C++11 standard, determine the size of the objects internally managed by std::map for use with boost::fast_pool_allocator?

这甚至可能吗?

推荐答案

有没有一个真正的跨平台的方式来演绎你所追求的,因为每个地图的实现是各有各的不幸,但一般是地图将在池分配节点。

There isn't a truly cross platform way to deduce what you are after, since every map implementation is unhappy in its own way, but generally it is the map node that will be allocated in the pool.

这寻找标准库的不同实现不同的,所以你code将不得不 #IFDEF -ed不同版本。随着脆弱的地方警告,这两个是主要的的G ++ /铛++ / MSC编译器和库的std:

This looks different for the different implementations of the standard library, so you code will have to #ifdef-ed for the different versions. With a fragility warning in place, here are the main ones for the g++/clang++/msc compilers and their std libs:

// libstdc++
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(std::_Rb_tree_node<fast_map_obj::value_type>)>::purge_memory()

// libc++
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(std::__tree_node<fast_map_obj::value_type, void*>)>::purge_memory()

// msvc 2013 (incl. nov ctp)
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(fast_map_obj::_Node)>::purge_memory()

下面是找到必要的定义了一些有用的链接:结果

Here are some useful links for finding the necessary defines:

http://www.boost.org/doc/libs / 1_55_0 /升压/配置/编译器/

http://sourceforge.net/p/$p$pdef/wiki /编译器/

这篇关于你如何确定节点由'的std ::图“(在跨平台的方式)创建为使用”的boost :: pool_allocator“的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆