使用内存池效率反而降低了??

hypeaches 2015-11-06 09:18:06
Asio大量使用回调函数,而回调函数其实都很小的,大概只有几十到一百多字节,大量在堆上分配内存保存回调很容易产生内存碎片。所以根据boost文档,建立了一个自定义的回调内存分配器

class handler_allocator
{
public:
//分配与回收内存相关的操作
private:
bool in_use_;
char storage_[1024];
};
template <typename Handler>
class custom_alloc_handler
{
public:
//管理内存;进行回调相关
private:
handler_allocator& allocator_;
Handler handler_;
};
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator& a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
}

所有通过boost::bind构造的回调函数都用make_custom_alloc_handler包一下,同时使用预先创建的handler_allocator,从而消除运行时在堆上分配内存。
测试方法为

int Run(int run_times)
{
handler_allocator* ha = new handler_allocator[run_times];
boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::local_time();
for (int i = 0; i < run_times; ++i)
{
sck_.async_read_some(boost::asio::buffer(buffer_, sizeof(buffer_)), strand_.wrap(
make_custom_alloc_handler(ha[i], boost::bind(&TestAllocator::RunHandler, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))));
/*sck_.async_read_some(boost::asio::buffer(buffer_, sizeof(buffer_)), boost::bind(&TestAllocator::RunHandler,
this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));*/
}
boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time();
return (t2 - t1).total_microseconds();
}
int main(int argc, char* argv[])
{
int run_times = 1000000;
int ret = 0;
for (int i = 0; i < 20; ++i)
{
ret += Run(run_times);
}
cout << "basic: " << (ret / 20) << endl;
return 0;
}

分别对用make_custom_alloc_handler和直接用boost::bind进行了测试,结果很奇怪,当run_times比较小时(1和100),make_custom_alloc_handler方式很快,而run_times取值为1000000时,直接boost::bind反而更快了。为什么啊?以下是运行结果(单位:微秒)
run_times make_custom_alloc_handler boost::bind
1 0 700
100 0 50
1000000 437750 405974
...全文
248 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-11-09
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
paschen 版主 2015-11-09
  • 打赏
  • 举报
回复
引用 5 楼 hypeaches 的回复:
[quote=引用 4 楼 paschen的回复:][quote=引用 3 楼 hypeaches 的回复:] [quote=引用 1 楼 paschen的回复:]避免内存碎片也是要付出代价的,boost内存池不是一定是最优的选择
不是boost内存池,我只是奇怪为什么循环次数多了直接bind效率会更好[/quote] 管理内存池也是有开销的[/quote] 说是内存池,其实只是预先分配了一块比较大的内存(1KB),需要时直接拿过来用,没有什么维护的开销。然而奇怪的是,循环次数少的时候,预分配内存方式跑的快,循环次数多了预分配内存反而跑的慢了,这挺奇怪的啊[/quote] 不全是这样,你看C++STL中的空间配置器的实现,他里面有链表记录分配的内存,分成两级
hypeaches 2015-11-09
  • 打赏
  • 举报
回复
引用 4 楼 paschen的回复:
[quote=引用 3 楼 hypeaches 的回复:] [quote=引用 1 楼 paschen的回复:]避免内存碎片也是要付出代价的,boost内存池不是一定是最优的选择
不是boost内存池,我只是奇怪为什么循环次数多了直接bind效率会更好[/quote] 管理内存池也是有开销的[/quote] 说是内存池,其实只是预先分配了一块比较大的内存(1KB),需要时直接拿过来用,没有什么维护的开销。然而奇怪的是,循环次数少的时候,预分配内存方式跑的快,循环次数多了预分配内存反而跑的慢了,这挺奇怪的啊
hypeaches 2015-11-07
  • 打赏
  • 举报
回复
引用 1 楼 paschen的回复:
避免内存碎片也是要付出代价的,boost内存池不是一定是最优的选择
不是boost内存池,我只是奇怪为什么循环次数多了直接bind效率会更好
paschen 版主 2015-11-07
  • 打赏
  • 举报
回复
引用 3 楼 hypeaches 的回复:
[quote=引用 1 楼 paschen的回复:]避免内存碎片也是要付出代价的,boost内存池不是一定是最优的选择
不是boost内存池,我只是奇怪为什么循环次数多了直接bind效率会更好[/quote] 管理内存池也是有开销的
yshuise 2015-11-06
  • 打赏
  • 举报
回复
为什么不用boost的内存池,记得要手动释放哦!
paschen 版主 2015-11-06
  • 打赏
  • 举报
回复
避免内存碎片也是要付出代价的,boost内存池不是一定是最优的选择

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