引入高速缓存概念
- 在计算机在执行程序时,以指令为单位来执行,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入 。
- 由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行指令的速度很快,而从内存读取数据和向内存写入数据的过程相对很慢,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度 。因此就引入了高速缓存 。
- 特性:缓存(Cache memory)是硬盘控制器上的一块内存,是硬盘内部存储和外界接口之间的缓冲器 。
- 预读取
?相当于提前加载,猜测你可能会用到硬盘相邻存储地址的数据,它会提前进行加载到缓存中,后面你需要时,CPU就不需要去硬盘读取数据,直接读取缓存中的数据传输到内存中就OK了,由于读取缓存的速度远远高于读取硬盘时磁头读写的速度,所以能够明显的改善性能 。
- 对写入动作进行缓存
?硬盘接到写入数据的指令之后,并不会马上将数据写入到盘片上,而是先暂时存储在缓存里,然后发送一个“数据已写入”的信号给系统,这时系统就会认为数据已经写入,并继续执行下面的工作,而硬盘则在空闲(不进行读取或写入的时候)时再将缓存中的数据写入到盘片上 。
- 【从缓存入门到并发编程三要素详解 Java中 volatile 、final 等关键字解析案例】换到应用程序层面也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据同步到主存当中 。
i = i + 1;
- 当线程执行这个语句时,会先从主存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中i最新的值刷新到主存当中 。
- 这个代码在单线程中运行是没有任何问题的,但是在多线程中运行就会有问题了(存在临界区) 。在多核CPU中,每条线程可能运行于不同的CPU中,因此每个线程运行时有自己的高速缓存区(对单核CPU来说,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的) 。
- 线程一执行
i = i + 1
,线程二执行var = i
- 线程二此时去主存中获取变量
i
,线程一只是在高速缓存中更新了变量,还未将变量i
写会主存 - 线程二读到的
i
不是最新值,此时多线程导致数据不一致
?这里的共享又可以回到上文中,即为上面所说,他们每个线程都有自己的高速缓存区,但是都是从同一个主存同步获取变量 。
那么这种问题应该怎样解决呢?
解决缓存不一致问题(硬件层面)
- 总线加锁模式
- 由于CPU在执行命令和其他组件进行通信的时候都需要通过总线,倘若对总线加锁的话,线程一执行
i = i + 1
整个命令过程中,其他线程是无法访问主存的 。 - 优缺只有一个,可以解决本问题;缺点的话除了优点全是缺点,效率低,成本高·····(谁也不会让一个主存同时只能干一件事)
经验总结扩展阅读
- 香港北角到铜锣湾怎么走
- [CG从零开始] 4. pyopengl 绘制一个正方形
- 一文读懂Apache Geode缓存中间件
- 树马齿苋花怎么养
- 义乌到河北唐山快递要多久
- 为什么睡到半夜胃胀气
- 马栗乐真假区别?
- 韩国苏秘真假对比?
- 雨水的格言
- 跳棋怎么玩(跳棋怎么玩新手入门)
- 由于CPU在执行命令和其他组件进行通信的时候都需要通过总线,倘若对总线加锁的话,线程一执行