cpu缓存一致性
文章目录
- cpu缓存一致性
- 缓存的出现:
- 多核之后带来的缓存一致性问题,如何解决
- LOCK 指令(刚好可以实现上述的目标)
- LOCK 指令特性
- 内存屏障特性
- 编译器屏障的作用
- MESI协议
- 为什么有了 MESI协议 还需要 内存屏障
- 问题:
- 总结:
- 附带:
- 参考
cpu缓存一致性
缓存的出现:
- 提高内存的访问速度(时间、空间局部性),指令、数据的预取
多核之后带来的缓存一致性问题,如何解决
-
锁总线
-
MESI 协议(总线嗅探机制)+ 内存屏障
LOCK 指令(刚好可以实现上述的目标)
- 早期:锁总线(实现,性能差)
后期:锁缓存(实现,Ringbus + MESI协议,硬件支持,无需软件实现) - 内存屏障
LOCK 指令特性
- 硬件层面提供 lfence、sfence、mfence 三个内存屏障以及一个可以实现相同效果的 lock 指令前缀
- 一般lock都会加入读屏障,保证后续代码可以读到别的cpu核心上的未回写的缓存数据,而unlock都会加入写屏障,将所有的未回写的缓存进行回写。
内存屏障特性
- 所有的CPU内存屏障封装都隐式包含了编译器屏障。
- 只有内存屏障是无法保证缓存的同步的,还需要MESI一致性协议的支持
编译器屏障的作用
- 防止编译乱序
- 数据重新load缓存
MESI协议
- 保证了单条指令的在缓存上的读写的一致性
- MESI协议可以通过提供加入缓存带来的数据一致性问题,但是会带来一些性能的消耗,比如说缓存的伪共享
- MESI是强一致性,强一致性必定会带来性能的损害
为什么有了 MESI协议 还需要 内存屏障
- MESI是强一致性的,比如:需要等待写失效才能写入内存,所以硬件又引入了store buffer还有invalid queue,导致了有可能cpu 的乱序执行,为了禁止这种乱序执行需要加入内存屏障,但是这种乱序执行的前提是(数据之间没有依赖性)
问题:
-
那如果当前访问的数据在寄存器上面呢
- 需要 用到 volatile指令,强制从缓存中读取一次数据,间接通过MESI协议能够访问到内存中的数据
-
那如果是多条指令的顺序性呢,内存数据还在store buffer、invalid queue上面呢?
- 需要用到 内存屏障的指令,比如 x86 fence
总结:
- volatile指令的作用(cpp的volatile和java的特性不一致)
- c++ volatile 的特性
- 禁止编译器的优化
- 禁止编译器的代码的重排序
- 强制从缓存中读取,失效寄存器
- java volatile 的特性:是基于 LOCK 指令 实现的
- 在cpp的特性的基础之上
- 实现了一个全屏障(越过cpu的乱序执行、指令重排序等,保证了数据的顺序一致性)
- c++ volatile 的特性
- 缓存的一致性保证是通过 MESI 协议(总线嗅探机制)+ 内存屏障 实现的,因此为什么说 尽管有了 CPU有缓存一致性协议(MESI),为什么JMM还需要volatile关键字(主要是增加屏障的目的,单靠MESI协议无法保证 整体顺序的一致性)
附带:
// (java 9) hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp
// java实现的内存屏障
inline void OrderAccess::loadload() { compiler_barrier(); }
inline void OrderAccess::storestore() { compiler_barrier(); }
inline void OrderAccess::loadstore() { compiler_barrier(); }
inline void OrderAccess::storeload() { fence(); }
inline void OrderAccess::acquire() { compiler_barrier(); }
inline void OrderAccess::release() { compiler_barrier(); }
inline void OrderAccess::fence() {if (os::is_MP()) {// always use locked addl since mfence is sometimes expensive
#ifdef AMD64__asm__ volatile ("lock; addl 0,0(%%rsp)" : : : "cc", "memory");
#else__asm__ volatile ("lock; addl0,0(%%esp)" : : : "cc", "memory");
#endif}compiler_barrier();
}
参考
volatile也不过如此
C/C++ Volatile关键词深度剖析
既然CPU有缓存一致性协议(MESI),为什么JMM还需要volatile关键字
相关文章:
cpu缓存一致性
文章目录 cpu缓存一致性缓存的出现:多核之后带来的缓存一致性问题,如何解决LOCK 指令(刚好可以实现上述的目标)LOCK 指令特性内存屏障特性编译器屏障的作用MESI协议为什么有了 MESI协议 还需要 内存屏障问题:总结&…...
Android Framework 常见解决方案(25-1)定制CPUSET解决方案-framework部分修改
1 原理说明 这个方案有如下基本需求: 构建自定义CPUSET,/dev/cpuset中包含一个全新的cpuset分组。且可以通过set_cpuset_policy和set_sched_policy接口可以设置自定义CPUSET。开机启动后可以通过zygote判定来对特定的应用进程设置CPUSET,并…...
PyTorch 参数化深度解析:自定义、管理和优化模型参数
目录 torch.nn子模块parametrize parametrize.register_parametrization 主要特性和用途 使用场景 参数和关键字参数 注意事项 示例 parametrize.remove_parametrizations 功能和用途 参数 返回值 异常 使用示例 parametrize.cached 功能和用途 如何使用 示例…...

自承载 Self-Host ASP.NET Web API 1 (C#)
本教程介绍如何在控制台应用程序中托管 Web API。 ASP.NET Web API不需要 IIS。 可以在自己的主机进程中自托管 Web API。 创建控制台应用程序项目 启动 Visual Studio,然后从“开始”页中选择“新建项目”。 或者,从“ 文件 ”菜单中选择“ 新建 ”&a…...
Vue2-子传父和父传子的基本用法
在Vue 2中,可以使用props和$emit来实现子组件向父组件传值(子传父)和父组件向子组件传值(父传子)。 子传父(子组件向父组件传值)的基本用法如下: 在父组件中定义一个属性ÿ…...

使用numpy处理图片——镜像翻转和旋转
在《使用numpy处理图片——基础操作》一文中,我们介绍了如何使用numpy修改图片的透明度。本文我们将介绍镜像翻转和旋转。 镜像翻转 上下翻转 from PIL import Image import numpy as np img Image.open(example.png) data np.array(img)# axis0 is vertical, a…...

HTML5 article标签,<time>...</time>标签和pubdate属性的运用
1、<article>...</article>标签的运用 article标签代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。它可以是一篇博客或报竟杂志中的文章、一篇论坛帖子、一段用户评论或一个独立的插件,或者其他任何独立的内容。把文章正文放在h…...

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用
分享一个有趣的小工具,10MB 身材的小工具,能够将各种不同的模型 API 转换为开箱即用的 OpenAI API 格式。 让许多依赖 OpenAI API 的软件能够借助开发者能够接触到的,非 OpenAI 的 API 私有部署和使用起来。 写在前面 这个小工具软件写于两…...

RK3568平台开发系列讲解(驱动篇)pinctrl 函数操作集结构体讲解
🚀返回专栏总目录 文章目录 一、pinctrl_ops二、pinmux_ops三、pinconf_ops沉淀、分享、成长,让自己和他人都能有所收获!😄 pinctrl_ops:提供有关属于引脚组的引脚的信息。pinmux_ops:选择连接到该引脚的功能。pinconf_ops:设置引脚属性(上拉,下拉,开漏,强度等)。…...
vue购物车案例,v-model 之 lazy、number、trim,与后端交互
购物车案例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"./js/vue.js"></script> </head> <body> <div id"d1"&…...

云原生Kubernetes: Kubeadm部署K8S 1.29版本 单Master架构
目录 一、实验 1.环境 2.K8S master节点环境准备 3.K8S master节点安装kubelet、kubeadm、kubectl 3.K8S node节点环境准备与软件安装 4.K8S master节点部署服务 5.K8S node节点部署 6.K8S master节点查看集群 7.容器网络(CNI)部署 8.K8S 集群…...

C++协程操作
什么是C++协程 C++中的协程是一种用户态轻量级线程,它拥有自己的上下文和栈,并且协程的切换和调度由用户定义,不需要陷入内核。如同一个进程可以拥有多个线程,一个线程也可以拥有多个协程。协程的优点在于极高的执行效率,因为协程切换不需要陷入内核,而是由用户程序定义切…...

计算机配件杂谈-鼠标
目录 基础知识鼠标的发展鼠标的左右手鼠标的显示样式鼠标的移动和可见性移动可见性 现在的我们的生活工作都基本上离不开电脑了,不管是你平时玩玩游戏,上班工作等等; 今天将关于鼠标的一些小的技巧分享出来,共勉! 基础…...

用Python来制作一个微信聊天机器人
1. 效果展示 通过本地搭建一个flask服务器来接收信息,这里我简单使用展示,就没有对接收的信息进行处理了。 信息接收展示 发送信息展示 这里就直接使用python发送一个post请求即可,可以发送文字或者图片 代码展示 接收信息 #!/usr/bin/e…...

2024年第九届机器学习技术国际会议(ICMLT 2024) 即将召开
2024年第九届机器学习技术国际会议(ICMLT 2024)将于2024年5月24-26日在挪威奥斯陆举行。ICMLT 2024旨在讨论机器学习技术领域的最新研究技术现状和前沿趋势,为来自世界各地的科学家、工程师、实业家、学者和其他专业人士提供一个互动和交流的…...
算法训练day9Leetcode232用栈实现队列225用队列实现栈
今天学习的文章和视频链接 https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 栈与队列理论基础 见我的博客 https://blog.csdn.net/qq_36372352/article/details/135470438?spm1001.2014.3001.5501 232用栈实现…...

linux驱动(四):platform
本文主要探讨x210驱动的平台设备类型(platform)以及misc设备。 驱动模型 设备驱动模型:总线(bus type)、设备(device)和驱动(driver) 总线:虚拟总线用于挂接驱动驱动和设备 总线、设备、驱动关系:/sys/bus下的子目录…...

Guava:Cache强大的本地缓存框架
Guava Cache是一款非常优秀的本地缓存框架。 一、 经典配置 Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似,提供了基于时间、容量、引用三种回收策略,以及自动加载、访问统计等功能。 基本的配置 Testpublic void testLoadingCache() th…...
#{}和${}的区别?
#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。Mybatis在…...

string的模拟实现
string的模拟实现 msvc和g下的string内存比较成员变量构造函数与析构函数拷贝构造函数赋值拷贝c_str、size和capacity函数以及重载[]、clear、expand_capacity迭代器与遍历reservepush_back、append、insert字符串比较运算符erase<<流提取 >>流插入resizefindsubst…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...