操作系统性能提升之内核锁优化

news2024/12/23 17:49:49

性能为王,系统的性能提升是每一个工程师的追求。目前,性能优化主要集中在消除系统软件堆栈中的低效率上或绕过高开销的系统操作。例如,内核旁路通过在用户空间中移动多个操作来实现这个目标,还有就是为某些类别的应用程序重构底层操作系统.

在许多领域中,专有化似乎是追求更好性能的答案,集中在应用程序和内核,甚至是在不同的内核子系统之间。特别地,专有化可以构建应用程序向系统请求某些功能的上下文。虽然,应用程序专有化和内核绕过了存储、网络化和加速器,但是,内核中的并发控制可能是整体性能的关键。

af6e92d3997d53bd27210b0d7a3e1f7f.jpeg

1. 操作系统的性能:内核锁

内核锁是一种用于控制进程访问共享资源的机制。在Linux内核中,内核锁是通过在进程创建时分配一个特殊的锁来实现的。当一个进程需要访问共享资源时,内核会检查该进程是否已经持有该锁,如果没有,则将该进程加入到等待锁定的队列中,等待其他进程释放该锁。

内核锁对于实现应用程序的良好性能和可伸缩性至关重要.然而,内核同步原语通常是不可见的,并且是应用程序开发人员无法触及的。设计锁定算法并验证它们的正确性已经具有挑战性,而增加硬件的异构性使其更加具有挑战性。开发人员缺乏对锁正在操作的环境的认识,如优先级倒置和锁持有人优先等问题,本质上是缺乏上下文。

能否有一种方法能让用户空间的应用程序可以调优内核中的并发控制呢?

例如,用户可以对持有一组锁的特定任务或系统调用进行优先级排序。用户可以强制执行特定于硬件的策略,例如非对称多处理感知锁定,并且可以根据给定的工作负载决定对读写的优先级。如果允许开发人员调优内核中的各种锁,更改它们的参数和行为,甚至在不同的锁实现之间进行更改,或许可以进一步提升系统的性能。

软件堆栈专有化是提高应用程序性能的新方式,提出为了性能目的将代码推送到内核,通过避免增加内核数量瓶颈来提高应用程序的可伸缩性。随着时间的推移,即使是像Linux这样的宏内核,也已经开始允许用户空间的应用程序自定义内核行为。开发人员可以使用eBPF为跟踪、安全甚至性能目的定制内核。

除了eBPF,Linux的开发人员也在使用io_uring,一个在用户空间和内核之间的共享内存环缓冲区,以加快异步IO操作。此外,如今的应用程序可以完全在用户空间中处理按需分页。

应用程序来控制底层内核的并发机制,这为锁的设计者和应用程序开发人员提供了各种机会。

30c0203fd2d8ff2a815ff370069c651b.jpeg

2. 锁:过去、现在和未来

硬件是决定锁的可伸缩性的主要因素,从而影响应用程序的可伸缩性。例如,对于基于队列的锁,当多个线程同时获得锁时,可以减少过多流量。同时,分层锁使用批处理来使高速缓存线抖动的问题最小化。

SHFLLock提出了一种通过解耦锁策略与实现来设计锁算法的新思想,实现较少的内核内存开销和性能下降。主要引入了一个shuffler程序的概念,它重新排序队列或修改等待线程的状态。尽管ShflLocks提供了一种强制执行策略的方法,但还可以试图将重点放在一组简单的锁获取/发布API上的通用策略上。为了迎合应用的需求,通过分析影响给定工作负载的特定内核锁,应用程序的开发人员应该以受控和安全的方式定义他们的策略,并动态地更新锁获取策略,使用shuffler执行政策。

3 典型场景:调度等待锁的线程

等待锁的线程可以以两种不同的方式进行调度:基于锁的获取顺序的获取感知调度,以及基于线程在关键段内花费的时间的占用感知调度。

3.1采集感知的调度

