zl程序教程

您现在的位置是:首页 >  其他

当前栏目

vppinfra--memory pool

2023-02-19 12:21:05 时间

内存池简介

内存池(memory pool)是在当前系统中请求一大片连续的内存空间,然后在运行时根据实际需要分配出去的技术。使用内存池的优点如下: 1、速度远比 malloc/free 快,因为减少了系统调用的次数,特别是频繁申请/释放内存块的情况。 2、避免了频繁申请/释放内存之后,系统的大量内存碎片。 3、节省空间

内存池分类

根据分配内存池的大小,内存池可以分为两类: 1、固定大小内存池,对应vpp的pool内存池。 2、可变长内存池, 对应vpp的heap内存池。

Pool 基本结构及内存分布介绍

 固定大小的内存池,基于vector和位图实现的。下面pool header结构如下:
typedef struct
{
  /** 内存池中内存块使用状态的bitmap,未使用free状态置位1,已使用置位0*/
  uword *free_bitmap;
  /**vector结构,保存已经释放数据块索引 */
  u32 *free_indices;
  /* 以下字段是为固定大小的预分配池设置的 */
  /** 当前内存池最多支持元素个数 */
  u32 max_elts;
  /** 内存池首地址 */
  u8 *mmap_base;
  u64 mmap_size;/*当前内存池占用内存的总大小*/
} pool_header_t;

vpp pool 分为两种: 一种是内存池的元素个数是无限制的,支持动态扩展。内存地址是在全局mheap上申请的。优点:按需分配,节省内存。

注意:从pool内存池中get操作可能会存在内存不足的情况,会从mheap堆上重新申请一块大内存,旧的内存将被释放;这样P指向的地址就发生的变更,需要重新进行赋值。一般在初始化时申请足够的内存池大小。

一种是内存池的元素个数是受限的,不支持动态扩展。内存地址是通过mmap直接映射的系统内存。缺点:不支持动态扩展,超过内存池最大元素大小时报错;内存池利用率低时,浪费内存。

/** initialize a fixed-size, preallocated pool */
#define pool_init_fixed(pool,max_elts)                  \
{                                                       \
  _pool_init_fixed((void **)&(pool),sizeof(pool[0]),max_elts);  \
}

内存池相关操作函数

下面函数是获取pool空闲内存单元的数量,但是vec_capacity计算的剩余字节数目,这个函数是存在问题的(vpp项目未发现有调用的地方)。如果想使用需要修改一下。

/** Queries whether pool has at least N_FREE free elements. */
always_inline uword
pool_free_elts (void *v)
{
  pool_header_t *p = pool_header (v);
  uword n_free = 0;

  if (v)
    {
      /*计算pool池剩余数量*/
      n_free += vec_len (p->free_indices);
      /* Space left at end of vector? 计算剩余字节大小*/
      n_free += vec_capacity (v, sizeof (p[0])) - vec_len (v);
    }
  return n_free;
}

pool相关操作函数如下:

总结:

本文简单介绍vpp基础库中pool内存池基本内存分布及操作函数。pool结构是经常使用的,是通过连续数组方式实现的,也是比较高效的原因。