java编程-硬件基础知识(缓存行,指令重排…)

很多情况下保持黑箱即可,因为打开这个黑箱,你会发现黑箱变成黑洞,吞噬你所有的时间和精力。有可能带你偏离原来的方向,陷入到不必要的细节中而无法自拔。 -- 适度打开即可

CPU的制作过程

Intel cpu的制作过程

https://haokan.baidu.com/v?vid=11928468945249380709&pd=bjh&fr=bjhauthor&type=video

CPU是如何制作的(文字描述)

https://www.sohu.com/a/255397866_468626

CPU的原理

计算机需要解决的最根本问题:如何代表数字

晶体管是如何工作的:

https://haokan.baidu.com/v?vid=16026741635006191272&pd=bjh&fr=bjhauthor&type=video

晶体管的工作原理:

https://www.bilibili.com/video/av47388949?p=2

汇编语言的执行过程

汇编语言的本质:机器语言的助记符 其实它就是机器语言

计算机通电 -> CPU读取内存中程序(电信号输入)

->时钟发生器不断震荡通断电(GHZ/s) ->推动CPU内部一步一步执行

(执行多少步取决于指令需要的时钟周期)

->计算完成->写回(电信号)->写给显卡输出(sout,或者图形)


输入处理输出流程.png

上述中:内存中数据不必写到cpu,而是直接由DMA处理(cpu告诉内存,把其某块的数据发送到显卡,DMA会通过数据总线将数据发送到显卡)

CPU的基本组成

  • PC -> Program Counter 程序计数器 (记录当前指令地址)
  • Registers -> 暂时存储CPU计算需要用到的数据
  • ALU -> Arithmetic & Logic Unit 运算单元
  • CU -> Control Unit 控制单元
  • MMU -> Memory Management Unit 内存管理单元
  • cache

缓存

一致性协议:https://www.cnblogs.com/z00377750/p/9180644.html

缓存行:折中都用64字节(程序的局部性原理,一次读取一块数据,而不是一个字节)

缓存行越大,局部性空间效率越高,但读取时间慢

缓存行越小,局部性空间效率越低,但读取时间快

cache一致性协议.png

英特尔采用的是以上缓存一致性协议
如果一个缓存行装载不下数据时,总线锁会介入,即一侧的核心处理完毕之后,另一侧才可以处理,这样效率会降低

cache line.png

上图中显示的是两个核心,xy处于一个cache line, 左边的核心要修改x,从L1读取,发现不存在,依次从L2,L3读取,直到main memory才找到,然后依次在L3,L2,L1都缓存一份,最后计算单元进行处理;而右边的核心要操作y,操作步骤与左边的核心相似,这样左右两边的核心各自持有一个cache line,但是操作的不同的数据,两个核心之间需要相互同步各自修改的,即伪共享

以下是模拟cache line 不是特别精确

public class T03_CacheLinePadding {
    public static volatile long[] arr = new long[2];
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(()->{
            for (long i = 0; i < 10000_0000L; i++) {
                arr[0] = i;
            }
        });

        Thread t2 = new Thread(()->{
            for (long i = 0; i < 10000_0000L; i++) {
                arr[1] = i;
            }
        });

        final long start = System.nanoTime();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println((System.nanoTime() - start)/100_0000);
    }
}
public class T04_CacheLinePadding {
    public static volatile long[] arr = new long[16];
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(()->{
            for (long i = 0; i < 10000_0000L; i++) {
                arr[0] = i;
            }
        });
        Thread t2 = new Thread(()->{
            for (long i = 0; i < 10000_0000L; i++) {
                arr[8] = i;
            }
        });
        final long start = System.nanoTime();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println((System.nanoTime() - start)/100_0000);
    }
}

缓存行对齐对于有些特别敏感的数字,会存在线程高竞争的访问,为了保证不发生伪共享,可以使用缓存行对齐的编程方式

  • JDK7中,很多采用long padding提高效率(让高竞争的数据永远处于一个缓存行且只有它自己,该方式适用于英特尔cpu)
    如下:无论如何截取cursor这个数据所处的缓存行只有它自己

    long padding.png

  • JDK8,加入了@Contended注解(实验)需要加上:JVM -XX:-RestrictContended

超线程

超线程.png

多组寄存器+PC。上图中为两组,减少了线程切换时,中间态数据的保存,这样同事状态两个线程的数据,ALU指向哪个执行就执行它

存储器的层次结构

存储器层次结构.png

越是往的成本越高,即塔尖的部分成本巨贵。至于CPU为什么设计成三层(L1,L2,L3)是由工业设计大量实践证明三层最合理

cpu到各层时间对比.png

寄存器与memor速度比=1:100

多核cpu.png

一颗物理cpu内部有两个核心,这两个核心各自独立的L1 & L2,共享L3
两颗物理cpu共享主内存。

乱序执行

https://preshing.com/20120515/memory-reordering-caught-in-the-act/

禁止乱序

CPU层面:Intel -> 原语(mfence lfence sfence) 或者锁总线
JVM层级:8个hanppens-before原则 4个内存屏障 (LL LS SL SS)
as-if-serial : 不管硬件什么顺序,单线程执行的结果不变,看上去像是serial

举例说明(乱序执行可能产生的问题)
DCL单利为什么加volatile?

对象创建的会编码.png

0 new - 这条指令开辟一块内存空间,并将m=0,并在本地方法栈内存放一个引用,指向给地址
3 dup - 将栈的引用复制一份
4 invokespecial #3 <T.<init>> - 从栈中弹出栈顶的那个引用指向那个对象执行构造方法,即 m = 8
7 astore_1 - 将弹出栈中最下面引用赋值给t

DCL-单利.png

发生了指令重排之后,t=null, 则此时Thread 2 恰巧进入if 判断分支成立,即使用了半初始化状态的对象
详看2020-设计模式->>单利模式->>懒汉模式(Mgr06)
https://www.jianshu.com/p/9baf3170bff7

合并写(了解)

Write Combining Buffer
一般是4个字节
由于ALU速度太快,所以在写入L1的同时,写入一个WC Buffer,满了之后再直接更新到L2


wc buffer.png

NUMA(了解)

Non Uniform Memory Access
ZGC - NUMA aware
分配内存会优先分配该线程所在CPU的最近内存

UMA.png

NUMA.png

从主板的结构来说,他会分为不同的插槽,每个插槽上有一组cpu和与之相邻的内存条,则cpu就近访问内存要比访问其他插槽的内存速度要快的多

————————————————————
坐标帝都,白天上班族,晚上是知识的分享者
如果读完觉得有收获的话,欢迎点赞加关注

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容