锁开关,使开发人员能够在各种锁的算法之间进行切换。有三种突出的情况:

  1. 从中性的读写器锁设计切换到每个cpu或基于numa的阅读器设计,以满足读密集型工作负载.例如,页面错误和枚举一个目录中的文件.另一种情况是从中立的读写锁切换到纯粹的写锁;一个例子是在一个目录中创建多个文件。

  2. 从基于Numa的锁设计切换到具有Numa感知的组合方法,其中锁持有人代表等待线程执行操作.这种方法具有更好的性能,因为它至少删除了一个高速缓存的传输。

  3. 之间的开关阻塞和非阻塞锁,反之亦然,例如,通过关闭SHFLLock的shuffler功能的停止/唤醒策略,将阻塞读切换为非阻塞读写锁(rwlock)。

这种方法带来了两个好处:首先,开发人员可以删除临时同步,例如使用非阻塞锁和使用等待事件实现停止/唤醒策略,这在Btrfs文件系统中是常用的。第二,允许开发人员通过动态地多路复用多个策略来统一锁的设计。

e6c71a7665fc272339fd56b12058c7d4.png

3.1.1 锁继承

一个进程可能会获取多个锁来执行一个操作。例如,Linux中的一个进程最多可以获得12个锁(例如,重命名操作),或者平均获得4个锁来执行内存或文件元数据管理操作。

不幸的是,这种锁的模式引发了基于队列的锁问题,一些线程必须等待更长的时间才能获得顶级锁,这是由另一个线程等待另一个锁。例如,假设线程t1想要获得两个锁,L1,然后L2作为一个操作,而t2只想收回L1的操作。由于这些锁定协议是基于fifo的,所以t1可能在队列的最后获得L2,而t2正在等待获得L1。开发人员可以为内核提供更多的上下文:要么是t1获取所有锁在一起,或t1声明它已经持有的锁,可以给它一个更高的优先级来获得下一个锁L2。

应用程序可能希望优先考虑系统调用路径或一组任务,以获得更好的性能。开发人员可以通过对任务优先级上下文进行编码,并将此信息传递给受影响的锁。对于系统调用,开发人员可以共享关于一组锁和关键路径上的优先级线程的信息。然后,shuffler程序将优先考虑这些线程,而不是等待指定应用程序的锁的其他线程。

3.1.2 公开调度程序的语义

通常,超额订阅硬件资源,如CPU或内存,可以得到更好的资源利用率,对于两个用户空间运行时系统,以及虚拟机。虽然超额订阅提高了硬件利用率,但它也引入了双重调度问题。系统监控程序可以安排一个vCPU作为锁持有人或VM中的下一个锁服务。管理程序可以将vCPU调度信息公开给shuffler程序,以根据服务的运行时间配额对其进行优先排序。

3.1.3 可适应的停止/唤醒策略

所有的封闭锁都遵循旋转后停车的策略,即它们在旋转一段时间后自己停车。这个旋转时间主要是特别的,也就是说,服务员要么根据时间配额旋转一定时间,要么在没有任务要执行的情况下继续旋转。现在,应用程序开发人员可以在分析关键部分的长度后公开时间上下文,以最小化能源消耗和唤醒信息,以按时安排下一个服务员,以最小化唤醒延迟。此外,开发人员可以进一步对睡眠信息进行编码,在锁定之前唤醒服务员,以减少长时间的唤醒延迟。该方法也适用于副虚拟化的自旋锁以避免护航效应.

3.2 占用调度

3.2.1 优先级继承

当持有锁的低优先级任务被正常优先级任务调度出去,等待同一锁时,就会发生优先级反转。在Linux IO堆栈中说明了这个问题:当调度IO请求时,一个想要获得一个锁的正常任务可以调度一个持有相同锁的较低优先级的后台任务。锁的调度即后台任务,导致IO性能下降。

3.2.2 任务公平的合作调度

这引入了一类新的问题,称为调度器颠覆问题,其中两个任务在不同的时间内获得锁。保持时间较长的任务颠覆了操作系统的调度目标。操作系统通过跟踪关键区域大小和惩罚长时间的任务来解决这个问题。尽管这个解决方案解决了这个问题,但即使对于可能不会从中受益的应用程序,它也加强了调度的公平性。

