SystemC / TLM(C ++)共享内存池;静态成员,静态方法,单例或?

时间:2015-09-30 17:27:37

标签: c++ memory-management coding-style singleton systemc

上下文 我正在编写一个在TLM模型之间使用的特定通信协议(用SystemC描述的HW块,因此是C ++)。 TLM概念并不重要,只需注意通过分配在HW块的这些C ++模型之间传递的对象(通用有效负载(gps))来模仿这种通信。

目的: 与协议一起,我想提供一个能够有效处理gps的内存管理器;这非常重要,因为在一次模拟中,大量的gps被构造,使用和销毁,这可能会减慢很多事情。 我的目标也是创造一些简单的东西,让其他人可以毫不费力地使用。

的问题:

  1. 我遇到的第一个问题是为与该协议通信的所有块创建单个共享池。我想过在mm类中创建一个静态成员,但后来我才意识到:

    • 静态成员需要cpp中的定义。这使得mm类的使用不那么直观(不同的人使用它,有些人会忘记这样做),我宁愿避免这样做。
    • 根据cpp文件中的静态变量定义的位置(以及其中?),池可能没有润湿需要初始化的参数(即创建的mm实例的数量)。
  2. 第二个问题类似于第一个问题。我想计算实例的数量,因此我需要创建一个共享计数器来代替池,然后由池使用它来初始化自己。同样,我想避免在cpp文件中使用静态变量定义并保证初始化顺序。

  3. 我主要考虑过:

    • 静态成员(由于上述原因而被丢弃)
    • 单身人士(因为我不需要为游泳池创建一个完整的类,让其他人和单个实例可见)所以放弃了
    • 静态方法(我最终选择的方法,离完整的Singleton不远)

    这是我制作的代码(仅包括相关部分):

    /**
    * Helper class to count another class' number of instances.
    */
    class counter {
    public:
      // Constructor
      counter() : count(0) {}
    
      //Destructor
      virtual ~counter() {}
    
    private:
      unsigned int count;
    
    public:
      unsigned int get_count() {return count;}
      void incr_count() {count++;}
      void decr_count() {count--;}
    };
    
    
    template <unsigned int MAX = 1>
    class mm: public tlm::tlm_mm_interface {
    //////////////////////////////TYPEDEFS AND ENUMS/////////////////////////////
    public:
      typedef tlm::tlm_generic_payload gp_t;
    
    ///////////////////////////CLASS (CON/DE)STRUCTOR////////////////////////////
    public:
      // Constructor
      mm() {inst_count().incr_count();}
    
      // Copy constructor
      mm(const mm&) {inst_count().incr_count();}
    
      // Destructor
      virtual ~mm() {}  // no need to decrease instance count in our case
    
    ////////////////////////////////CLASS METHODS////////////////////////////////
    public:
      // Counter for number of isntances.
      static counter& inst_count() {
        static counter cnt;
        return cnt;
      }
    
      /* This pattern makes sure that:
      -- 1. The pool is created only when the first alloc appears
      -- 2. All instances of mm have been already created (known instance sequence)
      -- 3. Only one pool exists */
      static boost::object_pool<gp_t>& get_pool() {
        static boost::object_pool<gp_t> p(
          mm<MAX>::inst_count().get_count() * MAX / 2, // creation size
          mm<MAX>::inst_count().get_count() * MAX      // max size used
        );
        return p;
      }
    
      // Allocate
      virtual gp_t* allocate() {
        //...
        return gp;
      }
    
      // Free the generic payload and data_ptr
      virtual void free(gp_t* gp) {
         //...
         get_pool().destroy(gp);
      }
    }
    

    现在,启动程序块类头应该有一个成员:

    mm m_mm;
    

    启动器块类cpp应该使用它:

    tlm_generic_payload* gp;
    gp = m_mm.allocate();
    //...
    m_mm.free(gp); // In truth this is called by gp->release()...
                   // ...not important here
    

    拥有电子硬件背景,我主要是尝试改进编码风格,学习新方法并优化速度/内存分配。

    有没有更好的方法来实现这一目标?特别是考虑到我的怀疑:

    • 在我看来,将计数器封装在一个类中是一个非最佳的解决方法,将它放在静态方法中本地(但是静态),然后对池执行相同的操作。
    • 即使SystemC“模拟内核”是单线程的,我也需要考虑一个多线程案例...我不确定这两种静态方法之间的关系是否安全,即使你是独立的,它们应该是安全的...... C ++ 03 g ++添加了代码以保证它和C ++ 11:
      

    §6.7[stmt.dcl] p4如果控制在初始化变量时同时进入声明,则并发执行应等待初始化完成。

    提前致谢。

0 个答案:

没有答案