03_012slab块分配器,管理内核内存分配,管理高速缓存

物理背景

为什么会有缓存cache
在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处理器内核要复杂得多,其时钟速度可以快上几个数量级。但是,外部总线和内存设备的频率并没有扩大到同样的程度。有可能实现小块的片上SRAM,它可以以与内核相同的速度运行,但是与标准的DRAM块相比,这种RAM非常昂贵,因为后者的容量可以达到数千倍。在许多基于ARM处理器的系统中,访问外部存储器需要几十甚至几百个内核周期。
缓存在哪里
缓存是位于核心和主内存之间的一个小型快速内存块。
它存储了主存储器中资料的副本。对高速缓冲存储器的访问比对主存储器的访问快得多。每当内核读取或写入一个特定的地址时,它首先在高速缓存中寻找。如果它在高速缓存中找到该地址,它就会使用高速缓存中的数据,而不是对主内存进行访问。这大大增加了系统的性能,因为它减少了缓慢的外部存储器访问时间的影响。
在这里插入图片描述
cpu集群和缓存l1 l2 l3的关系
实现ARMv8-A架构的处理器通常有两级或更多的高速缓存。这通常意味着处理器的每个内核都有小的L1指令缓存和数据缓存。Cortex-A53和Cortex-A57处理器通常采用两级或多级缓存,即一个小的L1指令和数据缓存和一个较大的、统一的L2缓存,该缓存在集群的多个内核之间共享。此外,还可以有一个外部L3高速缓存作为外部硬件块,在集群之间共享。
cache为啥能加速
向高速缓存提供数据的初始访问并不比正常速度快。对缓存值的任何后续访问才会更快,而性能的提高正是来自于此。核心硬件会检查缓存中所有的指令获取和数据读取或写入,尽管你必须将内存的某些部分,例如包含外围设备的部分,标记为不可缓存的。因为高速缓存只容纳了主内存的一个子集,所以你需要一种方法来快速确定你要找的地址是否在高速缓存中。

slab kem_cache cache 等名词扫盲

struct slab 结构体

为每种对象类型创建一个内存缓存,每个内存缓存由多个大块组成,一个大块是一个或者多个连续的物理页,每个大块包含多个对象。slab采用面向对象的思想,基于对象类型管理内存,每种对象被划分成一个类。比如进程描述符(task_struct)是一个类,每个进程描述符的实现是一个对象。
在这里插入图片描述

struct kmem_cache

从上面的图能看出
kmem_ cache是用于管理slab的高速缓存结构体。在一个kmem_ cache中,slab对象大小是相同的,也就是说,每个对象占用的空间大小都是固定的。 kmem cache 用来分配和管理或销毁 slab

struct kmem_cache_node

上面的结构体用来维护相同的slab 这个结构体用来存储所有的slab 给L1缓存使用
每个物理ram节点 都用一个kmem_cache_node进行描述
kmem_ cache_ node结构体中存储了三个列表: full partial 和empty列表。
这三个列表分别表了该节点上的满的slab、部分满的slab和空的slab。

Slab分配器

SLAB分配器的实现基于三个列表: full list、partial list和empty list。
当应用程序请求分配内存时,SLAB分配器首先在partial list中查找是否存在适合大小的内存块。
如果找到,则该内存块被分配并从partial list中移除。如果partial list中没有适合的内存块,
则SLAB分配器会从empty list中获取一块内存,并将其划分为多个大小相同的块。
其中一块被分配给请求方,并剩余的块被放入partial list中。
当释放内存时,被释放的内存块将被放回partial list中。
如果partial list已满,则会将其中的一-些块移动到full list中,以供下次分配使用。
在full list中的块只能被释放到empty list中,以便它们可以被重新划分为多个小块以供下次使用。
SLAB分配器的优点在于它可以提高内存分配和释放的速度,
因为它维护了partial list和emptylist,可以避免在每次分配和释放内存时进行重复的内存管理操作。
此外,SLAB分配器还可以避免内存碎片的产生,因为它只分配特定大小的内存块,不需要在内存池中寻找适合大小的碎片。

kmem_ cache

