linux 内存一致性

linux 出现内存一致性的场景

1、编译器优化 ,代码上下没有关联的时候,因为编译优化,会有执行执行顺序不一致的问题(多核单核都会出现)
2、多核cpu乱序执行,cpu的乱序执行导致内存不一致(多核出现)
3、dma 操作,dma操作外设,或者内存数据,cpu无法感知,仍然使用cache 数据,导致内存不一致(多核单核都会出现)

内存屏障

cpu 乱序导致的问题

如果CPU需要读取的地址中的数据已经已经缓存在了cache line中,即使是cpu需要对这个地址重复进行读写,对CPU性能影响也不大,但是一旦发生了cache miss(对这个地址进行第一次写操作),如果是有序处理器,CPU在从其他CPU获取数据或者直接与主存进行数据交互的时候需要等待不可用的操作对象,这样就会非常慢,非常影响性能。举个例子:

如果CPU0发起一次对某个地址的写操作,但是其local cache中没有数据,这个数据存放在CPU1的local cache中。为了完成这次操作,CPU0会发出一个invalidate的信号,使其他CPU的cache数据无效(因为CPU0需要重新写这个地址中的值,说明这个地址中的值将被改变,如果不把其他CPU中存放的该地址的值无效,那么就有可能会出现数据不一致的问题)。只有当其他之前就已经存放了改地址数据的CPU中的值都无效了后,CPU0才能真正发起写操作。需要等待非常长的时间,这就导致了性能上的损耗。

但是乱序处理器山就不需要等待不可用的操作对象,直接把invalidate message放到invalidate queues中,然后继续干其他事情,提高了CPU的性能,但也带来了一个问题,就是程序执行过程中,可能会由于乱序处理器的处理方式导致内存乱序,程序运行结果不符合我们预期的问题。

解决的办法-内存屏障

CPU内存屏障,指令

1、通用barrier,保证读写操作有序, mb()和smp_mb()

2、写操作barrier,仅保证写操作有序,wmb()和smp_wmb()

3、读操作barrier,仅保证读操作有序,rmb()和smp_rmb()

编译器重排导致的问题

int flag, data;void write_data(int value)
{data = value;flag = 1;
}void read_data(void)
{int res;while (flag == 0);res = data;flag = 0;return res;
}

我们拥有2个线程,一个用来更新数据,也就是更新data的值。使用flag标志data数据已经准备就绪,其他线程可以读取。另一个线程一直调用read_data(),等待flag被置位,然后返回读取的数据data。

如果compiler产生的汇编代码是flag比data先写入内存。那么,即使是单核系统上,我们也会有问题。在flag置1之后,data写45之前,系统发生抢占。另一个进程发现flag已经置1,认为data的数据已经准别就绪。但是实际上读取data的值并不是45(可能是上次的历史数据或者非法数据)。为什么compiler还会这么操作呢?因为,compiler是不知道data和flag之间有严格的依赖关系。这种逻辑关系是我们人为强加的

解决的办法-显式编译屏障

#define barrier() __asm__ __volatile__("": : :"memory")int a, b;void foo(void)
{a = b + 1;barrier();b = 0;
}

barrier()就是compiler提供的屏障,作用是告诉compiler内存中的值已经改变,之前对内存的缓存(缓存到寄存器)都需要抛弃,barrier()之后的内存操作需要重新从内存load,而不能使用之前寄存器缓存的值。并且可以防止compiler优化barrier()前后的内存访问顺序。barrier()就像是代码中的一道不可逾越的屏障

对于单个变量可以使用 volatile 或者是指针变量

dma 内存不一致

那DMA为什么和CPU的cache会产生cache一致性的问题呢,基本的原因的什么呢?我这里总结了几个。
1、DMA直接操作系统总线来读写内存地址,而CPU并不感知。
2、如果DMA修改的内存地址,在CPU的cache中有缓存,那么CPU并不知道内存数据被修改了,CPU依然去访问cache的旧数据,导致Cache一致性问题。

dam cache 一致性解决方法

1、使用硬件cache一致性的方案,需要CCI这种IP的支持。这个需要去查看一下你用的soc是否支持CCI控制器。

2、使用non-cacheable的内存来进行DMA传输,这种方案最简单,但效率最低,严重降低性能,还增加功耗。

3、使用软件主动干预的方法来帮助cache一致性。这个是比较常规的方法,特别是在类似CCI这种缓存一致性控制器没有出来之前,都用这种方式。对于DMA的操作,我们需要考虑两种情况。

