V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LeeReamond
V2EX  ›  Java

CPU 乱序执行代码,是 CPU 硬件级别的机制吗?

  •  
  •   LeeReamond · 2021-03-28 23:57:08 +08:00 · 5832 次点击
    这是一个创建于 1369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,java 学习过程中的问题。

    CPU 乱序执行,是那个级别的优化,CPU 硬件级,还是操作系统如此设计,还是 java 虚拟机如此设计?

    如果是 cpu 硬件级别的话,那说明不论什么代码丢进去,cpu 有自动优化执行的能力?

    29 条回复    2021-05-17 23:43:48 +08:00
    ooxxcc
        1
    ooxxcc  
       2021-03-29 00:01:35 +08:00   ❤️ 2
    ch2
        2
    ch2  
       2021-03-29 00:05:44 +08:00 via iPhone
    一个程序可以跑在很多个不同型号的 cpu 上,哪个 cpu 优化到什么程度不一定是相同的,它自己也不需要关心是怎么乱序执行的
    agagega
        3
    agagega  
       2021-03-29 00:15:26 +08:00
    > 还是 java 虚拟机如此设计

    我不清楚 Java 虚拟机的实现,不过编译器也是会做类似乱序执行的优化的,称为指令调度。volatile 关键字就是给编译器而不是 CPU 的提示。
    systemcall
        4
    systemcall  
       2021-03-29 00:15:50 +08:00 via Android
    是硬件级的,操作系统也有适配
    还要看编译器吧,而且优化不是万能的
    yolee599
        5
    yolee599  
       2021-03-29 00:54:05 +08:00 via Android
    不是硬件级的,单核 CPU 同一时间只能执行一个任务,是操作系统通过用定时器中断调度,把各个任务分时间片运行,至于被分到哪个时间片也是操作系统调度的
    yolee599
        6
    yolee599  
       2021-03-29 00:58:42 +08:00 via Android
    如果不用操作系统,直接裸跑,则代码是顺序执行的
    dangyuluo
        7
    dangyuluo  
       2021-03-29 01:24:46 +08:00   ❤️ 2
    @yolee599 我觉得你说的不对,哪怕单个核心来讲,CPU 是可以在指令层面进行 reorder 的,比如如果发现对于某两个寄存器的读写操作不会有坏的后果,是有可能进行指令重排的。不过这一切都是对用户透明
    GrayXu
        8
    GrayXu  
       2021-03-29 01:58:33 +08:00   ❤️ 1
    @yolee599 你理解错了,这里说的 CPU 乱序执行指的是指令乱序执行,而不是编译器完成优化后的乱序。CPU 是一个流水线执行的方式,并不是同一时间只能执行一个任务。区别于顺序执行,保证依赖关系的前提下,对不同指令做调度、做分支预测,都会产生指令乱序。建议可以仔细看看计算机组成原理。
    vk42
        9
    vk42  
       2021-03-29 02:36:18 +08:00
    @yolee599 你说的是分时系统调试,是 OS 概念。lz 问的是指令乱序,是体系结构的概念……
    katsusan
        10
    katsusan  
       2021-03-29 02:43:23 +08:00 via iPhone   ❤️ 3
    现代处理器的微架构层面上会将机器指令进一步分解为微指令 micro-ops,根据它们之间是否有 dependency chain 以及 execution unit 限制来决定是否乱序执行。
    ryd994
        11
    ryd994  
       2021-03-29 04:27:57 +08:00
    指令乱序是 cpu 的硬件 /微码实现的

    但是你说 Java,这涉及的不只是乱序执行,还有编译器的优化。编译器 /解释器可以在更高的层次上进行优化。一行源代码会编译成多个机器指令,这些指令之间可以重排。行与行之间也可以改变顺序(不影响结果的前提下)。这本身会带来性能优化,也能帮助 CPU 更好地执行。
    ryd994
        12
    ryd994  
       2021-03-29 04:30:47 +08:00   ❤️ 2
    @yolee599 1. 现代 CPU 都可以指令重排
    2. 现代 CPU,特别是 X86,是高度流水线的。所以根本就不存在你说的“同一时间只能执行一个任务”
    你说的只是宏观的操作系统调度。硬件 /微码 /流水线,会在微观 /底层干很多你不知道的优化。
    msg7086
        13
    msg7086  
       2021-03-29 05:55:17 +08:00 via Android
    指令重排是编译器,微指令重排是硬件。
    wanguorui123
        14
    wanguorui123  
       2021-03-29 08:13:09 +08:00 via iPhone
    乱序执行是硬件级的机制,为了提高 CPU 的利用率,但操作系统可以决定某些逻辑调度给 CPU 的那个核心上执行
    Mithril
        15
    Mithril  
       2021-03-29 08:21:04 +08:00
    你说的流程涉及两步“乱序执行”
    Java 或者说各种语言的编译器都会在编译的时候会进行一定程度上的优化重新调整语句顺序,拆解循环等等。当然这需要你打开优化功能才行。
    对于 Java 来说,这步是在 JVM 虚拟机里做的。本身 Java 编译器(把.java 编译成.class 的那个)不会做到这点。
    第二个是,现代 CPU 都是以流水线方式,将 JVM 或者说操作系统送过来的优化好的二进制指令进一步拆解成微指令执行的。在这过程中 CPU 会进行指令重排等各种优化,这些大部分都是硬件级别的机制。
    你可以简单理解为一堆人排队打疫苗,JVM 会把屋子外面排队的那些人根据个体情况调整排队顺序。CPU 相当于把屋子里面的人根据打疫苗的不同步骤进行再次重排。
    photon006
        16
    photon006  
       2021-03-29 09:13:27 +08:00
    应该是硬件级别,raspberry pi 4b 开始支持乱序执行,以前不行。
    Cloutain
        17
    Cloutain  
       2021-03-29 09:25:52 +08:00
    乱序执行自然是 CPU 的硬件机制,编译器会针对这种硬件机制做代码上的优化,编译器会将不相关的指令进行穿插,方便 CPU 乱序执行,这就是编译器的流水线优化方式之一。另外 CPU 分支预测机制则告诉我们一个基本概念,多重循环时,将次数多的循环放内层,次数少的放外层。预测错误时会冲洗流水线,付出较大代价,冲洗次数越少越好。
    可以看看《深入理解计算机系统》等书
    weizhen199
        18
    weizhen199  
       2021-03-29 10:06:05 +08:00
    是现在桌面级的 x86 的这样搞的。

    之前出过一个叫 atom 的 x86 顺序架构。

    intel 贴了无数钱但总感觉失败了(然而 chromebook 疫情大成功
    cmostuor
        19
    cmostuor  
       2021-03-29 11:03:17 +08:00
    是, CPU 的多级流水本就是乱序执行的 就如 @ryd994 #12 所言

    参考资料: CPU 指令执行及流水线(超标量、多发射、乱序执行) https://blog.csdn.net/qq_41154905/article/details/105163718

    书籍推荐:
    清华大学李亚民教授的书 计算机原理与设计:Verilog HDL 版
    dartabe
        20
    dartabe  
       2021-03-29 11:06:31 +08:00
    ARM a53 是顺序的 性能不行 : )
    Artbox
        21
    Artbox  
       2021-03-29 11:45:41 +08:00   ❤️ 1
    1.
    CPU 乱序执行 [指令] ,是 CPU 硬件级别的机制吗?
    是。
    乱序执行 [代码] ,是 CPU 硬件级别的机制吗?
    否,由编译器( Java 虚拟机),CPU,共同完成。
    2.
    编译器 /虚拟机的贡献:
    代码产生指令的过程,诸如拆循环,块优化之等因素的影响代码顺序。
    得到的指令序列未必能一一对应原代码段落。
    CPU 的贡献:
    指令序列被 CPU 执行的过程,诸如多发射,乱序执行等因素影响指令的顺序。
    CPU 只保证最终提交的执行结果安全即可,取指序列&&提交序列未必能一一对应指令序列。
    crackhopper
        22
    crackhopper  
       2021-03-29 14:26:43 +08:00
    有内存栅栏,可以做指令执行的同步。不过一般也不用关心乱序的问题。如果到这种级别的关心,编译器各种功能开关,手动拆循环,CPU 扩展指令这些都需要深入研究,还挺复杂的。一般我感觉加速方面,工程上从缓存命中,以及 SIMD 上入手能有不少的优化;算法上,能做的更多一点。
    XuanFei990
        23
    XuanFei990  
       2021-03-29 14:40:25 +08:00
    硬件可以实现
    以前看过一些 CPU 芯片的 datasheet,开发手册之类的,有这类的介绍,
    Brentwans
        24
    Brentwans  
       2021-03-29 16:47:50 +08:00
    CPU 自己控制取指令,当然可以优化了。CPU 不会乱序执行,这个是编译器做的事情。CPU 通常是顺序执行,但是流水线的存在,有指令多发和分支预测等手段来充分利用 CPU 各个部件。
    gyf304
        25
    gyf304  
       2021-03-29 17:50:28 +08:00
    @yolee599 不是的
    sariya
        26
    sariya  
       2021-03-29 19:08:41 +08:00 via Android
    是硬件级的。CPU 有能力对指令进行并行执行来提高效率(流水线)。但是这个能力的真实效果受实际执行指令排列的不同而不同,所以编译器在编译时就会对尽可能其进行优化,以便 CPU 发挥出它的实力
    newmlp
        27
    newmlp  
       2021-03-29 19:20:32 +08:00
    编译器以及 CPU 都可能会对指令进行重排
    VYSE
        28
    VYSE  
       2021-03-29 20:21:40 +08:00   ❤️ 1
    了解下 Intel CPU 之前 Spectre Meltdown 漏洞原理, 能比较好理解这个机制
    narutow
        29
    narutow  
       2021-05-17 23:43:48 +08:00
    编译器和 CPU 都会对没有依赖的指令进行分析后决定是否重排。
    1. 当编译器的优化(指令重排,缓存变量)可能会对程序的正确性产生影响时,使用 volatile 阻止优化。
    2. 当 CPU 乱序执行无依赖的微指令可能会对程序的正确性产生影响时,使用 barrier 阻止乱序执行。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5823 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 06:22 · PVG 14:22 · LAX 22:22 · JFK 01:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.