重庆知名做网站的公司北京移动端网站优化
web/
2025/10/3 15:43:04/
文章来源:
重庆知名做网站的公司,北京移动端网站优化,杰诚网站建设,成都九度装饰设计有限公司参考链接
FFmpeg源代码简单分析#xff1a;内存的分配和释放#xff08;av_malloc()、av_free()等#xff09;_雷霄骅的博客-CSDN博客_av_malloc
内容介绍
内存操作的常见函数位于libavutil\mem.c中本文记录最常使用的几个函数#xff1a; av_malloc()av_realloc()av_mal…参考链接
FFmpeg源代码简单分析内存的分配和释放av_malloc()、av_free()等_雷霄骅的博客-CSDN博客_av_malloc
内容介绍
内存操作的常见函数位于libavutil\mem.c中本文记录最常使用的几个函数 av_malloc()av_realloc()av_mallocz()av_calloc()av_free()av_freep()
代码
av_malloc()
void *av_malloc(size_t size)
{void *ptr NULL;if (size atomic_load_explicit(max_alloc_size, memory_order_relaxed))return NULL;#if HAVE_POSIX_MEMALIGNif (size) //OS X on SDK 10.6 has a broken posix_memalign implementationif (posix_memalign(ptr, ALIGN, size))ptr NULL;
#elif HAVE_ALIGNED_MALLOCptr _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN
#ifndef __DJGPP__ptr memalign(ALIGN, size);
#elseptr memalign(size, ALIGN);
#endif/* Why 64?* Indeed, we should align it:* on 4 for 386* on 16 for 486* on 32 for 586, PPro - K6-III* on 64 for K7 (maybe for P3 too).* Because L1 and L2 caches are aligned on those values.* But I dont want to code such logic here!*//* Why 32?* For AVX ASM. SSE / NEON needs only 16.* Why not larger? Because I did not see a difference in benchmarks ...*//* benchmarks with P3* memalign(64) 1 3071, 3051, 3032* memalign(64) 2 3051, 3032, 3041* memalign(64) 4 2911, 2896, 2915* memalign(64) 8 2545, 2554, 2550* memalign(64) 16 2543, 2572, 2563* memalign(64) 32 2546, 2545, 2571* memalign(64) 64 2570, 2533, 2558** BTW, malloc seems to do 8-byte alignment by default here.*/
#elseptr malloc(size);
#endifif(!ptr !size) {size 1;ptr av_malloc(1);}
#if CONFIG_MEMORY_POISONINGif (ptr)memset(ptr, FF_MEMORY_POISON, size);
#endifreturn ptr;
}
如果不考虑上述代码中的一大堆宏定义av_malloc()的代码可以简化成如下形式可以看出此时的av_malloc()就是简单的封装了系统函数malloc()并做了一些错误检查工作
void *av_malloc(size_t size)
{void *ptr NULL;/* lets disallow possibly ambiguous cases */if (size (max_alloc_size - 32))return NULL;ptr malloc(size);if(!ptr !size) {size 1;ptr av_malloc(1);}return ptr;
}
av_realloc()
void *av_realloc(void *ptr, size_t size)
{void *ret;if (size atomic_load_explicit(max_alloc_size, memory_order_relaxed))return NULL;#if HAVE_ALIGNED_MALLOCret _aligned_realloc(ptr, size !size, ALIGN);
#elseret realloc(ptr, size !size);
#endif
#if CONFIG_MEMORY_POISONINGif (ret !ptr)memset(ret, FF_MEMORY_POISON, size);
#endifreturn ret;
}
默认情况下的代码可以看出av_realloc()简单封装了系统的realloc()函数。C 库函数 – realloc() | 菜鸟教程
void *av_realloc(void *ptr, size_t size)
{/* lets disallow possibly ambiguous cases */if (size (max_alloc_size - 32))return NULL;return realloc(ptr, size !size);
}
av_mallocz()
void *av_mallocz(size_t size)
{void *ptr av_malloc(size);if (ptr)memset(ptr, 0, size);return ptr;
}
av_mallocz()可以理解为av_malloc()zeromemoryav_mallocz()中调用了av_malloc()之后又调用memset()将分配的内存设置为0
av_calloc()
void *av_calloc(size_t nmemb, size_t size)
{size_t result;if (size_mult(nmemb, size, result) 0)return NULL;return av_mallocz(result);
}
static int size_mult(size_t a, size_t b, size_t *r)
{size_t t;#if (!defined(__INTEL_COMPILER) AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow)if (__builtin_mul_overflow(a, b, t))return AVERROR(EINVAL);
#elset a * b;/* Hack inspired from glibc: dont try the division if nelem and elsize* are both less than sqrt(SIZE_MAX). */if ((a | b) ((size_t)1 (sizeof(size_t) * 4)) a t / a ! b)return AVERROR(EINVAL);
#endif*r t;return 0;
}
av_calloc()则是简单封装了av_mallocz() 从代码中可以看出它调用av_mallocz()分配了nmemb*size个字节的内存。
av_free()
void av_free(void *ptr)
{
#if HAVE_ALIGNED_MALLOC_aligned_free(ptr);
#elsefree(ptr);
#endif
}
可以看出av_free()简单的封装了free()
av_freep()
void av_freep(void *arg)
{void *val;memcpy(val, arg, sizeof(val));memcpy(arg, (void *){ NULL }, sizeof(val));av_free(val);
}
av_freep()简单封装了av_free()。并且在释放内存之后将目标指针设置为NULL。C 库函数 – memcpy() | 菜鸟教程
补充知识
内存对齐
参考链接计算机中的内存对齐与大小端 | MuYis Blog程序员通常认为内存就是一个字节数组每次可以一个一个字节存取内存。例如在C语言中使用char *指代“一块内存”Java中使用byte[]指代一块内存。如下所示。但那实际上计算机处理器却不是这样认为的。处理器相对比较“懒惰”它以块为单位进行数据的读取块的大小可以是2字节4字节8字节16字节甚至32字节来存取内存。例如下图显示了以4字节为单位读写内存的处理器“看待”上述内存的方式。上述的存取单位的大小称之为内存存取粒度。下面看一个实例分别从地址0和地址1读取4个字节到寄存器。从程序员的角度来看读取方式如下图所示。而2字节存取粒度的处理器的读取方式如下图所示。可以看出2字节存取粒度的处理器从地址0读取4个字节一共读取2次从地址1读取4个字节一共读取了3次。存储的时候也是将2个字节作为数据块的大小进行存储由于每次读取的开销是固定的因此从地址1读取4字节的效率有所下降。4字节存取粒度的处理器的读取方式如下图所示。可以看出4字节存取粒度的处理器从地址0读取4个字节一共读取1次从地址1读取4个字节一共读取了2次。从地址1读取的开销比从地址0读取多了一倍。由此可见内存不对齐对CPU的性能是有影响的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86291.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!