计算器基础知识

75 阅读4分钟

1.cpu基本构成

  1. program conter 程序计数器 记录当前指令地址
  2. register 寄存器 暂时存储cpu使用到的数据
  3. ALU arithmetic & logic unit 运算单元
  4. CU control unit 控制单元 中断
  5. MMU memory manager unit 内存管理单元 程序虚拟内存与真实物理内存地址转换
  6. cache L1 L2 L3级别缓存

2.缓存一致性协议

inter 缓存行 64KB

JDK避免频繁修改的两个属性属于同一个缓存行

@Contended -XX:-RestrictContended

  1. modified 被修改的 缓存行数据已经被更改,但还未写回内存当中
  2. exclusive 独享的 缓存行被该cpu一个人使用,还没有做任何修改
  3. shared 共享的 多个cpu 同时访问该数据,还没有做任何修改
  4. invalid 无效的 缓存行已经被其他cpu修改

exclusive -- 另一个cpu参与了 -- shared -- 一个cpu修改了 

-- 发起修改的cpu 变成了 modified

-- 被修改的cpu  变成了 invalid

3.禁止cpu指令重排

  1. cpu  interl  mfence lfence sfence lock 锁总线

  2. jvm 8个hanppens-before原则 4个内存屏障 (LL LS SL SS)

  3. jvm 单线程 执行结果保持一致

  4. 程序次序规则:在一个单独的线程中,按照程序代码的执行流顺序,(时间上)先执行的操作happen—before(时间上)后执行的操作

  5. 管理锁定规则:一个unlock操作happen—before后面(时间上的先后顺序,下同)对同一个锁的lock操作

  6. volatile变量规则:对一个volatile变量的写操作happen—before后面对该变量的读操作

  7. 线程启动规则:Thread对象的start()方法happen—before此线程的每一个动作

  8. 线程终止规则:线程的所有操作都happen—before对此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行

  9. 线程中断规则:对线程interrupt()方法的调用happen—before发生于被中断线程的代码检测到中断时事件的发生

  10. 对象终结规则:一个对象的初始化完成(构造函数执行结束)happen—before它的finalize()方法的开始

  11. 传递性:如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C

  • LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕
  • StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见
  • LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕
  • StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能

synchronize

  1. 获得互斥锁
  2. 清空工作内存
  3. 从主内存拷贝变量的最新副本到工作内存
  4. 执行代码
  5. 将更改后的共享变量的值刷新到主内存中
  6. 释放互斥锁

volatile

在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障
在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障

线程写volatile变量的过程:

    1. 改变线程工作内存中volatile变量副本的值
    2. 将改变后的副本的值从工作内存刷新到主内存

线程读volatile变量的过程:

    1. 从主内存中读取volatile变量的最新值到线程的工作内存中
    2. 从工作内存中读取volatile变量的副本

    public class Demo { private static Demo demo = new Demo(); private Demo(){} public static Demo getInstance(){return demo;} }

    public class Demo { private static class InnerDemo { private static final Demo demo = new Demo(); } private Demo(){} public static Demo getInstance(){return InnerDemo.demo} }

    public enum Demo { INSTANCE; }

    public class Demo { private volatile Demo demo; private Demo(){} public static Demo getInstance(){ if (null != demo){ synchronize(Demo.class){ if( null != demo ){ demo = new Demo(); } } } return demo; } }

4.NUMA

Non Uniform Memory Access

分配内存会优先分配该线程所在CPU的最近内存

5.OS

  1. 用户态 ring3
  2. 内核态 ring0

ring3 请求 ring0 得到内核同意 调用 ring0 接口