MNN框架学习(三):内存管理

六月ゝ 毕业季﹏ 提交于 2020-01-27 15:07:07

不知道是不是借鉴了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
}

打完收工~

参考资料:

[1] https://www.jianshu.com/p/9c58dd414e5f

[2] https://github.com/alibaba/MNN

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!