软件干预dma 操作

在这里插入图片描述理解这里为什么要先做cache的clean或者flush操作的一个关键点是:比如这个图里,大家要想清楚,在DMA开始传输之前,最新的数据在哪里?很明显,在这个图里,在这个场景下的逻辑,最新数据有可能还在cache里,因为主机的软件产生数据,比如网卡发包,CPU的网络软件去组包,这个组包的过程,其实可以看成是CPU去create了新的数据,然后CPU把数据存在内存的DMA buffer里,这个过程中,有可能还有新的数据在CPU的cache里。所以,在启动DMA之前,我们需要调用cache的flush操作,把cache的数据回写到DMA buffer里。这个就是这个逻辑。

1、 在DMA拷贝前,进行一次CACHE CLEAN,将cache内容dirty回写,清除cache,保证在DMA传输时间内不会有回写动作,(也叫做写回(Writeback):DMA从内存中读取数据时,先强制将Cache中的内容写回到内存中)
2、 在DMA拷贝完成之后,进行一次CACHE FLUSH,保证CPU访问目的地址时cache会重新构建,目的地址的值一定是从DDR上读取最新数据。(也叫做写无效(Invalidate):DMA向内存中写入数据完成后,直接令Cache中的内容无效。这样CPU在读取Cache时必然要先从内存中读取数据到Cache)

一些嵌入式平台可能包括两级Cache,称为Inner Cache和Outer Cache。前者是内部Cache,位于CPU内部,也称为一级Cache或L1 Cache;后者是外部Cache,位于CPU外部,也称为二级Cache或L2 Cache。

几个常见的嵌入式平台如ARM、MIPS、PPC都采用软件管理Cache,提供相应的接口来管理Cache,但需要我们编写代码主动操作Cache。以ARM平台为例,Linux对DMA的数据一致性操作函数为dmac_flush_range()函数和outer_flush_range()函数,两个函数都同时进行了写无效操作和写回操作确保数据一致性。

1、针对Inner Cache。

extern void dmac_flush_range(const void *, const void *);

2、针对Outer Cache。

static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)

参考网址:
https://blog.csdn.net/baidu_38797690/article/details/123234019
https://zhuanlan.zhihu.com/p/465411610
https://www.cnblogs.com/jerry116/articles/9206061.html
https://zhuanlan.zhihu.com/p/505956490?utm_id=0

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elasticSearch+kibana+logstash+filebeat集群改成https认证

文章目录 一、生成相关证书二、配置elasticSearh三、配置kibana四、配置logstash五、配置filebeat六、连接https es的java api 一、生成相关证书 ps:主节点操作 切换用户:su es 进入目录:cd /home/es/elasticsearch-7.6.2 创建文件&#x…

OpenCV(十三):图像中绘制直线、圆形、椭圆形、矩形、多边形和文字

