by shihang.mai
1. CPU组成部件
CPU组成CPU由以下几个部分组成
- ALU 运算单元。此部件参与CPU计算。
- Registers 寄存器。此部件用于暂存CPU计算需要用到的数据
- PC 程序计算器。此部件用于记录当前指令地址。
- Cache 缓存。此部件用于提高计算效率。因为硬盘、内存、CPU不同的速度,速度快的缓存贵,导致出现多层缓存。
- MMU 内存管理单元。此部件用于将线性地址映射到物理地址。
- CU 控制单元。此部件用于中断。
CPU读取数据时,会按块读取,因为程序局部性原理,可以提高效率
1.1 超线程
即一个ALU对应多组(Registers+pc),ALU要做一个上下文切换(context switch)。
1.2 NUMA
Uma:多个cpu,没有优先级访问同一个内存。
NUMA:在主板上,有多个独立的cpu插槽,还有离该插槽近的内存,具有该内存的优先级访问
1.3 缓存行
CPU有多级缓存,并且根据局部性原理,会按块读取,每次读取64Byte(英特尔CPU),这样会导致缓存行伪共享现象
- 内存中有64Byte的数据块,即缓存行,包括X和Y数据
- 这个缓存行会在L3、L2、L1都存在。分别保存在那两个CPU上
- 在CPU1中修改数据X,那么CPU2在操作这个X时,就不是最新的数据,CPU会根据缓存一致性协议,重新读取整个缓存行。造成了
缓存行伪共享现象
缓存一致性协议,英特尔和AMD都有自己的实现,而英特尔的实现方案是MESI,MESI分别对应缓存行中数据的状态
-
M:modified 修改的
-
E:exclusive 专有的
-
S:share 共享的
-
I:invalid 非法的
ps:当有些跨越多个缓存行的数据,那么会直接锁总线来保持数据一致性。
1.4 缓存行对齐
正因为上面的缓存行伪共享现象
- jdk8前:会用long p1 p2 p2 p4 p5 p6 p7占用字节,
解决缓存行伪共享现象
- jdk8后:JVM参数设置参数 -XX:-RestrictContended,用@Contended 修饰成员变量,
解决缓存行伪共享现象
1.5 CPU乱序执行
cpu不是乱序,而是同时执行,提高效率。但是乱序执行会导致问题。
多线程情况下,乱序执行会导致问题,dcl就是典型的例子(见DCL volatile章节)。
2. 汇编执行过程
数字 | 助记符 |
---|---|
01001000 | mov |
10110011 | add |
网友评论