Linux源码阅读笔记06-RCU机制和内存优化屏障

RCU机制

RCU(Read-Copy-Update),是Linux内核重要的同步机制。Linux内核有原子操作,读写信号量,为什么要单独设计一个比较复杂的新机制呢?

  • spinlock和mutex信号量都使用了原子操作,多CPU在访问共享变量的时候Cache一致性会变得非常糟糕,有时候会使得整个性能下降。
  • 允许多个读者存在,但是读和写不能同时存在。
  • RCU让读者没有或者让同步开销变得更小,不需要锁和原子操作指令。将需要同步的任务交给写线程,等读者线程读完再更新数据。
  • 在RCU机制中如果有多个写的存在,需要额外的保护机制。

原理

RCU记录所有指向共享数据的指针使用者,当要修改共享数据时,首先创建一个副本,在副本中修改。所有读访问线程都离开临界区后,指针指向新的修改后副本的指针,并且删除旧数据。

  • 写者修改:首先复制一个副本,然后更新副本,最后使用新对象替换旧对象。
  • 写者删除对象:必须等待所有访问被删除对象读者访问结束的时候,才能执行销毁操作实现。
  • 优点:RCU优势是读者没有任何同步开销;不需要获取任何锁,不需要执行原子指令。
  • 缺点:写者的同步开销比较大,写者需要延迟释放对象、复制被修改的对象,写者之间必须使用锁互斥操作的方法。

用于读者性能要求高的场景。只保护动态分配的数据结构,必须通过指针访问此数据结构;受RCU保护的临界区不能sleep;读写不对成,对写的性能没有要求,但是对读要求高。

应用场景

链表:有效提高遍历读取数据,读取链表成员数据只要rcu_read_lock(),允许多个线程同时读取,允许一个线程同时修改,RCU的意思是读-复制-更新。

static inline void list_add_rcu(struct list_head *new, struct list_head *head)
{
	__list_add_rcu(new, head, head->next);
}

static inline void list_del_rcu(struct list_head *entry)
{
	__list_del_entry(entry);
	entry->prev = LIST_POISON2;
}

  • 替换

在整个操作过程中,要防止编译器和CPU优化代码执行的顺序。smp_wmb()保证在他前两行代码执行完毕再执行后两行。

RCU层次架构

RCU根据CPU数量的大小按照树形结构来组成其层次结构,称为RCU Hierarchy。具体内核源码分析如下:

/*
 * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
 * CONFIG_RCU_FANOUT_LEAF.
 * In theory, it should be possible to add more levels straightforwardly.
 * In practice, this did work well going from three levels to four.
 * Of course, your mileage may vary.
 */

#ifdef CONFIG_RCU_FANOUT
#define RCU_FANOUT CONFIG_RCU_FANOUT
#else /* #ifdef CONFIG_RCU_FANOUT */
# ifdef CONFIG_64BIT
# define RCU_FANOUT 64
# else
# define RCU_FANOUT 32
# endif
#endif /* #else #ifdef CONFIG_RCU_FANOUT */

#ifdef CONFIG_RCU_FANOUT_LEAF
#define RCU_FANOUT_LEAF CONFIG_RCU_FANOUT_LEAF
#else /* #ifdef CONFIG_RCU_FANOUT_LEAF */
#define RCU_FANOUT_LEAF 16
#endif /* #else #ifdef CONFIG_RCU_FANOUT_LEAF */

#define RCU_FANOUT_1	      (RCU_FANOUT_LEAF)
#define RCU_FANOUT_2	      (RCU_FANOUT_1 * RCU_FANOUT)
#define RCU_FANOUT_3	      (RCU_FANOUT_2 * RCU_FANOUT)
#define RCU_FANOUT_4	      (RCU_FANOUT_3 * RCU_FANOUT)

RCU层次结构根据CPU熟练决定,内核中有宏帮助构建RCU层次结构,其中

CONFIG_RCU_FANOUT_LEAF表示一个子叶子节点的CPU数量,CONFIG_RCU_FANOUT表示每个层数最多支持多少个叶子数量。

优化内存屏障

优化屏障

在编程的时候,指令一般不按照源程序顺序执行,原因是为了提高程序性能,会对他进行优化,主要分两种:编译器优化和CPU执行优化。优化屏障避免编译的重新排序优化操作,保证编译程序时在优化屏障之前的指令不会在优化屏障之后执行。

  • 编译器优化:为提高系统性能,编译器在不影响逻辑的情况下会调整指令的执行顺序。
  • CPU执行优化:为提高流水线性能,CPU的乱序执行可能会让后面的寄存器重提的汇编指先于前面指令完成。

