全部博文(18)
分类: LINUX
2008-12-12 17:46:38
SLAB的设计理念是基于对象缓冲的,基本想法是避免重复大量的初始化和清理操作。SLAB也可考虑到了CPU缓冲的有效利用。SLAB主要可以用于频繁分配释放的内存对象。
SLAB的设计目的是作为系统的核心缓冲系统,当然,在各个子系统里也可以使用独立的缓冲系统,但这种方法有三个缺点:(选译自:The Slab Allocator: An Object-Caching Kernel Memory Allocator)
在概念上,SLAB的工作方式如下(选译自:The
Slab Allocator: An Object-Caching Kernel Memory Allocator):
分配一个对象:
if (there is an object in the cache) |
return it to the cache; (with destructor required) |
take some objects from the cache; |
创建一个cache ,一般使用kmem_cache_create(),正如以上伪代码所表明的:这并不意味着SLAB分配器会预先分配任何object。它只是分配一个cache描述符,初始化其成员而已。OK,那么“分配一个cache描述符”是怎么分配的呢?答案是仍然是使用SLAB分配器的标准接口:kmem_cache_alloc(),那么这又要求一个己经创建好的cache。仿佛碰到了“鸡生蛋还是蛋生鸡”问题。
答案是用于分配cache描述符的cache是系统静态定义和初始化的,这就是cache_cache。
还有一个通常称为cache_sizes的一系列cache,实际上它们就是一系列预先创建的具有不同object大小的cache,用于常用的kmalloc()/kfree()接口,别无任何特殊之处。
slab管理性信息包括一些统计性信息和空闲object链表(依靠索引维系链接关系)。根据object的大小和页面大小,它可能保存于objects所在的页面上。如果slab管理信息单独保存,就称这种slab是off slab。如果处于object页面内,它们会出现在页面首部。
如果每个slab在承载了objects(和可能的管理性信息)之后尚有剩余空间,那么,还可以进行缓冲着色处理,具体可以支持多少种“颜色”,取决于object的对齐要求,L1缓冲参数和剩余空间的大小。注意“剩余空间”的大小不可能超过object的大小。
在Slab正在扩展空间或者已经扩展了空间之后,这个Slab会设置一个GROWN标志,这样在系统在第一趟回收内存时会先跳过它(在这趟扫描时,它会除掉这个标志,所以之后的扫描不会再对之留情)。
在SMP内核里,每个slab有一个为每个处理器安排的缓冲池,每个CPU里可以有limit个object,每次需要补充这个缓冲池时,会补充batchcount个object。limit取决于object的大小,batchcount取决于limit,在2.4.22内核里batchcount=limit/2。
SLAB避免重复对象的初始化操作和清理操作。除了节省了这部分代码执行时间之外,这种跳过操作,还避免了初始化/清理代码污染了hotpath代码的缓冲,也即减少了cache footprint。但这种节省也意味着,我们在使用SLAB时需要注意:
此外,关于缓冲着色,如果你确定需要这个功能,不要以为SLAB分配器的实现会一定满足它的需要,例如对于3000字节的对象,它恐怕是做不到着色效果的。因为每个slab只能保存这样大小的一个object。而每个slab的object数据都会从一个页面的固定偏移开始,所以,你会发现所有3000字节的对象都有一样的页内偏移,这样的话,基本也就没有什么着色而言啦。
SLAB的设计很棒,但这并不妨碍它成为我们砸自己脚的工具。