首先给自己一个介绍,本人是一个蠢笨蠢笨的女程序员,由于有一天突然觉悟了,想在学习的过程中写一些笔记,以前一直不敢开始这个事情,因为我害怕写错了,误导了别人,现在还是害怕,如果真的误导了同行,你们也轻点喷我 哈哈哈
接下来进入正题,今天来记录一下我自己学到的东西,Java相关的硬件知识,说到这个我们先谈谈计算机的最重要的组成部分,跟我们写程序联系比较紧密的部分:
先来看看计算机的组成,如下图:
image

一、cpu(计算机的重要组成部分)

cpu是计算机的核心组成部分,功能主要是解释计算机指令以及处理计算机软件中的数据,cpu中有一个重要的部件,就是时钟发生器,他就像人的心脏,推动着cpu进行一步一步的计算,比如我计算3+2需要多少步骤,通过时钟发生器不断的通电断电给cpu信号,推动cpu进行计算(比较粗略的理解)

PC:Program Counter 程序计数器(每个线程私有) 记录当前指令的地址

Registers: 寄存器 暂时存储cpu计算需要用到的数据

ALU:Arithmetic & Login Unit 逻辑运算单元

ALU逻辑运算单元,当一个线程获得执行时间片开始执行,需要进行运算的时候,那么ALU从寄存器中取出某个线程的数据来进行运算,

此处有一个知识点,就是现在说的超线程,比如两核四线程、四核八线程,是怎么实现的,比如原来的单核单线程,就是一个cpu的一个核里面只有一组PC(程序计数器)和Registers(寄存器),当一个线程获得执行时间片时,需要将前一个线程的数据先保存起来,再将自己的数据放入PC和Registers,而超线程的实现,就是cpu的一个核里面有两组PC和Registers,当其中的一个线程获得执行的时间片之后,ALU可以直接去该线程对应的PC和Registers取得数据,节省线程切换的消耗,达到提升性能的目的,如下图:
image

CU:Control Unit 控制单元(本人还没理解透彻)

MMU:Memory Management Unit 内存管理单元(本人还没理解透彻)

cache:缓存

cpu和内存的速度比大概是100:1,缓存就是为了解决cpu和内存的速度差异,缓存分为L1、L2、L3,cpu的每一个核都拥有独立的L1、L2这两级缓存,L3是所有核共享的,如下图:

image

下面我们再介绍缓存行的概念,缓存行是cpu缓存系统中的基本单位,当cpu从内存当中读取数据的时候,并不是你需要某个字节就只读取某个字节,而是将你需要的字节所在的内存块读取到缓存行,因为根据一定的预测,可能需要的数据也不只是这一个字节,也许周围的数据你也是需要的,这样的读取也可以提高效率

到这里,再记录一个与缓存行有关的知识,MESI协议,缓存一致性协议是指一个缓存行,在不同的cpu中被修改之后,要保证数据一致,每个缓存行都有额外的两个位来存储缓存行的状态(modified、exclusive、shared、invalid),当处于同一个缓存行的数据,在A(cpu的内核)处被修改,那么B处的缓存行将变成失效状态,当B需要修改同一个缓存行的数据时,需要重新从内存中读取数据再进行修改,缓存一致性协议有MSI,MESI(Intel)、synapse、Firely、Dragon等,不同品牌的cpu使用不同的缓存一致性协议

此处有一个问题叫伪共享,我们以Intel cpu举例,当cpu的两个核分别修改了同一个缓存行中的独立变量时,实际上两个变量是互不影响的,但是由于他们在一个缓存行中,当A修改了a,B中的缓存行就会变成失效状态,这个时候如果B修改b,就必须要先提交A中的缓存行,然后B再去内存当中读取这个缓存行进行修改,此操作应该是一个并行操作,但是由于缓存一致性,却变成了串行,反而降低了效率

解决办法是,缓存行对齐:对于一些特别敏感的数字,会存在线程高竞争的访问,可以使用缓存行对齐的编程方式

JDK7中,很多采用long padding提高效率
image

JDK8,加入了@Contended注解
需要加上:JVM -XX:-RestrictContended

二、内存(计算机的重要组成部分)(下次研究哈哈哈哈)

下一篇内容:
https://segmentfault.com/a/11...


萌妹子_liu
28 声望43 粉丝

萌萌哒,程序猿