Linux使用宏barrier实现优化屏障,如gcc编译器的优化屏障宏定义具体查阅Linux源码如下:

/* Optimization barrier */

/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")

内存屏障

内存屏障(也称内存栅障或屏障指令等),是一类同步屏障指令,是编译器或CPU对内存访问操作的时候,严格按照一定顺序来执行,也就是memory barrier之前的指令和memory barrier之后的指令不会由于系统优化等原因而导致乱序的。

Linux内核支持三种内存屏障:编译器屏障、处理器屏障、【内存映射I/O写屏障(Memory Mapping I/O,MMIO)。此屏障已废弃新驱动不应该使用】

  • 内存屏障是一种保证访问顺序的方法,解决内存屏障内存访问乱序问题:
    1. 编译器编译代码时可能重新排序汇编指令,使编译出来的程序在处理器上执行速度更快,但是有时候优化的结果可能不符合软件开发工程师的意图。
    2. 新式处理器采用超标量体系结构和乱序执行技术,能够在一个时钟周期并行执行多条指令。一句话总结为:顺序取指令,乱序执行,顺序提交执行结果。
    3. 多处理器系统中,硬件工程师使用存储缓冲区、使无效队列协助缓存和缓存一致性协议实现高性能,引入处理器之间的内存访问乱序问题。
  • 使用顺序

假使使用禁止内核抢占方法保护临界区:

preempt_desable();

临界区

preempt_enable();

  • 为了阻止编译器错误重排指令,在禁止内核抢占和开启内核抢占的里面添加编译器优先屏障,具体如下:

  • GCC编译器定义宏
/* Optimization barrier */

/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")

关键字为__volatile__告诉编译器:禁止优化代码,不需要改变barrier()前面的代码块、barrier()和后面的代码块这三个代码块的顺序。

处理器内存屏障

处理器内存屏障解决CPU之间的内存访问乱序问题和处理器访问外围设备的乱序问题。

内存屏障类型强制性的内存屏障SMP的内存屏障
通用内存屏障mb()smp_mb()
写内存屏障wmb()smp_wmb()
读内存屏障rmb()smp_rmb()
数据依赖屏障read_barrier_depends()smp_read_barrier_depends()
  • 除了数据依赖屏障之外,所有处理器内存屏障隐含编译器优化屏障。
  • SMP屏障只有在SMP系统中才有,在单核心处理器中没有SMP屏障。

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

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

相关文章

在Python中定义和使用函数及模块

我将介绍如何在Python中定义和使用函数,以及如何创建和使用Python模块。这些基础知识将帮助你编写更高效和可复用的代码。 目录 函数基础定义和调用函数参数传递 函数式编程匿名函数高阶函数 装饰器模块和包常用的标准库模块 函数基础 定义和调用函数 定义函数&a…

这样制作宣传册,才能提升品牌的曝光度

​在当今竞争激烈的市场环境中,一份高质量的宣传册不仅可以展示企业的实力和特色,还能有效提升品牌的曝光度。要想制作出既能吸引眼球又能传达信息的宣传册,需要如何制作呢? 1.明确宣传目标:制作翻页电子宣传册之前&am…

C语言·动态内存管理

1. 为什么要有动态内存管理? 例1: //固定的向内存申请4个字节 int a 10;//申请连续的一块空间 int arr[10]; 这些数据一旦声明定义之后就会在内存中有一块空间,这些空间都是固定的,为了让内存使用更加灵活,这时我们…

Spark SQL 血缘解析方案

背景 项目背景建设数据中台,往往数据开发人员首先需要能够通过有效的途径检索到所需要的数据,然后根据检索的数据模型进行业务加工然后得到一些中间模型,最后再通过数据抽取工具或者OLAP分析工具直接将数据仓库中加工好的公共模型输出到应用层。这里我不在去介绍数据仓库为…

【Qt】day2

文章目录 菜单栏工具栏状态栏铆接部件(浮动窗口)中心部件添加图片对话框模态对话框非模态对话框标准对话框(信息对话框)错误对话框信息对话框提问对话框警告对话框 其他标准对话框颜色对话框文件对话框 字体对话框 登录窗口布局按…

《重构》读书笔记【第1章 重构,第一个示例,第2章 重构原则】

