且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Juc10_CPU指令、缓存结构、运行安全等级、操作系统内存管理、上下文切换、虚拟机指令集架构(二)

更新时间:2022-06-28 01:46:10

③. CPU缓存结构


  • ①. 现代CPU为了提升执行效率,减少CPU与内存的交互(交互影响CPU效率),一般在CPU上集成了多级缓存架构,常见的为三级缓存结构: L1、L2是多核独享、L3是多核共享


Juc10_CPU指令、缓存结构、运行安全等级、操作系统内存管理、上下文切换、虚拟机指令集架构(二)

Juc10_CPU指令、缓存结构、运行安全等级、操作系统内存管理、上下文切换、虚拟机指令集架构(二)


②. 存储器存储空间大小:内存>L3>L2>L1>寄存器


存储器速度快慢排序:寄存器>L1>L2>L3>内存


③. 还有一点值得注意的是:缓存是由最小的存储区块-缓存行(cacheline)组成,缓存行大小通常为64byte


缓存行是什么意思呢?


比如你的L1缓存大小是512kb,而cacheline = 64byte,那么就是L1里有512 * 1024/64个cacheline


④. CPU读取存储器数据过程 重点


CPU要取寄存器X的值,只需要一步:直接读取


CPU要取L1 cache的某个值,需要1-3步(或者更多):把cache行锁住,把某个数据拿来,解锁,如果没锁住就慢了


CPU要取L2 cache的某个值,先要到L1 cache里取,L1当中不存在,在L2里,L2开始加锁,加锁以后,把L2里的数据复制到L1,再执行读L1的过程,上面的3步,再解锁


CPU取L3 cache的也是一样,只不过先由L3复制到L2,从L2复制到L1,从L1到CPU


CPU取内存则最复杂:通知内存控制器占用总线带宽,通知内存加锁,发起内存读请求,等待回应,回应数据保存到L3(如果没有就到L2),再从L3/2到L1,再从L1到CPU,之后解除总线锁定


⑤. 时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期它很可能还会被再次访问


比如循环、递归、方法的反复调用等


空间局部性(Spatial Locality):如果一个存储器的位置被引用,那么将来他附近的位置也会被引用


比如顺序执行的代码、连续创建的两个对象、数组等


⑥. 多线程的引入,摩尔定律失效(硬件方面)


集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍,可是从2003年开始CPU主频已经不再翻倍,而是采用多核而不是更快的主频


在主频不再提高且核数不断增加的情况下,要想让程序更快就要用到并行或并发编程


④. CPU运行安全等级


①. CPU有4个运行级别,分别为:ring0、ring1、ring2、ring3


②. Linux与Windows只用到了2个级别:ring0、ring3,操作系统内部内部程序指令通常运行在ring0级别,操作系统以外的第三方程序运行在ring3级别,第三方程序如果要调用操作系统内部函数功能,由于运行安全级别不够,必须切换CPU运行状态,从ring3切换到ring0,然后执行系统函数,说到这里相信同学们明白为什么JVM创建线程,线程阻塞唤醒是重型操作了,因为CPU要切换运行状态


③. 下面我大概梳理一下JVM创建线程CPU的工作过程


CPU从ring3切换ring0创建线程


创建完毕,CPU从ring0切换回ring3


线程执行JVM程序


线程执行完毕,销毁还得切会ring0


④. 我们的线程都有两个堆和栈,一个在用户空间(用户态),一个在系统空间(系统态)如果我们不去调用系统库的话(比如开启一个线程),都是运行在用户空间,一旦你的线程需要阻塞,或者杀死,那么你的CPU状态就要从用户态切换到内核态,把操作系统的堆和栈给丢了,杀死掉(这个时候CPU的安全等级是ring0,ring0表示的是最高的等级)杀掉或者阻塞好了以后,又会从系统态(ring0)切回到用户态(ring3) 掌握