从零开始成为GStreamer专家——GSlice

GSlice是GStreamer中的一种高效内存管理机制,它通过将内存分割成固定大小的chunk并利用magazine缓存来优化内存分配和释放。每个线程拥有两个magazine链表,用于快速分配和回收内存,避免频繁的系统调用。Gslice还采用了cachecolorization技术提高CPU缓存利用率。当内存不再需要时,它不会立即释放,而是保留在magazine中,等待后续使用。此外,Gslice还包括slab分配器和page分配器,分别处理页面大小的内存和对齐的内存分配。错误处理方面,可能会遇到如segfault等问题,通常与内存访问不当有关。

从零开始成为GStreamer专家——GSlice

        Gslice全称应该是GSlice allocator,是一种有效的内存管理方式,它将大小相同chunk_size的内存分成内存块组,称为一个magazine,一个magazine内有许多个内存大小一样的空间。是一种节省空间、可扩展的分配大小相同的内存块的内存管理方式,就像#GMemChunks(来自 GLib 2.8),同时避免了过多的内存浪费、可伸缩性和性能问题。

        Gslice使用了一种复杂的分层设计,它使用 posix_memalign() 来优化这些相同大小内存块的分配。Gslice中每个线程都有空闲链表(所谓的magazine层),用来快速分配已知大小结构体的内存请求。 这就意味着内存Gslice并不是立即释放内存返回给系统,而是提供额外的缓存逻辑来保存这段内存信息。由于地址对齐而未使用的那部分内存,则使用缓存着色技术(cache colorization—内存地地址随机分步,有助于提高CPU cache利用率)以提高 CPU 缓存利用率,可以用chunk = (ChunkLink*) (mem + color);语句来表示,其中mem是分配的内存起始地址,clolor是多余的空间长度。 Gslice分配器的cache层自适应高锁竞争(high lock contention)来提高可扩展性。

        Gslice可以分配小到只有两个指针的数据结构内存块,与 malloc() 不同,它不会为每个块保留额外的空间。而大块的内存,g_slice_new() 和 g_slice_alloc() 将自动调用系统 malloc() 实现。 对于新开发的代码,建议使用g_slice函数而不是g_malloc之类的函数分配内存,g_slice之类函数分配的内存,只要对象在其生命周期内没有调整大小,那么这段内存在释放时仍然可用。

        从层次结构上讲,Gslice大致可以分为4层,也即在slab层后扩展了magazine层。分别是thread magazines层,magazine cache层,slab分配器,page分配器。

        后续例子在arm 32位平台,按如下Allocator参数进行:

{min_page_size = 128, max_page_size = 8192, config = {always_malloc = 0, bypass_magazines = 0, debug_blocks = 0, working_set_msecs = 15000, color_increment = 1}, max_slab_chunk_size_for_magazine_cache = 1021,   magazine_mutex = {p = 0x0, i = {0, 0}}, magazines = 0x58d360, contention_counters = 0x58d160, mutex_counter = -11, stamp_counter = 0, last_stamp = 15905188, slab_mutex = {p = 0x0, i = {0, 0}}, slab_stack = 0x58d560,  color_accu = 544} 

#define LARGEALIGNMENT          (256)
#define P2ALIGNMENT               (8)
#define ALIGN(size, base)       ((base) * (gsize) (((size) + (base) - 1) / (base)))
#define NATIVE_MALLOC_PADDING   8
#define SLAB_INFO_SIZE             (24)
#define MAX_MAGAZINE_SIZE       (256)
#define MIN_MAGAZINE_SIZE        (4)
#define MAX_STAMP_COUNTER       (7)
#define MAX_SLAB_CHUNK_SIZE(al) (1021)
#define MAX_SLAB_INDEX(al)      (126)
#define SLAB_INDEX(al, asize)   ((asize) / 8 - 1)
#define SLAB_CHUNK_SIZE(al, ix) (((ix) + 1) * 8)
#define SLAB_BPAGE_SIZE(al,csz) (8 * (csz) + 24)

Thread magazines层

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值