一. bpu内存以及相关接口
X3开发板中,芯片架构是Bernoulli2,在Bernoulli系列芯片的架构中,BPU和CPU共享同一个memory空间,如下图:

由于BPU需要使用物理空间连续的一块内存,因此runtime库提供专门的接口用来申请bpu内存,该接口返回申请到的memory地址(包括物理地址和虚拟地址),其中bpu虚拟地址可以被CPU直接读写,在后续执行BPU操作时也是传入虚拟地址。
且CPU与主存之间存在的cache会缓存数据,而BPU与主存之间没有cache,不过bpu的内存接口实现中也可以有cache,不过cacheable的bpu内存的cache与CPU cache机制不同,这种差别导致了cpu读写bpu内存时需要符合某种约束才行。具体来说,针对CPU读写 cacheable 的bpu内存,需要注意如下两项事项:
1. 对于CPU写bpu memory的场景,由于数据会缓存到cache中,导致memory中的数据是旧,这样BPU执行模型的时候取的数据就是错的。因此需要把cache中的数据flush到物理memory中,这时候就需要使用HB_SYS_BPU_MEM_CACHE_CLEAN参数调用HB_SYS_flushMemCache接口。
2. 对于CPU曾经读取过bpu memory的场景,数据有可能在之前被缓存到cache中。这时如果BPU写了这块memory,那么CPU在读取数据时仍然从
cache中读,这样就会导致CPU读到老旧的数据。这时候就需要把cache中读取得数据清理掉,需要使用HB_SYS_BPU_MEM_CACHE_INVALIDATE参数 调用HB_SYS_flushMemCache。
Tips:
对于模型的输入内存,可以不用设置cacheable,因为通常模型的input只会被读取一次。
对于模型的输出内存,则有必要设置cacheable,因为后处理会多次读取输出内存,这样能够利用cache缓存,提高访问速度。
以上便是开发板中内存相关的说明,runtime库提供如下接口来申请/刷新/释放bpu内存:
/*
* \brief alloc bpu memory for input and output of model,
* flag cachable indicates whether a cache is required.
*/
int HB_SYS_bpuMemAlloc(const char *name,
size_t alloc_mem_size,
bool cachable,
BPU_MEMORY_S *mem);
#define HB_SYS_MEM_CACHE_INVALIDATE (1) // flush memory to CPU
#define HB_SYS_MEM_CACHE_CLEAN (2) // flush CPU to memory
/*
* \brief flush cache with flag.
* HB_SYS_MEM_CACHE_INVALIDATE should be used after write,
* and HB_SYS_MEM_CACHE_CLEAN should be used before read .
*/
int HB_SYS_flushMemCache(const BPU_MEMORY_S *mem, int flag);
/*
* \brief query memory whether is cachable or not.
*/
int HB_SYS_isMemCachable(const BPU_MEMORY_S *mem);
/*
* \brief free bpu mem.
*/
int HB_SYS_bpuMemFree(BPU_MEMORY_S *mem);
具体的接口说明请参考开发包中的BPU SDK API文档,在此不再赘述。
二. 开发板内存说明
下面介绍开发板中,如何通过命令查看对应内存。

其中,reserved的45484K为系统所用,不可被应用所用。 cma-reserved为704512K,是cma内存;available为296528K,是CPU内存,为防止误解,记为available内存,这个类型内存也是kernel唯一可用的内存。
cpu使用内存时,会随机从cma内存和available内存申请。
然后通过free命令,获得结果如下图:

free命令输出,第二行的used的374180K,其中就包含了预留的272MB的cma内存,也就是cma_carveout_size大小的内存的使用情况会在used列中体现。
根据上面的分析,可以得到0922 x3镜像的内存示意图:

其中,cpu在进行memory malloc调用时,会随机从available和cam中分配内存(一半一半的概率)。
而bpu会优先从carve out分配内存,等到不够时,会从cma中分配,当cma中可用内存不够的情况下,kernel会将cma中被cpu占用的内存数据搬运到available,从而腾出cma空间给bpu使用,如果没有足够的available容纳腾出的数据,会报bpu分配失败的错误。
以上便是X3开发板的内存的一个大概介绍。