3.2.3 在非对称多核处理器(AMP)机器上的任务公平锁定

在一个处理器中具有不同的计算能力核心,这种体系结构上使用的基本锁原语存在一种调度程序颠覆问题,应用程序吞吐量可能由于较弱内核的计算能力较慢而崩溃。为了实现更快的进程,开发人员可以在更快的核心上分配关键锁,也可以重新排序等待获得锁的线程队列,以改进整个锁。

3.2.4 实时调度

与实时系统中的调度类似,应用程序开发人员可以创建锁策略,总是调度线程以保证SLO。在这里,锁可以设计为一个基于阶段公平的算法.这种方法还允许消除抖动,并保证延迟关键应用程序的尾部延迟的上限。

3.3 动态锁的分析

应用程序开发人员可以配置文件有关任何内核锁的信息。选择要配置的锁使开发人员能够在不同的粒度级别上配置。例如,它们可以配置在内核中运行的所有自旋锁、特定函数中的锁、代码路径或名称空间,甚至是单个锁实例。这种方法使应用程序开发人员受益,能够通过只分析感兴趣的部分来更好地理解底层同步。

开发者也可以对性能合约进行推理,基于各种shuffler策略甚至是一组策略提供的某些担保,这些性能合约会影响应用程序的性能。

4.一种内核锁的优化框架

重新定义内核锁所使用的决策和行为,并公开为API,用户定义的代码替换这些公开的API,用户可以根据自己的需要定制锁定功能。例如,在加入等待队列之前是否要旋转可以是一个API,这样用户就可以做出决定。用户首先编写自己的代码来根据用例修改内核中的锁协议,然后操作系统替换内核内部带注释的锁函数,流程示意如下:

2fd18abff7b3d53a0c78a0c8f97412c0.jpeg

用户指定了一个锁策略(1),eBPF验证者在编译后验证它,同时考虑到eBPF限制和互斥安全属性(2,3)。然后,验证者将通知用户验证结果(4),如果成功,则将编译后的eBPF代码存储在文件系统(5)中。最后,使用现场补丁模块替换指定锁(6)的注释函数。

4.1 API

各种API支持了锁策略的灵活实现,同时保障了安全,操作系统底层实现依赖于eBPF来修改内核锁。通过使用eBPF和锁API,为内核中的一组锁实例实现了所需的策略。一个用户可以编码多个策略,它被转换为原生代码,并由eBPF验证者进行安全检查。验证器在将本机代码加载到内核中之前执行符号执行,例如内存访问控制或只允许白名单的辅助函数。

a3dc3db3218f5db4a677093b2e205839.jpeg

4.2 安全性

除了eBPF验证器,ShflLocks有单独的锁获取阶段和一个重新排序等待队列的阶段。用户依赖API函数来比较当前节点和洗牌器节点与是否对当前节点进行重新排序,也可以设计调度器协同锁,通过对临界切片长度较小的节点进行优先级排序,从而降低对节点的优先级。

虽然不正确的用户实现可能会破坏公平性保证的策略,但是可以在运行时检查并确保互斥属性。此外,内核没有任何死锁问题,API不修改锁行为,只返回移动节点的决定。开发人员能够通过实现每个调用所需的行为,以细粒度的方式配置他们的锁。虽然不会改变锁函数的行为,但重量配置分析策略可能会增加关键部分的长度,从而导致性能下降。

此外,eBPF公开了链接多个eBPF程序的功能,用户可以使用这些程序来编写策略。最后,我们还依赖于现场调度的数据结构,用于修改锁定原语所使用的数据结构。例如,可以扩展基于队列的锁节点数据结构,并将额外的信息用于为特定的用例编码信息。在不执行用户空间代码的最坏情况下,动态修改锁算法可能会产生高达20%的开销。

4.3 组合策略

