Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 优先级队列中的池内存分配_C++_Priority Queue_Event Driven - Fatal编程技术网

C++ 优先级队列中的池内存分配

C++ 优先级队列中的池内存分配,c++,priority-queue,event-driven,C++,Priority Queue,Event Driven,我正在编写一个基于事件的模拟器,其中每个事件调用一个处理函数(节点),该函数可以生成新事件,等等。 时间戳与每个事件相关联,它们需要按照时间的增加顺序进行处理(但事件不一定按照该顺序创建)。为此,我使用了一个简单的优先级队列,其中Event是一个类,包含指向必须调用的处理节点的指针和时间戳 因此,一切正常,但我每秒分配和释放数百万个事件,这显然限制了我的模拟器的速度(大约30%的执行时间被事件对象的内存分配和释放占用) 我发现这个问题: 看起来我可以从对象池中受益匪浅。尽管我已经看到Boost提

我正在编写一个基于事件的模拟器,其中每个事件调用一个处理函数(节点),该函数可以生成新事件,等等。 时间戳与每个事件相关联,它们需要按照时间的增加顺序进行处理(但事件不一定按照该顺序创建)。为此,我使用了一个简单的
优先级队列
,其中Event是一个类,包含指向必须调用的处理节点的指针和时间戳

因此,一切正常,但我每秒分配和释放数百万个事件,这显然限制了我的模拟器的速度(大约30%的执行时间被事件对象的内存分配和释放占用)

我发现这个问题: 看起来我可以从对象池中受益匪浅。尽管我已经看到Boost提供了一些方法来实现这一点,但我不确定这是否适用于在
优先级队列中实现池。当涉及到自定义内存分配时,我真的很迷茫

所以我的问题是:在我的
优先级队列中使用对象池是否实用/有益,如果是,是否有一种简单的方法可以做到这一点,最好是在第一次不立即依赖Boost的情况下使用一些代码示例(或至少是一个起点)

实际上,也欢迎一些参考文献来了解池分配的工作原理


谢谢。

我想你说的是
std::priority\u queue
。是的,您可以提供自己的分配方案

STL优先级队列是根据另一个容器(默认情况下,
std::vector
我认为)实现的,该容器可以指定为模板参数。然后,您可以使用分配器(以通常的STL方式)参数化另一个容器


它仍然是分配器的一个实现。如果你不想自己做,我敢肯定你可以找到很多(比如你提到Boost)。我曾经用过一些小的修改。它做得很好…

我想你说的是
std::priority\u queue
。是的,您可以提供自己的分配方案

STL优先级队列是根据另一个容器(默认情况下,
std::vector
我认为)实现的,该容器可以指定为模板参数。然后,您可以使用分配器(以通常的STL方式)参数化另一个容器


它仍然是分配器的一个实现。如果你不想自己做,我敢肯定你可以找到很多(比如你提到Boost)。我曾经用过一些小的修改。它做得很好…

一个快速而肮脏的对象池示例

EventPool.h

#include <stack>
class Event;

class EventPool
{
 public:
   explicit EventPool(const unsigned int initSize = 0);
   ~EventPool();
   Event* getEvent();
   void returnEvent(Event* e);
 private:
   std::stack<Event*> pool_;
};
#包括
班级活动;
类事件池
{
公众:
显式事件池(const unsigned int initSize=0);
~EventPool();
Event*getEvent();
无效返回事件(事件*e);
私人:
std::堆栈池;
};
EventPool.cxx

#include <Event.h>
#include <EventPool.h>

EventPool::EventPool(const unsigned int initSize)
{
   for(unsigned int i = 0; i < initSize; ++i)
   {
      pool_.push(new Event());
   }
}

EventPool::~EventPool()
{
   while(!pool_.empty())
   {
      delete pool_.top();
      pool_.pop();
   }
}

Event* EventPool::getEvent()
{
   if(pool_.empty())
   {
      return new Event();
   }
   Event* returnValue = pool_.top();
   pool_.pop();
   return returnValue;
}

void EventPool::returnEventToPool(Event* e)
{
   pool_.push(e);
}
#包括
#包括
EventPool::EventPool(常量unsigned int initSize)
{
for(无符号整数i=0;i

通过这样做,您可以允许池控制自身的大小。当另一个对象抓取一个事件时,由抓取器返回或删除该事件。

对象池的快速脏示例

EventPool.h

#include <stack>
class Event;

class EventPool
{
 public:
   explicit EventPool(const unsigned int initSize = 0);
   ~EventPool();
   Event* getEvent();
   void returnEvent(Event* e);
 private:
   std::stack<Event*> pool_;
};
#包括
班级活动;
类事件池
{
公众:
显式事件池(const unsigned int initSize=0);
~EventPool();
Event*getEvent();
无效返回事件(事件*e);
私人:
std::堆栈池;
};
EventPool.cxx

#include <Event.h>
#include <EventPool.h>

EventPool::EventPool(const unsigned int initSize)
{
   for(unsigned int i = 0; i < initSize; ++i)
   {
      pool_.push(new Event());
   }
}

EventPool::~EventPool()
{
   while(!pool_.empty())
   {
      delete pool_.top();
      pool_.pop();
   }
}

Event* EventPool::getEvent()
{
   if(pool_.empty())
   {
      return new Event();
   }
   Event* returnValue = pool_.top();
   pool_.pop();
   return returnValue;
}

void EventPool::returnEventToPool(Event* e)
{
   pool_.push(e);
}
#包括
#包括
EventPool::EventPool(常量unsigned int initSize)
{
for(无符号整数i=0;i

通过这样做,您可以允许池控制自身的大小。当另一个对象抓取事件时,由抓取器返回或删除该事件。

是的,这样做非常实用。请记住,内置的动态分配器是为满足各种目的而构建的,即它必须以任何顺序分配和取消分配任何大小、任何类型的数据。如果您事先知道这是不必要的,您可以在很大程度上降低分配和取消分配的复杂性


在这种情况下,您预先知道您总是分配一个事件。这就使对象池成为您理想的分配器。在
std::priority_队列
中添加一个定制分配器(设计用于STL对象)是非常实用的—该队列在内部容器上模板化,默认为
std::vector
,您可以在
std::vector
中显式指定定制分配器。结果应该是非常实用且易于使用的-自定义内存分配器(如对象池一样基于值)(据我所知)非常容易插入。

是的,这样做非常实用。请记住,内置的动态分配器对于每个pur都是以尽可能快的速度构建的