汇编语言(机器语言)的执行过程
汇编语言的本质:机器语言的助记符 其实它就是机器语言
计算机通电 -> CPU读取内存中程序(电信号输入)->时钟发生器不断震荡通断电 ->推动CPU内部一步一步执行(执行多少步取决于指令需要的时钟周期)->计算完成->写回(电信号)->写给显卡输出(sout,或者图形)
CPU的基本组成
PC Program Counter 程序计数器(记录当前指令地址)
Register 暂时存储CPU计算需要的数据
ALU Arithmetic&Logic Unit 运算单元
CU Control Unit 控制单元
MMU Memory Management Unit 内存管理单元
cache 缓存
缓存行:
缓存行越大,局部性空间效率越高,但读取时间慢
缓存行越小,局部性空间效率越低,但读取时间快
取一个折中值,目前多用:64字节
缓存行对齐:对于有些特别敏感的数字,会存在线程高竞争的访问,为了保证不发生伪共享,可以使用缓存航对齐的编程方式
JDK7中,很多采用long padding提高效率
JDK8,加入了@Contended注解(实验)需要加上:JVM -XX:-RestrictContendedCPU
乱序执行:本质是提高效率
禁止乱序:
CPU层面:Intel -> 原语(mfence lfence sfence) 或者锁总线
JVM层级:8个hanppens-before原则 4个内存屏障 (LL LS SL SS)
1.在每个volatile写操作的前面插入一个StoreStore屏障(不能同时写)
2.在每个volatile写操作的后面插入一个StoreLoad屏障(volatile写的时候不能读)
3.在每个volatile读操作的后面插入一个LoadLoad屏障(不能同时读)
4.在每个volatile读操作的后面插入一个LoadStore屏障(volatile读的时候不能写)
as-if-serial : 不管硬件什么顺序,单线程执行的结果不变,看上去像是serial
volatile 的实现细节
volatile 底层是使用内存屏障实现的,在写操作和读操作前后都加了屏障。(JVM要求这样实现,是一种规范,底层用Lock指令实现)
JVM层面上:
StoreStoreBarrier
volatile 写操作(Store)
StoreLoadBarrier
LoadLoadBarrier
volatile 读操作(Load)
LoadStoreBarrier
合并写
Write Combining Buffer
一般是4个字节
由于ALU速度太快,所以在写入L1的同时,写入一个WC Buffer,满了之后,再直接更新到L2
NUMA
Non Uniform Memory Access
ZGC - NUMA aware
分配内存会优先分配该线程所在CPU的最近内存
启动过程
通电 -> bios uefi 工作 -> 自检 -> 到硬盘固定位置加载bootloader -> 读取可配置信息 -> CMOS
OS
内核分类
微内核 - 弹性部署 5G IoT
宏内核 - PC phone
外核 - 科研 实验中 为应用定制操作系统 (多租户 request-based GC JVM)
用户态与内核态
cpu分不同的指令级别
linux内核跑在ring 0级, 用户程序跑在ring 3,对于系统的关键访问,需要经过kernel的同意,保证系统健壮性
内核执行的操作 - > 200多个系统调用 sendfile read write pthread fork