通过调优内核并发控制,应用程序可以对软件堆栈有更多的控制。应用程序开发人员提供了一组需要应用锁的策略。组合多个策略是一项困难的任务,特别是当某些策略可能发生冲突的时候。通过利用程序合成来自动化这个过程,或许可以将安全属性完全移动到用户空间中的验证,也可以提供一种安全的方式来组成相互冲突的策略。

用户不能添加太多的策略,因为它们的执行可能会落在关键路径上。允许一个特权用户修改内核锁,该模型仅适用于使用整个系统的一个用户。然而,为了处理云环境中的多租户,需要一个感知租户的策略编写器,它不违反用户之间的隔离。在用户空间中综合策略以避免此类冲突,并在锁算法中添加运行时检查,这些检查只在策略可以影响特定行为时使用。

除了锁之外,还有其他在内核中大量使用的同步机制,如RCU, seqlocks ,等待事件等扩展,将进一步允许应用程序提高其性能。也就是说,用户空间应用程序还有它们自己的、本质上是通用的锁。相比之下,现有的技术,如库插入,只允许在应用程序开始执行时对不同的锁实现进行一次更改。

5.小结

内核锁的同步原语对一些应用程序的性能和可伸缩性有巨大的影响,然而,控制内核同步原语对于应用程序开发人员来说是无法实现的。如果使用上下文并发控制,它允许用户空间应用程序微调内核并发原语。这是一种思考软件堆栈专有化的方法,在一定程度上加速了内核同步领域的创新。

【参考资料与关联阅读】

  • https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux. git/tree/include/uapi/linux/bpf.h?h=v5.4.

  • https://www.kernel.org/doc/html/ latest/livepatch/shadow-vars.html.

  • https://github.com/ antonblanchard/will-it-scale.

  • https://doi.org/10.1109/ECRTS.2009.14

  • https://www.kernel.org/doc/Documentation/locking/mutex-design.txt.

  • Kernel Live Patching,https://lwn.net/Articles/619390/

  • lockstat: documentation. https://lwn.net/Articles/252835/

  • http://www.brendangregg.com/blog/2019-12-02/ bpf-a-new-type-of-software.html.

  • 异想天开!没有CPU的操作系统

  • 一种编译器视角下的python性能优化

  • 操作系统中的系统抽象

  • 温故知新:从计算机体系结构看操作系统

  • 从操作系统看Docker

  • 感知人工智能操作系统

  • Linux 内核裁剪框架初探

  • IoT中的Linux选择

  • 嵌入式Linux的网络连接管理

  • 老曹眼中的Linux基础

  • 计算机体系结构的一知半解

  • 计算机网络的元认知、实践与未来

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

提升效率,从这款智能挂灯开始

❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP 10🏆,Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作…

华为项目经理就是CEO,华为对项目经理的要求是什么?

项目经理要向上发展,下面我们来看看华为对项目经理的要求。 原文出自:pmo前沿

太空大战-第14届蓝桥杯国赛Scratch真题中级组第6题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第148讲。 太空大战,本题是2023年5月28日上午举行的第14届蓝桥杯国赛Scratch图形化编程中级组真题第6题&am…

Flume学习---3、自定义Interceptor、自定义Source、自定义Sink

1、自定义Interceptor 1、案例需求 使用 Flume 采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不同的分析系统。 2、需求分析 在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发…

【微信公众平台对接】有关【上传图文消息内的图片获取URL】调用示例

