Protocol Buffer優化技術-Arena allocation


Protocol Buffer Arena allocation
Arena是pb C++版本才有的特性。用來優化msg創建過程中對內存的使用。
pb版本需要3以上。
 
核心思想:預分配遲回收
好處:
  1. 減少內存分配回收的成本
  2. 緩解碎片對象問題,主要是這個目的
  3. 提高了緩存行的命中率

如何使用

需要在.proto文件中加上下面這行
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.

使用粒度

在大多數服務使用場景中,“arena-per-request”模式表現良好。
建議使用arena,大內存場景下,性能有顯著提高。
 
https://github.com/protocolbuffers/protobuf/issues/4327
https://github.com/protocolbuffers/protobuf/tree/3.16.x/src/google/protobuf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM