分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

cnstream 源码学习笔记(-):Pipeline的IdxManager类 wulingchao2020-08-13 10:38:41 回复 查看 CNStream
cnstream 源码学习笔记(-):Pipeline的IdxManager类
分享到:

基于samples/example/example.cpp代码


我们创建一个pipeline流水线后里面维持着一些Module和stream,如何保存他们之间的独立性,这里利用到了Pipeline类里面的一个私有成员(测试时公有)IdxManager类指针,它指向一个IdxManager类。


下面展开IdxManager类,它是一个在pipeline里面创建、管理、销毁Moudle和stream的idx的类,也就是说它能保证idx的唯一性:

class IdxManager { 
public:
  IdxManager() = default;
  IdxManager(const IdxManager&) = delete;
  IdxManager& operator=(const IdxManager&) = delete;
  uint32_t GetStreamIndex(const std::string& stream_id);  
  // 本质的实现是从0到Max查找,如果没有在stream_bitset里面的就可以分配为index。  
  void ReturnStreamIndex(const std::string& stream_id);   
  // 这里返回的查找对应stream_bitset和stream_idx_map会将查找的复原,这个位置又空出来
  size_t GetModuleIdx();                                  
  // module的index使用的是掩码的方法  
  void ReturnModuleIdx(size_t id_);                       
  // module_id_mask_ &= ~(1 << id_);把当前为变0
  
private:
  SpinLock id_lock;
  std::unordered_map<std::string, uint32_t> stream_idx_map;
  std::bitset<MAX_STREAM_NUM> stream_bitset;             
  // 所有分配stream的index都在这里
  uint64_t module_id_mask_ = 0;                
  // 所有分配的module的index都在这,根据这个方法,module最大支持64个
};  // class IdxManager

1、stream分配idx的方法:

利用一个bitset来存储可以节省空间,每个元素占1bit,每个元素存储0或者1。我们通过bitset的索引找到元素值,如我们找bitset的第10个元素,发现值为0,说明10这个位置没有使用。那么10就可以作为stream的idx进行分配,同时只要把bitset[10]置为1就行。空间回收也是类似。


2、module分配idx的方法分开表示如下:位移表示为 ((uint64_t)1 << i))

  • mask=0000  位移=0001,那么可以分配第一个idx为0。mask=0001

  • mask=0001  位移=0001,跳过;mask=0001  位移=0010,可以分配第二个idx为1。mask=0011

  for (size_t i = 0; i < GetMaxModuleNumber(); i++) {    
    if (!(module_id_mask_ & ((uint64_t)1 << i))) {
       module_id_mask_ |= (uint64_t)1 << i;
       return i;
    }

mask的中间状态 mask = 00000000001111111,假如要找2这个idx是否分配,对1进行左移2,得到000...000100,将它与mask进行与操作,如果结果为1,则2这个idx已经分配;如果为0,则2这个idx未分配。

IdxManager::ReturnModuleIdx(size_t id_)这个方法用了 module_id_mask_ &= ~(1 << id_) ,个人理解是为了把当前id_这个idx返回给索引池,因此调用这个函数之后module_id_mask_在id_这个位置为0。


对于IdxManager类的大致用法目前探索到这里,希望大佬们有时间能分享一下漏掉的知识点。


版权所有 © 2019 寒武纪 Cambricon 备案/许可证号:京ICP备17003415
关闭