如何通过Arena allocation技术优化Protocol Buffer性能?
- 内容介绍
- 文章标签
- 相关推荐
本文共计666个文字,预计阅读时间需要3分钟。
%E2%80%9Cpb%E7%89%88%E6%9C%AC%E7%9A%84%E5%88%86%E9%85%8D%E5%99%A8%E5%9C%A8C++%E7%89%88%E6%9C%AC%E4%B8%AD%E5%8F%AF%E4%BB%A5%E5%8A%A0%E5%BC%BAmsg%E7%9A%84%E5%88%9B%E5%BB%BA%E6%95%88%E7%8E%87%EF%BC%8C%E4%BC%98%E5%8C%96%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E3%80%82%E9%9C%80%E8%A6%813%E4%BB%A5%E4%B8%8A%E3%80%82%E5%85%B3%E5%AF%BC%E6%80%9D%E6%83%B3%EF%BC%9A%E9%A2%84%E5%88%86%E5%88%86%E9%85%8D%EF%BC%8C%E5%8F%8D%E5%9B%9E%E6%94%B6%E6%9E%84%E5%BB%BA%E6%9E%84%EF%BC%8C%E5%87%8F%E5%B0%91%E5%86%85%E5%AD%98%E6%8B%9B%E5%85%A5%EF%BC%8C%E9%94%81%E5%AE%9A%E7%A2%8E%E7%89%87%E5%AF%B9%E8%B1%A1%E3%80%82%E2%80%9D
Protocol Buffer Arena allocation Arena是pb C++版本才有的特性。用来优化msg创建过程中对内存的使用。 pb版本需要3以上。 核心思想:预分配迟回收 好处:- 减少内存分配回收的成本
- 缓解碎片对象问题,主要是这个目的
- 提高了缓存行的命中率
option cc_enable_arenas = true;proto在生成时,会为message类生成出arena相关的函数。 import时,也需要带上该选项。 第一种 使用Arena
#include <google/protobuf/arena.h>
Arena arena;
MyMessage* msg= google::protobuf::Arena::CreateMessage<MyMessage>(&arena);
arena会分配一块内存使用,不够时采用倍增算法。
默认的初始分配大小是 256B ,最大分配大小是 8KB。每块最大8K。
当arena生命周期结束时,会自动回收内存块。
业务代码不要delete msg这个指针。
可以通过arena.SpaceAllocated() 接口获取实际分配内存的大小。
可以通过arena.SpaceUsed()接口获取实际使用内存的大小。
第二种 自定义内存块
char m_arena_block[1 * 1024 * 1024] = {};
ArenaOptions options;
options.initial_block = m_arena_block;
options.initial_block_size = sizeof(m_arena_block);
Arena arena(options);
auto* message = Arena::CreateMessage<MyMessage>(&arena)
第一种由于不知道需要分配多大的内存,所以还是有可能会调用new。
一次性分配1M,足矣。
对于string类型和bytes类型,arena特性不生效。
不过,在3.16.0中已经有了ArenaString的实现。
- Do out-of-line allocation and deallocation of string object in ArenaString.
本文共计666个文字,预计阅读时间需要3分钟。
%E2%80%9Cpb%E7%89%88%E6%9C%AC%E7%9A%84%E5%88%86%E9%85%8D%E5%99%A8%E5%9C%A8C++%E7%89%88%E6%9C%AC%E4%B8%AD%E5%8F%AF%E4%BB%A5%E5%8A%A0%E5%BC%BAmsg%E7%9A%84%E5%88%9B%E5%BB%BA%E6%95%88%E7%8E%87%EF%BC%8C%E4%BC%98%E5%8C%96%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E3%80%82%E9%9C%80%E8%A6%813%E4%BB%A5%E4%B8%8A%E3%80%82%E5%85%B3%E5%AF%BC%E6%80%9D%E6%83%B3%EF%BC%9A%E9%A2%84%E5%88%86%E5%88%86%E9%85%8D%EF%BC%8C%E5%8F%8D%E5%9B%9E%E6%94%B6%E6%9E%84%E5%BB%BA%E6%9E%84%EF%BC%8C%E5%87%8F%E5%B0%91%E5%86%85%E5%AD%98%E6%8B%9B%E5%85%A5%EF%BC%8C%E9%94%81%E5%AE%9A%E7%A2%8E%E7%89%87%E5%AF%B9%E8%B1%A1%E3%80%82%E2%80%9D
Protocol Buffer Arena allocation Arena是pb C++版本才有的特性。用来优化msg创建过程中对内存的使用。 pb版本需要3以上。 核心思想:预分配迟回收 好处:- 减少内存分配回收的成本
- 缓解碎片对象问题,主要是这个目的
- 提高了缓存行的命中率
option cc_enable_arenas = true;proto在生成时,会为message类生成出arena相关的函数。 import时,也需要带上该选项。 第一种 使用Arena
#include <google/protobuf/arena.h>
Arena arena;
MyMessage* msg= google::protobuf::Arena::CreateMessage<MyMessage>(&arena);
arena会分配一块内存使用,不够时采用倍增算法。
默认的初始分配大小是 256B ,最大分配大小是 8KB。每块最大8K。
当arena生命周期结束时,会自动回收内存块。
业务代码不要delete msg这个指针。
可以通过arena.SpaceAllocated() 接口获取实际分配内存的大小。
可以通过arena.SpaceUsed()接口获取实际使用内存的大小。
第二种 自定义内存块
char m_arena_block[1 * 1024 * 1024] = {};
ArenaOptions options;
options.initial_block = m_arena_block;
options.initial_block_size = sizeof(m_arena_block);
Arena arena(options);
auto* message = Arena::CreateMessage<MyMessage>(&arena)
第一种由于不知道需要分配多大的内存,所以还是有可能会调用new。
一次性分配1M,足矣。
对于string类型和bytes类型,arena特性不生效。
不过,在3.16.0中已经有了ArenaString的实现。
- Do out-of-line allocation and deallocation of string object in ArenaString.

