我在多线程应用程序中为std::list对象使用池化内存分配器时遇到了一些问题。
我关注的代码部分独立运行每个线程函数(即线程之间没有通信或同步),因此我想为每个线程设置单独的内存池,其中每个内存池都不是线程安全的(因此速度很快)。
我尝试使用共享线程安全的单例内存池,发现性能很差,不出所料。
这是我尝试做的这类事情的一个高度简化的版本。很多代码都是以伪代码的方式包含的,如果让人感到困惑,很抱歉。
/* The thread functor - one instance of MAKE_QUADTREE created for each thread
*/
class make_quadtree
{
private:
/* A non-thread-safe memory pool for int linked list items, let's say that it's
* something along the lines of BOOST::OBJECT_POOL
*/
pooled_allocator<int> item_pool;
/* The problem! - a local class that would be constructed within each std::list as the
* allocator but really just delegates to ITEM_POOL
*/
class local_alloc
{
public :
//!! I understand that I can't access ITEM_POOL from within a nested class like
//!! this, that's really my question - can I get something along these lines to
//!! work??
pointer allocate (size_t n) { return ( item_pool.allocate(n) ); }
};
public :
make_quadtree (): item_pool() // only construct 1 instance of ITEM_POOL per
// MAKE_QUADTREE object
{
/* The kind of data structures - vectors of linked lists
* The idea is that all of the linked lists should share a local pooled allocator
*/
std::vector<std::list<int, local_alloc>> lists;
/* The actual operations - too complicated to show, but in general:
*
* - The vector LISTS is grown as a quadtree is built, it's size is the number of
* quadtree "boxes"
*
* - Each element of LISTS (each linked list) represents the ID's of items
* contained within each quadtree box (say they're xy points), as the quadtree
* is grown a lot of ID pop/push-ing between lists occurs, hence the memory pool
* is important for performance
*/
}
};所以实际上我的问题是,我希望每个线程functor实例有一个内存池实例,但是在每个线程functor中,在多个std::list对象之间共享内存池。
发布于 2011-01-07 08:59:56
为什么不直接构造一个引用make_quadtree的local_alloc实例呢?
发布于 2011-01-07 09:26:33
线程特定的分配器是一个相当大的挑战。
我花了一些时间寻找“现成”的线程专用分配器。我找到的最好的是hoard ( hoard.org )。这提供了显著的性能改进,但是hoard有一些严重的缺点。
在testing
所以我决定基于boost::pool和boost::threadspecificptr来使用我自己的线程专用内存分配器。这需要少量的非常高级的C++代码,但现在看起来运行良好。
我已经看了好几个月了,但也许我可以再看一次。
你的评论说你正在寻找一个线程特定的而不是一个线程安全的分配器。这是有意义的,因为如果分配器是特定于线程的,那么它就不需要是线程安全的。然而,根据我的经验,只要不发生争用,保持线程安全的额外负担是微不足道的。
然而,所有这些理论都很有趣,但我认为我们应该转向实际。我认为我们需要一个小型的、带仪表的独立程序来演示您需要解决的问题。我遇到了std::multiset分配听起来非常类似的问题,并编写了你可以在这里看到的程序:Parallel reads from STL containers
如果你能写一些类似的东西,显示你的问题,那么我可以检查我的线程特定的内存分配器是否可以在你的情况下更好地应用。
https://stackoverflow.com/questions/4621547
复制相似问题