kmem cache是用于管理slab的高速缓存结构体。
slab是一 种内存分配机制,用于管理相同大小的对象。
在一个kmem_ cache中,slab对象大小是相同的,也就是说,每个对象占用的空间大小都是固定的。
kmem_ cache结构体包含了slab的相关参数,如每个slab中包含的对象数量、slab的页数、
每个对象的大小等。kmem_ cache还负责分配和管理slab内存,以及初始化和销毁slab。
每个kmem_ cache实例都维护着一组slab, 它们具有相同的大小和缓存属性。
因此,kmem. cache和slab是相互关联的,kmem_ cache用于管理和操作slab,而slab是由
kmem_cache创建和维护的。
在内核中,kmem_ cache和slab是 紧密结合的,它们一起实现了内核的内存管理功能。
在内核中,kmem_ cache并不是与zone一一对应的, 而是可以被多个zone共享。
当一个zone需要管理一种大小相同的对象时,它可以通过访问已经存在的kmem_ cache, 或者创建一个新的
kmem_ cache来管理这些对象。这样可以避免在不同的zone中重复创建相同的kmem_ cache, 节省内存开销。

kmem cache node

kmem_ cache_ node是一个用于节点的结构体,它的作用是维护不同节点的缓存空间的信息。
一个节点表示的是在NUMA系统中的一个节点,通常对应着一组处理器和一 些内存。
由于每个节点都可能有不同的内存资源,因此为每个节点单独维护缓存空间的信息可以提高内存分配的效率。
kmem_ cache_ node结构体中存储了三个列表: full、 partial 和empty列表。
这三个列表分别表了该节点上的满的slab、部分满的slab和空的slab。
每个节点都有一个kmem cache_ node结构体,
其中kmem_ cache以及每个slab中都包含一个指向所属节点的kmem_ cache_node的指针。
这样,通过遍历kmem_ cache_ node中的三个链表,可以高效地找到一个可以使用的slab进行内存分配。
该结构保存了Slab的三个链表,并基于结构对Slab对象进行管理。

kmlloc

kmalloc实际上调用的是slab_ alloc申请内存,所以kmalloc实际上分配小内存。下面是kmallic实
际上调用分配内存的 do kmalloc函数完成的工作:
1.检查要分配的内存大小是否超过了kmalloc所管理的内存池的最大值,如果超过了则返回
NULL。
2.调用kmalloc_slab函数获取对应大小的kmem_ cache结构体,如果获取失败则返回错误。
3.调用slab_ alloc函数从获取到的kmem cache对象中分配一块大小为size的内存, 如果分配失败
则返回错误。
4.调用kasan kmalloc函数给刚刚分配的内存打上KASAN标记,用于检测内存访问越界等问题。
5.调用trace
kmalloc函数记录分配内存的相关信息,用于跟踪和分析内存分配情况。
6.返回分配的内存指针。

总结

伙伴系统的实现是为了减少物理内存碎片化,每个zone通过自己的伙伴系统减少内存碎片。slab
分配器使得内存重复利用,减少物理内存的分配和释放。即通过slab分配器减少了物理内存的碎片
化。在Linux中除了slab分配还有slub、slob分配器。 他们都是通过缓存对象,来减少实际内存的
分配和释放。在linux中通过伙伴系统管理大内存,slab管理小内存。Linux通过这套体系减少了物
理内存的碎片化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/62424.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搭建SVN服务器