1、微信接口说明: 2、调用示例 /*** 上传图文消息内的图片获取URL** param image* return*/PostMapping("uploadImg")public String uploadImg(MultipartFile image) {return wechatOpenService.uploadImg(image);}/*** 上传图文消息内的图片获取URL* htt…

css魔法:伪元素content内容竟然可以用css函数!

🌻 前言 CSS 伪元素用于设置元素指定部分的样式。伪元素中 ::before 和 ::after 是最常用的,它们分别用于在dom元素前/后插入内容,本文内容就是关于 ::before 和 ::after 的 content 内容的一些冷门用法展开的。 一般我们在使用伪元素时&…

基于Java+jsp+servlet的养老院管理系统设计和实现《收藏版》

基于Javajspservlet的养老院管理系统设计和实现《收藏版》 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方…

大麦生成链接 大麦生成订单截图 抢票成功截图

一键生成购票链接 一键生成订单截图 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

微服务工程搭建过程中的注意点

1、父工程pom.xml文件 1:父工程的maven坐标; 2:packaging使用pom; 原因:在Spring Cloud微服务工程中,通常会采用多模块的方式进行开发,父工程的pom文件中的packaging标签设置为pom,是…

操作系统 | 知识梳理 | 复习(上)

目录 📚操作系统概述 🐇操作系统中的抽象概念 📚准备知识 🐇中断输入输出 🐇软件中断 🐇处理器特权级 🐇操作系统的结构 📚程序的结构 🐇运行时视图简介 &…

SQL语句中EXISTS的详细用法大全

SQL语句中EXISTS的详细用法大全 前言一、建表1.在MySQL数据库建表语句2.在ORACLE数据库建表语句 二、在SELECT语句中使用EXISTS1.在SQL中使用EXISTS2.在SQL中使用NOT EXISTS3.在SQL中使用多个NOT EXISTS4.在SQL中使用多个EXISTS5.在SQL中使用NOT EXISTS和EXISTS 三、在DELETE语…

jmeter非gui运行,jtl生成了,但是html报告没有生成

jmeter非gui运行,jtl生成了,但是html报告没有生成,查看log,内容如下: 22:45:00,913 ERROR o.a.j.JMeter: Error generating dashboard: org.apache.jmeter.report.dashboard.GenerationException: Error while proces…

谷歌的passkey是什么?

谷歌的passkey是什么? 谷歌正在研发一种名为“Passkey”的新技术,它将用于用户身份验证。Passkey不同于传统的密码,它采用了硬件加密密钥(如安全密钥或生物识别方式)以及双因素身份验证等技术,可以更好地保…

微信:把元宇宙装进小程序

作为月活13.09亿的国民级应用,微信的每次小升级都很容易形成现象级。2023开年,微信放大招,试图把元宇宙装进小程序。 微信小程序 XR-FRAME 不久前,微信官方在开放社区贴出了“XR-FRAME”开发指南,这是一套为小程序定制…

RocketMQ 快速入门教程,手把手教教你干代码

目录 RocketMQ定义为什么要用消息中间件?应用解耦流量削峰数据分发 RocketMQ各部分角色介绍NameServer主机(Broker)生产者(Producer)消费者(Consumer)消息(Message) 使用RocketMQ的核心概念主题(Topic)消息队列(Message Queue)分组(Group)标签(Tag)偏移量(Offset) 普…

企业级信息系统开发讲课笔记4.11 Spring Boot中Spring MVC的整合支持

文章目录 零、学习目标一、Spring MVC 自动配置(一)自动配置概述(二)Spring Boot整合Spring MVC 的自动化配置功能特性 二、Spring MVC 功能拓展实现(一)创建Spring Boot项目 - SpringMvcDemo2021&#xff…

老胡的周刊(第094期)

老胡的信息周刊[1],记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 qrbtf[2] 艺术二维码生成器: qrb…

某学院校园网站的设计与实现(论文+源码)_kaic

摘 要 使用旧方法对冀中工程技师学院网站的信息进行系统化管理已经不再让人们信赖了,把现在的网络信息技术运用在冀中工程技师学院网站的管理上面可以解决许多信息管理上面的难题,比如处理数据时间很长,数据存在错误不能及时纠正等问题。这次…

ajax--XML、AJAX简介、express框架使用、AJAX操作的基本步骤

一、XML(可扩展标记语言) XML与HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。 比如有一个学生数据:name“孙悟空”;age18;gender“男”&a…

数字图像处理期末复习习题 SCUEC part3 形态学图像处理专项

1.关于膨胀,腐蚀,开操作,闭操作的证明题 2.腐蚀和膨胀的定义 3.开操作与闭操作的定义 4.击中击不中变换