Linux slub分配和释放分析

本文详细介绍了Slub内存分配器的工作原理,包括其结构、内存分配与释放过程,并探讨了针对并发访问的优化措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Slub内存分配器,是在slab的基础上,进一步优化而来,在内存管理,多处理并发访问上更有优势.

 

这里主要讲解slub分配,释放,调试选项,以及针对slab的优化,源代码基于3.18.22

1. slub框架

 

 

 

   slub是特定大小内存的集合(称为object),每个slub可以包含多个page,代码中用

  struct kmem_cache, struct kmem_cache_node, struct kmem_cache_cpu来实现整个slub

  关系如下:

 

struct kmem_cache {

  struct kmem_cache_cpu __percpu *cpu_slab; /*per cpu数据,分配内存时,可以直接返回object */

unsigned long min_partial; /*每个cache 最小slab数量 */

int size; /* The size of an object including meta data */

int object_size; /* The size of an object without meta data */

int offset; /* Free pointer offset. */

int cpu_partial; /* Number of per cpu partial objects to keep around

如果大于这个值,然后就会释放slab到系统中 */

int inuse; /* Offset to metadata */

int align; /* Alignment */

const char *name; /* Name (only for display!) */

struct list_head list; /* List of slab caches */

struct kmem_cache_node *node[MAX_NUMNODES]; /*内存分配 */

};

struct kmem_cache_node {

spinlock_t list_lock; /*访问partial链表锁 */

#ifdef CONFIG_SLUB

unsigned long nr_partial; /*node上的slab数量 */

struct list_head partial; /*所有的slab挂接 */

#endif

};  

struct kmem_cache_cpu {

void **freelist; /* Pointer to next available object */

unsigned long tid; /* Globally unique transaction id:全局标志,用户免锁机制实现 */

struct page *page; /* The freelist from which we are allocating */

struct page *partial; /* Partially allocated frozen slabs list :从node中分配的内存*/

};

 

为什么 kmem_cache_cpu和kmem_cache_node都会挂接内存? 这种做是基于什么目的了?

这种做能够提高内存分配效率,具体在分配一节分析.

2. 内存分配

slub内存分配有五种情况, 效率从高到低.

这里cpu指struct kmem_cache_cpu结构体 node指struct kmem_cache_node

前三种情况都是从percpu上直接分配内存

2. 1. cpu->freelist分配

这种效率最高, 免锁操作,且中断开启

 

2. cpu->page 分配

类似与第一个

cpu->freelist = cpu->page->freelist ;

cpu->page->freelist = NULL ;

 

3. cpu->partial list

percpu的partial 上挂接了多个slab

 

cpu->page = cpu->partial ;

cpu->freelist = cpu->page->freelist ;

cpu->page->freelist = NULL ;

cpu->partial = cpu->page->next ;

免锁操作,禁止本地中断

 

4. node->partial list

如果percpu都分配失败,那么从node上分配 ,这样需要拿spinlock list_lock

1. 获取node->partial第一个page

cpu->page = nodepage

cpu->freelist = nodepage->freelist

nodepage->freelist = NULL

2. 当cpu->partial 总的object小于kmemcache->cpu_partial时

获取node->partial list上的slab 挂接到cpu->partail 直到总的object大于cpu_partail

5. alloc page

 

当上面四种情况都分配失败时,向邻居系统申请page,也即调用page_alloc

 

 

3 内存释放

内存释放分为三种情况

1. free to cput->freelist

2. free to cput->partial list

3. free to node->partial list

再释放object时,还设计到内存回收,也即释放内存到伙伴系统

当cpu partial 的objects > cpu_partial 时,

put page to node partial list

 

当node 上挂接的slab数据nr_partial 大于min_partial 且slab 全空时,

释放内存到伙伴系统

4. slub对并发的优化

this_cpu_cmpxchg_double :避免禁止中断

cmpxchg_double :避免使用锁

 

 

 

Stable Diffusion是一款基于深度学习的文本到像模型,能够根据输入的文字提示生成相应的图片。为了帮助您了解如何使用Stable Diffusion批量生成图片的过程,下面将为您详细介绍。 ### 环境准备 首先你需要准备好适合运行Stable Diffusion的工作环境: 1. **硬件设备**:建议配备一块NVIDIA GPU,显存越大越好;如果没有GPU也可以只依靠CPU工作,不过效率会非常低。 2. **安装Python环境**:通常选择Anaconda来管理虚拟环境可以简化依赖包之间的冲突问题。 3. **获取Stable Diffusion WebUI项目源码**: - 可以从GitHub上克隆官方仓库`https://github.com/AUTOMATIC1111/stable-diffusion-webui.git` 4. 安装必要的依赖库并启动Web UI界面: ```bash git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui conda env create -f environment.yaml # 或者使用 pip install 脚本里的命令去创建pip环境 ``` 5. 根据系统情况调整配置文件中的设置(例如CUDA版本等) ### 批量生成功能实现步骤 接下来就是具体的批处理流程了: 1. 进入StableDiffusion web ui页面后,在左侧找到“Batch Generate”选项卡; 2. 设置好每次迭代的数量、随机种子值范围以及总的迭代次数等等参数; 3. 输入想要转换成画内容描述语句作为Prompt,并设定Negative Prompt避免某些特征出现在最终结果里; 4. 修改其他如风格倾向(Style)、CFG Scale、采样步数(Sampling Steps)等相关超参直至满意为止; 5. 开始点击"Generate"按钮就可以让程序自动为你生成一系列高质量的艺术作品啦! 需要注意的是由于这是一个比较消耗资源的任务,所以在长时间稳定输出之前最好先做一些小规模测试熟悉整个过程并且观察效果是否达到预期标准。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值