Linux memcg lru lock提升锁性能
目录
内核关于per memcg lru lock的重要提交:
计算虚拟地址转换基本机制
问题背景
swap换入流程
时奎亮的per memcg lru lock分享视频
内核关于per memcg lru lock的重要提交:
f9b1038ebccad354256cf84749cbc321b5347497
6168d0da2b479ce25a4647de194045de1bdd1f1d
计算虚拟地址转换基本机制
为了处理多应用程序的地址冲突, linux 系统在应用中使用了虚拟地址,得益于硬件的MMU的广泛使用,虚拟地址到实际内存的物理地址转化变得快速很多。
当虚拟地址送到cpu中后, 系统先前检查TLB表中是否有这个地址, 如果有,直接返回物理地址, 如果没有就去检查PageTable, 如果pagetable中也没有这个地址,系统产生一个page fault,来给这个地址实际分配物理内存。
每个应用的page table 保存了虚拟地址到物理地址一一对应表, 示意图如下所示:
Page fault 在linux中采用了称之为lazy fault的处理策略, 就是申请内存时并不实际分配物理内存, 直到实际使用这块内存时才实际分配内存。例如,得益于linux共享内存的设计,如果应用申请的share lib已经被其他程序实际分配到内存。 那么后来的应用只要在pagetable中填上对应的页表项就好。不需要发生实际的IO,这个过程叫做 minor fault. 第一个使用share lib的应用因为需要把share lib的内容读到内存, 需要有IO 的参与, 称之为Major fault.
问题背景
自电子计算机诞生以来,内存性能一直是行业关心的重点。内存也随着摩尔定律,在大小和速度上一直增长。现在的云服务器动辄单机接近 TB 的内存大小,加上数以百记的 CPU 数量也着实考验操作系统的资源管理能力。
作为世间最流行的操作系统 Linux, 内核使用 LRU(Last Recent Used)链表来管理全部用户使用的内存,用一组链表串联起一个个的内存页,并且使用 lru lock 来保护链表的完整性。
所有应用程序常用操作都会涉及到 LRU 链表操作,例如,新分配一个页,需要挂在 inactive lru 链上, 2 次访问同一个文件地址, 会导致这个页从 inactive 链表升级到 active 链表, 如果内存紧张, 页需要从 active 链表降级到inactive 链表, 内存有压力时,页被回收导致被从 inactive lru 链表移除。不单大量的用户内存使用创建,回收关系到这个链表, 内核在内存大页拆分,页移动,memcg 移动,swapin/swapout, 都要把页移进移出 lru 链表。
可以简单计算一下 x86 服务器上的链表大小:x86 最常用的是 4k 内存页, 4GB 内存会分成 1M 个页, 如果按常用服务器 256GB 页来算, 会有超过 6 千万个页挂在内核 lru 链表中。超大超长的内存链表和频繁的 lru 操作造成了 2 个著名的内核内存锁竞争, zone lock 和 lru lock。这 2 个问题也多次造成麻烦,系统很忙,但是业务应用并没得到多少 cpu 时间, 大部分 cpu 都花在 sys 上了。一个简单 2 次读文件的 benchmark 可以显示这个问题, 它可以造成 70% 的 cpu 时间花费在 LRU lock 上。https://git.kernel.org/pub/scm/Linux/kernel/git/wfg/vm-scalability.git/tree/case-lru-file-readtwice
作为一个知名内核性能瓶颈, 社区也多次尝试以各种方法解决这个问题, 例如,使用更多的 LRU list, 或者 LRU contention 探测(https://lwn.net/Articles/753058/)。
但是都因为各种原因被 Linux 内核拒绝。
swap换入流程
cpu接到访问一个虚拟地址的命令, cpu需要把这个虚拟地址转化成物理地址,于是先去访问TLB,如果命中TLB,返回物理地址, 如果没有继续访问页表,如果命中页表, 返回物理地址, 如果没有命中, 产生page fault, 在page fault处理程序中,发现,虚拟地址对应的页表项虽然present bit 为零但是内容非空,所以这个地址在一个被交换到swap设备的页中。继续检查,这个页是否在swapcache中,如果在,返回这个页地址加虚拟地址地址在页中的偏移,如果不在,获得一个内存页, 到swap设备上读取内容填到这个页,此处产生IO, 为Major page fault. 接下了就上把这个页加到swapcache,加入 LRU, 加入page table, 关联到所属的memcg, 并且添加反向映射,然后用户就可以正常使用了。 最后在某些机器上在更新mmu cache.(spark/ppc)
linux kernel 使用LRU来管理内存页。 Last Recent Used. 内核页管理方式如下图所示:
lru 由2个链表组成,一个是inactive list, 另一个是active list, page fault新产生的页加到inactive list的头上, 二次访问到的页从inactive list上提升到active list上, 如果内存有压力回收时,active list的页降级的inactive list, inactive list页从尾巴上回收掉。
lru 页管理涉及到的内核数据有3个,per node 上的 Lru_lock, page.flags上的 PG_lru bit 和per node 5个链表。linux 把所有用户使用的内存页都放在5个链表上, inactive anon, active anon, inactivec file, active file and unevictable list.
Lru_lock保护的对象有6个,
加锁保护的时机如下:
在2008年以前, memcg加入内核之前, 内核使用一个per node lru_lock保护per node的lru lists.
当memcg引入内核后, lru list改成了 per memcg的模式,每个memcg都有一组lru lists.
当每个memcg的页共同还在同一个lru lock上竞争时, 显然不如给每个memcg一个lru lock, 这样lock contention就会大大减小。
使用per memcg 的 lru_lock, 要先解决一个问题: 内存页不会一直在一个memcg上固定不变, 页也许会被移动到其他的memcg上, 也许memcg会销毁。 所以使用per memcg lru lock的关键就是如何在在lru lock 锁定期间 保证memcg固定。
开始很直接想到的是relock方案:
page在memcg之间移动要获得lru_lock, 所以lru_lock relock可以保护page在memcg之间的移动, 但是回顾上面读取swap device的例子, 我们会在关联memcg之前加入lru list, 这个导致页所属的memcg不稳定, 因而会拿错Lru_Lock 。解决的根本是改变页加入lru list和memcg的次序:如下所示,先关联memcg, 然后在加入lru list.
关键步骤更新后,页管理中的锁的使用次序页可以改变了:
relock方案是可以用了。 但是relock 增加了lock 排队的机会 会导致性能下降。
更好的办法是不用lru_lock 保护memcg change, 比如拿出PG_lru bit做互斥: 原本的page isoaltion次序是:
get_page; get lru_lock; clear page lru; delete page from lru list. 新的方法是,
get_page; TestClearPageLRU; get lru_lock; delete page from lru list. page isolation互斥从lru lock上移到PG_bit, 通过线性获得PG_lru bit来保证。lru lock只用来保证list的完整性。加上一些code clean up. 新的lru lock保护对象只保留了 lists.
另外lru_lock使用时机还是不变。
时奎亮的per memcg lru lock分享视频
Linux Kernel Page Management and Iru List Locking Optimization - OpenAnolis龙蜥操作系统开源社区
相关文章:

Linux memcg lru lock提升锁性能
目录 内核关于per memcg lru lock的重要提交: 计算虚拟地址转换基本机制 问题背景 swap换入流程 时奎亮的per memcg lru lock分享视频 内核关于per memcg lru lock的重要提交: f9b1038ebccad354256cf84749cbc321b5347497 6168d0da2b479ce25a4647d…...
【spring】引入 Jackson 依赖 对java对象序列号和反序列化
Jackson Jackson 是一个非常流行的 Java 序列化/反序列化库,用于将 JSON 转换为 Java 对象,或者将 Java 对象转换为 JSON。要在你的 pom.xml 文件中引入 Jackson 依赖,你可以按照下面的步骤进行操作。引入 Jackson 依赖 通常,Jackson 核心库包含以下三个部分: jackson-dat…...
算法面经手撕系列(3)--手撕LayerNormlization
LayerNormlization 在许多的语言模型如Bert里,虽然都是说做的LayerNormlization,但计算均值和方差只会沿着channel维度做,并不是沿着seq_L和channel维度一起做,参考:BERT用的LayerNorm可能不是你认为的那个Layer Norm LayerNorm…...

出厂非澎湃OS手机解BL锁
脚本作者:酷安mlgmxyysd 脚本项目链接:https://github.com/MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass/ 参考 B站作者:蓝空穹 https://www.bilibili.com/read/cv33210124/ 其他参考:云墨清风、水墨青竹、Magisk中文网 决定解BL…...
Go语言错误处理之道:优雅地应对程序中的问题
错误处理是任何编程语言中的关键部分,Go语言以其独特的错误处理机制而著称。对于初学者来说,理解Go语言中的错误处理对于编写健壮和可靠的程序至关重要。 为什么需要错误处理 在编程中,错误处理是必不可少的,因为程序可能会遇到…...
LIMS实验室管理系统的特点
LIMS实验室管理系统在实验室管理中发挥着不可或缺的作用。首要特点是其强大的自动化数据管理功能,该系统能够无缝集成实验室从样品接收到测试结果录入与存储的全过程,显著提升了数据的准确性和可靠性,减少了人为错误的可能性。 流程优化是LI…...

vue之 package.json和package-lock.json
一、package.json 定义了当前项目所需要引用的各个模块,可以手工修改配置,也可以删除后,使用npm init命令重新自动生成。 但是该文件只锁定大版本号,也就是版本号的第一位,所以你会发现两个文件中同一个包的版本号不一…...

android 老项目中用到的jar包不存在,通过离线的方法加载
1、之前的项目用的jar包,已经不在远程仓库中,只能手工去下载,并且安装。 // implementation com.github.nostra13:Android-Universal-Image-Loader // implementation com.github.lecho:hellocharts-android:v1.5.8 这…...
每天五分钟玩转深度学习框架PyTorch:梯度下降之学习率衰减
本文重点 我们前面学习了优化器optim,然后学习了为神经网络不同层设置不同的学习率,本节课程我们讲解学习率衰减的方法,也就是说如何在训练过程中动态的修改学习率,本文介绍两种方法。本文是学习第6步(优化器) 为什么要进行学习率衰减 对于一阶梯度进行优化的方法而言,…...

智能家居配上高颜值UI,瞬间感觉消费不起了呢
高颜值的UI设计可以给智能家居产品带来奢华和高端的感觉,为大家分享一波搞颜值界面。 高颜值的智能家居界面设计可以带来以下优势和好处: 用户体验提升: 高颜值的界面设计可以提升用户的视觉享受和满意度。精美的界面设计可以给用户带来愉…...
Winform登录实现及工具栏切换
1、登录实现 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace LoginApp {public par…...
Git bash使用
将本地文件推送到github上 先在所在文件夹进行初始化 git init绑定你的远程仓库 git remote add origin URL 随即 git add 指定文件 ——将工作区域中的文件添加到缓冲区 git commit -m【提交附带的信息】 git push origin master 推送到远程仓库 推送的时候可能会出现一些情…...

Java入门程序-HelloWorld
Java程序开发的三个步骤 1.编写代码得到 .java 源代码文件 2.使用javac编译得到 .class 字节码文件 3.使用java运行 注意事项 建议代码文件名全英文,首字母大写,满足驼峰命名法,源代码文件的后缀必须是.java 开发HelloWorld程序 &…...

计算机人工智能前沿进展-大语言模型方向-2024-09-12
计算机人工智能前沿进展-大语言模型方向-2024-09-12 1. PharmaBench: Enhancing ADMET benchmarks with large language models Z Niu, X Xiao, W Wu, Q Cai, Y Jiang, W Jin, M Wang… - Scientific Data, 2024 大语言模型在药物发现中的应用:PharmaBench 文章由…...

Android MediaPlayer + GLSurfaceView 播放视频
Android使用OpenGL 播放视频 概述TextureView的优缺点OpenGL的优缺点 实现复杂图形效果的场景参考 概述 在Android开发中,使用OpenGL ES来渲染视频是一种常见的需求,尤其是在需要实现自定义的视频播放界面或者视频特效时。结合MediaPlayer,我…...

gitee远程仓库OPEN GIT BASH HERE从错误中学习
推荐一个ai软件(搜索器搜索kimi),是一个ai,有什么错误跟着一步步解决就可以了 当你创建一个仓库 会出现这些 打开这个窗口跟着敲就行了 到这里为止我还没出现错误,后面我把remote add添加远程仓库的地址输错地址了 所…...
如何查看当前系统中所有具有sudo权限的用户?
要查看当前系统中所有具有 sudo 权限的用户,你可以使用以下方法: 方法一:查看 /etc/sudoers 文件 你可以直接查看 /etc/sudoers 文件,找到具有 sudo 权限的用户和用户组。请使用 visudo 命令来编辑和查看该文件,因为…...

在线制作PPT组织架构图!这个AI工具简单又好用!
ppt组织架构图如何制作,用哪个软件好? 在现代商业世界中,组织架构图是展示公司结构和层级关系的重要工具,譬如内部沟通或者对外展示等场合下,一个精美且清晰的组织架构图都能有效传达信息,提升企业形象。 …...
Mysql 视图存储过程触发器
初识: 在 MySQL 中,视图(View)、存储过程(Stored Procedure)和触发器(Trigger)是用于管理和操作数据库的高级功能。它们各自有不同的用途和优势。 2. 视图 (View) 视图是一个虚拟表,它是从一个或多个表中获取数据的结果。视图并不存储数据本…...

【天池比赛】【零基础入门金融风控 Task2赛题理解】实战进行中……20240915更新至2.3.4.3 查看训练集测试集中特征属性只有一值的特征
2.3 代码示例 2.3.1 导入数据分析及可视化过程需要的库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import datetime import warnings warnings.filterwarnings(ignore) 2.3.2 读取文件 #读取数据时相对路径载入报错时…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...