文章目录 第1章 重构,第一个示例1.1 重构前1.2 重构后 第2章 重构原则2.1 何谓重构2.2 两顶帽子2.3 为何重构2.4 何时重构2.5 重构和开发过程 第1章 重构,第一个示例 我这里使用的IDE是IntelliJ IDEA 1.1 重构前 plays.js export const plays {&quo…

将 MinIO 与 Keycloak OIDC 集成

Keycloak是一种单点登录解决方案。使用Keycloak,用户使用Keycloak而不是MinIO进行身份验证。如果没有Keycloak,您将不得不为每个用户创建一个单独的身份 - 从长远来看,这将很麻烦。您需要一个集中身份解决方案来管理 MinIO 的身份验证和授权。…

Python深度学习技术

原文链接:Python深度学习技术 近年来,伴随着以卷积神经网络(CNN)为代表的深度学习的快速发展,人工智能迈入了第三次发展浪潮,AI技术在各个领域中的应用越来越广泛。Transformer模型(BERT、GPT-…

3.2 文件包含漏洞渗透实战(OWASP实战训练)

3.2 文件包含漏洞渗透实战(OWASP实战训练) 原理及危害3.低安全级别渗透3.1本地文件包含漏洞3.2 本地文件包含漏洞webshell3.3远程文件包含漏洞 上一节讲了本地文件包含和远程文件包含 本地文件包含需要将文件传上去或者不传上去(本地系统的一…

导出 S 参数扫描结果供 INTERCONNECT 使用

导出 S 参数扫描结果供 INTERCONNECT 使用 正文正文 有时候,对于 FDTD 无法直接进行仿真的大型仿真链路,我们需要使用 FDTD 针对单个小的模块进行仿真,再将得到的 S 参数结果导入到 INTERCONNECT 中使用,最终完成整个链路的仿真。通常完成 S 参数扫描后其状态如下图所示:…

【数据结构】栈的定义与实现(附完整运行代码)

目录 一、栈的定义 二、顺序栈 链栈比较 三、栈的实现(顺序栈) 3.1 ❥ 定义栈结构 3.2 ❥ 初始化 3.3 ❥ 销毁 3.4 ❥ 插入(入栈) 3.5 ❥ 删除 (出栈) 3.6 ❥ 获取栈顶元素 3.7 ❥ 判空 3.8 ❥…

1962springboot VUE社区服务平台系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE社区服务平台系统是一套完善的完整信息管理类型系统,结合springboot框架和VUE完成本系统,对理解vue java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代码和…

光泽正在褪去,所以我们又回到了人工智能领域。

光泽正在褪去,所以我们又回到了人工智能领域。 人工智能冬天将被私有化 自从“人工智能”这个流行词在20世纪50年代被创造出来以来,人工智能经历了几次繁荣和萧条周期。 一种新的技术方法看起来很有趣,并取得了一些成果。它被荒谬地炒作并获…

EdgeOne 边缘函数 + Hono.js + Fauna 搭建个人博客

一、背景 虽然 “博客” 已经是很多很多年前流行的东西了,但是时至今日,仍然有一部分人在维护自己的博客站点,输出不少高质量的文章。 我使用过几种博客托管平台或静态博客生成框架,前段时间使用Hono.jsFauna ,基于 …

热电发电机越来越受到研发关注

热电发电机 (TEG) 利用热量(或更准确地说,温差)和众所周知的塞贝克效应来发电。它们的应用范围从收集可用热能,尤其是在工业和其他情况下“浪费”的热能,到在放射性同位素热发电机 (RTG) 中使用航天器的放射性电源作为…

静电场的基本方程

目录 场积分方程 通量(高斯定理) 环量 场微分方程 散度 旋度 小结 补充知识 立体角 场积分方程 通量(高斯定理) 环量 场微分方程 散度 旋度 小结 补充知识 立体角

慢性病防治新策略:诊所管理系统助力健康管理变革

慢性病,如高血压、糖尿病等,正逐渐成为全球健康领域的重要挑战。据尚普咨询的数据显示,全球每年有4100万人死于慢性非传染性疾病,占全球死亡总数的71%。而在中国,随着经济社会发展和卫生健康服务水平的提高&#xff0c…

OpenAI突然宣布停止向中国提供API服务!

标题 🌟 OpenAI突然宣布停止向中国提供API服务! 🌟摘要 📜引言 📢正文 📝1. OpenAI API的重要性2. 停止服务的原因分析3. 对中国市场的影响4. 应对措施代码案例 📂常见问题解答(QA)❓…

使用AES,前端加密,后端解密,spring工具类了

学习python的时候,看到很多会对参数进行加密,于是好奇心驱使下,让我去了解了下AES加密如何在java中实现。 首先 npm install crypto-js 然后在你的方法中,给你们前端源码看看,因为我用的ruoyi框架做的实验&#xff…

iSCSI driver not found和Failed to start Open-iSCSI的解决方法

案例1:iscsi的配置有问题 方法:一般的处理方法为重装iscsi-initiator-utils。 案例2:linux安装了多个内核,启动所选的内核与iscsi服务不匹配 方法:重启系统,选择对应的内核版本启动系统。 (注…