当前位置: 首页 > news >正文

【线程安全的讨论(一)】CPU多核缓存架构和JMM

CPU多核缓存架构

  • 一、CPU多核缓存架构
    • 可见性问题
    • 乱序执行(指令重排)
  • 二、JMM——Java内存模型

一、CPU多核缓存架构

计算机的基本组成图

在这里插入图片描述CPU 缓存为了提高程序运行的性能,现代 CPU 在很多方面会对程序进行优化。CPU 的处理速度很快,内存的速度是其次的,磁盘的速度更慢(由于 CPU 向内存中获取数据得经过系统总线等原因,会影响 CPU 整体的执行效率,所以设置了多级缓存策略)。

在这里插入图片描述

CPU 分为三级缓存:每个 CPU 都有 L1、L2缓存,但是L3缓存是多核公用的。
CPU 查找数据的顺序为:CPU->L1->L2->L3->内存->磁盘.

在这里插入图片描述

从CPU到大约需要的时间
主存60~80纳秒
L3 cache大约15纳秒
L2 cache大约3纳秒
L1 cache大约1纳秒
寄存器大约0.3纳秒

进一步优化,CPU 每次读取一个数据,并不是仅仅读取这个数据本身,而是会读取到与它相邻的64个字节的数据,称之为【缓存行】,因为 CPU 认为,我使用了这个变量,很快就会使用与它相邻的数据,这是计算机的局部性原理。这样,就不需要每次都从主存中读取数据了。MySQL进行IO操作获取表数据也是这样的,会多取相邻的数据放入页中。

可见性问题

在多级缓存的结构下,最经典的问题就是【可见性问题】,即每个逻辑 CPU 都有自己的缓存,这些缓存和主存之间不是完全同步的。

比如:两个 CPU 读取了一个缓存行,缓存行里有两个变量,一个x一个y。每一颗CPU修改了x的数据,还没有刷回主存,此时第二颗CPU,从主存中读取了未修改的缓存行,而此时第一颗CPU修改的数据刷回主存,这时就出现,第二颗CPU读取到的数据和主存不一致的情况。当然刷回到主存只是时间问题,产生可见性问题也是概率性事件。

为了解决数据不一致的问题,很多厂商也提出了自己的解决方案,比如缓存一致性协议(MESI),该协议虽解决了缓存一致性问题,但是对性能有很大损耗,当然CPU的设计者也对其进行了优化,这里小编不多阐述。

乱序执行(指令重排)

除了增加高速缓存提高性能以外,为了使处理器内部的运算单元尽量被充分利用。处理器可能会对输入的代码进行【乱序执行】,优化处理器会在计算之后将乱序执行的结果【进行重组】,保证该结果与顺序执行的结果是一致的,但不保证程序中各语句的先后执行顺序与输入代码的顺序一致,因此如果存在一个计算任务,依赖于另一个依赖任务的中间,结果那么顺序性不能靠代码的先后顺序来保证。Java虚拟机的即时编译器中也有【指令重排】的优化。

举个例子:现在我们有这么一个需求,有四条指令,这四条指令分别是让四个人在四张纸上写下【新年快乐】四个字。但是在这个过程当中,有的人写的快,有的人写得慢,而如果我们非要按照新年快乐这四个顺序去执行这个工作的话,可能时间会浪费的多一点,那我们不妨让这四个人分别去写他们这四个字儿,我们等着这四个人最后一个写完了,然后再把这四个字组合在一起,我们就达到目的了,这样的乱序执行效率可能会更高一些。

二、JMM——Java内存模型

Java 虚拟机规范中曾经试图定义一种Java内存模型,来屏蔽各种硬件和操作系统的内存访问之间的差异,以实现让Java程序在各种平台上都能达到一致的内存访问效果。在此之前,主流程序语言直接使用物理内存和操作系统的内存模型,会由于不同平台的内存模型差异,可能导致程序在一套平台上发挥完全正常,在另一台就可能发生错误,所以在某种常见的场景下,必须针对平台来进行代码的编写。

在这里插入图片描述在Java内存模型中,仍然是存在可见性问题和指令重排问题的。

http://www.lryc.cn/news/103440.html

相关文章:

  • 以太网交换机的生成树协议STP
  • 手机照片转换成pdf怎么做?了解这几种方法就可以了
  • 跨境电商还有人在做吗,这十大选品技巧建议收藏!
  • HTML快速学习
  • centos7搭建k8s环境并部署springboot项目
  • nuitka打包软件程序
  • 12-3_Qt 5.9 C++开发指南_创建和使用静态链接库
  • conda模式安装paddlepaddle2.4.2版本
  • 英语疑问句
  • k8s证书更新,kubeadm安装的K8S证书过期后无法使用后证书更新方法
  • java实现日期拆分的方法
  • Ansible之playbook剧本编写
  • 【ChatGPT辅助学Rust | 基础系列 | Hello, Rust】编写并运行第一个Rust程序
  • 自监督去噪:Noise2Noise原理及实现(Pytorch)
  • BES2700 SDK绝对时间获取方法
  • Closure Table-树形多级关系数据库设计(MySql)
  • 【SQL应知应会】表分区(一)• MySQL版
  • java语法基础-- 变量、标识符、关键字
  • [STL]stack和queue模拟实现
  • 汽车销售企业消费税,增值税高怎么合理解决?
  • flask数据库操作
  • 【C++】 哈希
  • TCP三次握手和四次挥手以及11种状态(二)
  • 【华为OD】运维日志排序
  • Mag-Fluo-4 AM,镁离子荧光探针,是一种有用的细胞内镁离子指示剂
  • 与 ChatGPT 进行有效交互的几种策略
  • 华为云安装MySQL后,本地工具连接MySQL失败
  • Flink On Yarn模式部署与验证
  • [数据库]对数据库事务进行总结
  • 【Lua学习笔记】Lua进阶——Table(2)