简介 SVN(Subversion)是一种版本控制工具,用于管理和跟踪文件的修改历史。它可以帮助团队协作开发,方便地共享和更新代码,同时也可以提供备份和安全控制功能。 使用SVN,你可以创建中央代码库(…

【MySQL】对表中数据的操作

本期给大家带来的是MySQL下对表中数据的增删查改操作 目录 一、对表插入数据 1.1 单行数据插入 1.2 多行数据插入 1.3 插入冲突时更新数据 1.4 替换式插入 1.5 插入查询结果 二、对表中数据进行查询 2.1 基本select 2.1.1 使用select查询表中数据 2.1.2 使用select…

内存快照:宕机后,Redis如何实现快速恢复?RDB

AOF的回顾 回顾Redis 的AOF的持久化机制。 Redis 避免数据丢失的 AOF 方法。这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大。一般而言,只要你采用的不是 always 的持久化策略,就不会对性能造成太大影响。 …

Godot 4 源码分析 - 碰撞

碰撞功能应该是一个核心功能,它能自动产生相应的数据,比如目标对象进入、离开本对象的检测区域。 基于属性设置,能碰撞的都具备这样的属性:Layer、Mask. 在Godot 4中,Collision属性中的Layer和Mask属性是用于定义碰撞…

任务12、Quality指令加持,Midjourney生成电影级数码作品

12.1 任务概述 本次实验任务旨在帮助你掌握Midjourney AI绘画中的Quality指令。通过深入介绍Quality指令的概念和作用,我们将解释为什么它在绘画中至关重要。通过测试不同的Quality参数对绘画效果的影响,并提供实战演示,你将学会如何在Midjourney中设置Quality参数以达到更…

使用uni-app的uniCloud 云数据库入门:实现一个简单的增删改查

官方云数据库文档 前置步骤使用uni-app新建一个uniCloud项目 [外链图片转存失败,源站可能有防盗官方云数据库文档]!链机制,建议将()https://uniapp.dcloud.net.cn/uniCloud/hellodb.html)] 新建表 这里我加了几个测试字段 createTime、remark、money // 文档教程: https://un…

利用appium抓取app中的信息

一、appium简介 二、appium环境安装 三、联调测试环境 四、利用appium自动控制移动设备并提取数据

GO学习之 网络通信(Net/Http)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、 文章目录 GO系列前言一、H…

计算机网络体系结构

计算机网络体系结构 常用的网络体系结构 OSI体系结构 为了使不同体系结构的计算机网络都能互连,国际标准化组织于1977年成立了专门机构研究该问题,不就他们就提出了一个试图使各种计算机在世界范围内互连成网的标准框架,也就是著名的开放系…

docker部署jenkins且jenkins中使用docker去部署项目

docker部署jenkins且jenkins中使用docker去部署项目 1、确定版本 2.346.1是最后一个支持jdk8的 2、编写docker-compose.yml并执行 在这个目录中新增data文件夹,注意data是用来跟docker中的文件进行映射的 docker-compose.yml version: "3.1" service…

Java私有仓库Nexus搭建部署

Java私有仓库Nexus搭建部署 需求分析 为什么要搭建部署Nexus私有仓库,有什么用,用来干什么,怎么用,也许是大家看到这篇文章的第一个反应和疑惑,这里给大家先笼统的做一个介绍: 依赖管理:在Java…

USB采集卡如何打pts

一、使用采集卡提供的pts 二、手动打pts 1.usb采集设备pts的问题 2.采集卡驱动,UVC/UAC,ffmpeg的关系 3.如何自己打pts 4.音视频同步调优 5.NTP等联网调时工具带来的不同步问题 一、使用采集卡提供的pts 我们用使用pc摄像头和使用pc麦克风声卡里的方法&…

idea数据库快速上手-库操作与表结构和数据操作

引言 对数据库的操作无非就是执行SQL语句,要想熟练操作数据库,就要熟练运用SQL语句。 一,数据库操作 展示当前服务器内的数据库 -- 展示服务器内的数据库 show databases; show schemas; 执行结果: 创建数据库: --…

【福建事业单位-推理判断】07逻辑论证-削弱

【福建事业单位-推理判断】07逻辑论证-削弱-加强 题型分析一、削弱题1.1 否定论点1.2 拆桥(话题不一致)1.3否定论据(否定强度低于前面两者)1.4 因果关系(论点中的因果关系)——力度相当于否定论点1.5 另有他…

docker search 镜像报错: connect: no route to host (桥接模式配置静态IP)

如下 原因 可能有多种: ① 没有开放防火墙端口 ② ip地址配置有误 解决 我是因为虚拟机采用了桥接模式,配置静态ip地址有问题。 先确认虚拟机采用的是 桥接模式,然后启动虚拟机。 1、打开命令行,输入下面指令,打开…

Docker 快速安装 MinIO

概述 MinIO 是一款基于Go语言的高性能对象存储服务,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等。 拉取docker镜像 docker pull minio/minio创建宿主机数据目录(共享数据卷) 此…

FPGA----UltraScale+系列的PS侧与PL侧通过AXI-HP交互(全网唯一最详)附带AXI4协议校验IP使用方法

1、之前写过一篇关于ZYNQ系列通用的PS侧与PL侧通过AXI-HP通道的文档,下面是链接。 FPGA----ZCU106基于axi-hp通道的pl与ps数据交互(全网唯一最详)_zcu106调试_发光的沙子的博客-CSDN博客大家好,今天给大家带来的内容是&#xff0…

Java根据坐标经纬度计算两点距离(5种方法)、校验经纬度是否在圆/多边形区域内的算法推荐

目录 前言 一、根据坐标经纬度计算两点距离(5种方法) 1.方法一 2.方法二 3.方法三 4.方法四 5.方法五 5.1 POM引入第三方依赖 5.2 代码 6.测试结果对比 二、校验经纬度是否在制定区域内 1.判断一个坐标是否在圆形区域内 2.判断一个坐标是否…

回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测

回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测预测效果基本介绍研究内容程序设计参考资料…

C语言代码的x86-64汇编指令分析过程记录

先通过Xcode创建一个terminal APP&#xff0c;语言选择C。代码如下&#xff1a; #include <stdio.h>int main(int argc, const char * argv[]) {int a[7]{1,2,3,4,5,6,7};int *ptr (int*)(&a1);printf("%d\n",*(ptr));return 0; } 在return 0处打上断点&…