目录 1.绘制直线line() 2.绘制圆形circle() 3.绘制椭圆形ellipse() 4.绘制矩形rectangle() 5.绘制多边形 fillPoly() 6.绘制文字putText() 7.例子 1.绘制直线line() CV_EXPORTS_W void line(InputOutputArray img,Point pt1, Point pt2,const Scalar& color,int t…

【数据结构与算法 三】常见数据结构与算法组合应用方式

一般的数据结构和对应的 很抱歉,作为一个文本AI模型,我无法直接绘制图表,但我可以为您列出常见的算法和数据结构分类,并为每个分类提供简要说明。您可以根据这些信息自行绘制图表。 算法分类: 搜索算法:用于在数据集中查找特定元素的算法,如线性搜索、二分搜索等。 排…

MTK6761/MT6761安卓核心板4G安卓智能模块详细参数性能介绍

MTK6761 安卓核心板采用12nm制程四核Cortex-A53、最高主频2.0GHZ 处理器,板载内存为 1GB8GB(2GB16GB、3GB32GB、4GB64GB),搭载Android 9.0操作系统。 MTK6761(曦力 A22)安卓核心板基本概述 MTK6761安卓核心板 是一款高性能低功耗…

HikariCP源码修改,使其连接池支持Kerberos认证

HikariCP-4.0.3 修改HikariCP源码,使其连接池支持Kerberos认证 修改后的Hikari源码地址:https://github.com/Raray-chuan/HikariCP-4.0.3 Springboot使用hikari连接池并进行Kerberos认证访问Impala的demo地址:https://github.com/Raray-chuan/springboot-kerberos-hikari-im…

2023 AZ900备考

文章目录 如何学习最近准备考AZ900考试,找了一圈文档,结果发现看那么多文档,不如直接看官方的教程https://learn.microsoft.com/zh-cn/certifications/exams/az-900/ ,简单直接,突然想到纳瓦尔宝典中提到多花时间进行思…

博客系统自动化测试项目实战(测试系列9)

目录 前言: 1.博客前端页面测试用例图 2.测试用例的代码实现 2.1登录页面的测试 2.2博客列表页面的测试 2.3写博客测试 2.4博客详情页面的测试 2.5已发布博客的标题和时间的测试 2.6注销用户的测试 结束语: 前言: 之前小编给大家讲…

Java学习笔记之----I/O(输入/输出)一

在变量、数组和对象中存储的数据是暂时存在的,程序结束后它们就会丢失。想要永久地存储程序创建的数据,就需要将其保存在磁盘文件中(就是保存在电脑的C盘或D盘中),而只有数据存储起来才可以在其他程序中使用它们。Java的I/O技术可…

Shell开发实践:服务器的磁盘、CPU、内存的占用监控

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…

Flutter 安装教程 + 运行教程

1.下载依赖 https://flutter.cn/docs/get-started/install/windows 解压完后根据自己的位置放置,如(D:\flutter) 注意 请勿将 Flutter 有特殊字符或空格的路径下。 请勿将 Flutter 安装在需要高权限的文件夹内,例如 C:\Program …

Elasticsearch终端命令行用法大全

API作用使用场景curl localhost:9200/_cluster/health?pretty查看ES健康状态curl localhost:9200/_cluster/settings?pretty查看ES集群的设置其中persistent为永久设置,重启仍然有效;trainsient为临时设置,重启失效curl localhost:9200/_ca…

锐捷盒式交换机S5760C版本U盘升级

1.确认设备当前版本信息 2.将升级文件包放置U盘文件夹中, U盘名称123 , 文件夹名称A 3.查看到升级包后,进行U盘升级 #upgrade usb0:/A/S5760X_RGOS12.5(4)B0702P4_install.bin 4.升级成功后 reload交换机 5.等交换机重启完毕,再次…

【Dart】学习使用(二):基本类型

前言 基本类型是语言的基础。 Dart 语言支持以下基础类型:Numbers(int、double), 整形Strings(String), 字符串Booleans(bool) , 布尔型Records((value1,value2)) 记录Lists(List ) 数组Sets(Set) 集合Maps(Map) 映射Runes(Runes,通常由 characters AP…

支付宝使用OceanBase的历史库实践分享

为解决因业务增长引发的数据库存储空间问题,支付宝基于 OceanBase 数据库启动了历史库项目,通过历史数据归档、过期数据清理、异常数据回滚,实现了总成本降低 80%。 历史数据归档:将在线库(SSD 磁盘)数据归…

基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作

文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量化的综合性知识体系。特别是,信息可视化技术手段和方法的运用,可直观的展示主题的研究发展历程、研究现状、研究…

ELK原理和介绍

为什么用到ELK: 一般我们需要进行日志分析场景:直接在日志文件中 grep、awk 就可以获得自己想要的信息。但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。需要集中化…

Ansible学习笔记11

Command和Shell模块&#xff1a; 两个模块都是用于执行Linux命令的&#xff0c;这个对于命令熟悉的工程师来说&#xff0c;用起来非常high。 Shell模块跟Command模块差不多&#xff08;Command模块不能执行一类$HOME、> 、<、| 等符号&#xff0c;但是Shell是可以的。&…

大学物理 之 安培环路定理

文章目录 前言什么是安培环路定理安培环路定理有什么作用 深入了解深入学习 前言 什么是安培环路定理 安培环路定理的物理意义在于描述了电流和磁场之间的相互作用&#xff0c;以及如何在一个封闭的回路中分析这种相互作用。 简单的来说 , 用环路定理来解决在磁场中B对任意封…

java基础-----第九篇

系列文章目录 文章目录 系列文章目录前言一、GC如何判断对象可以被回收前言 一、GC如何判断对象可以被回收 引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计 数为0时可以回收, 可达性分析法:从 GC Roots 开始向下搜索,搜索所走过的…

TCP Header都有啥?

分析&回答 源端口号&#xff08;Source Port&#xff09; &#xff1a;16位&#xff0c;标识主机上发起传送的应用程序&#xff1b; 目的端口&#xff08;Destonation Port&#xff09; &#xff1a;16位&#xff0c;标识主机上传送要到达的应用程序。 源端&#xff0c;目…