不知道是不是借鉴了NCNN的代码,感觉差不多,具体可以参考大佬对于ncnn内存管理代码的解析,具体见参考资料[1],讲的非常清楚,这里只是做一个学习笔记。
具体代码为source/core/MNNMemoryUtils.c文件:
1、对齐内存分配接口:使用malloc函数
// 使用malloc函数来进行内存分配
// 传入待分配内存大小,及对齐内存大小
void *MNNMemoryAllocAlign(size_t size, size_t alignment)
首先,需要分配原始内存:
void **origin = (void **)malloc(size + sizeof(void *) + alignment);
这里多分配的sizeof(void*)用于保存对齐前内存地址;多分配的alignment为了保证对齐后,依然有size大小内存可用;转换成(void**)的原因,是为了后面origin+1直接跳过用于保存对齐前内存地址的预留内存。
然后,对齐分配的内存:
static inline void **alignPointer(void **ptr, size_t alignment);
对应实现部分为:
(void **)((intptr_t)((unsigned char *)ptr + alignment - 1) & -alignment);
后面加上alignment -1的目的有两个:
(1)防止刚好为alignment倍数的size不会被多算;
(2)防止不是alignment倍数的size不会被少算;
后面&-alignment是为了保证分配内存为alignment倍数:
如:alignment为16,对应原码为0001 0000(8位2进制), 0x0000 0000 0000 0010(64位16进制)
补码: 1111 0000(8位2进制),0xffff ffff ffff fff0(64位16进制)
求&操作就可以自然保证前者是16倍数。
2、对齐内存分配接口:使用calloc函数
void *MNNMemoryCallocAlign(size_t size, size_t alignment)
实现过程差不多。
3、内存释放接口:
void MNNMemoryFreeAlign(void *aligned)
直接看代码注解吧:
// 释放掉对齐内存
void MNNMemoryFreeAlign(void *aligned) {
#ifdef MNN_DEBUG_MEMORY
free(aligned);
#else
if (aligned) {
// aligned - 1就是未对齐前内存地址
void *origin = ((void **)aligned)[-1];
// 释放掉对应内存
free(origin);
}
#endif
}
打完收工~
参考资料:
来源:CSDN
作者:Mirror_Yu_Chen
链接:https://blog.csdn.net/sinat_31425585/article/details/104092018