Memory allocator
这个exericise的工作是通过为每个CPU维护一个freelist来减少kalloc时的锁竞争,当CPU对应的freelist为空时,从其他CPU的freelist中窃取page。
1.为每个CPU都维护一个freelist
struct {
struct spinlock lock;
struct run *freelist;
} kmem[NCPU];
2.kinit时为每个CPU对应freelist初始化锁
void
kinit()
{
for (int i = 0; i < NCPU; i++)
initlock(&kmem[i].lock, "kmem");
freerange(end, (void*)PHYSTOP);
}
3.freerange时将所有的page都放到同一个CPU对应的freelist中,freerange函数保持不变
4.kalloc时获取当前cpu的cpuid,然后根据cpuid去对应的freelist中查找是否有可用的page,如果没有到其他cpu的freelist中查找
void *
kalloc(void)
{
struct run *r;
push_off();
int cpu_id = cpuid();
pop_off();
acquire(&kmem[cpu_id].lock);
r = kmem[cpu_id].freelist;
if(r)
kmem[cpu_id].freelist = r->next;
else {
for (int i = 0; i < NCPU; i++) {
if (i != cpu_id) {
acquire(&kmem[i].lock);
r = kmem[i].freelist;
if(r)

这篇博客讨论了如何通过为每个CPU维护局部freelist和使用多级BUCKET策略来减少内存分配(kalloc)和缓冲区缓存(bcache)中的锁竞争。kalloc中,每个CPU都有自己的freelist,当本地freelist为空时,可以从其他CPU的freelist窃取页。而在bcache中,引入了多个BUCKET,通过哈希定位块并依据使用时间记录来优化缓冲区的查找和释放,减少了锁的使用,提高了系统性能。
最低0.47元/天 解锁文章
33万+

被折叠的 条评论
为什么被折叠?



