0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

当我们在谈论cpu指令乱序的时候,究竟在谈论什么?

dyquk4xk2p3d 来源:罗一鑫 2023-05-19 14:42 次阅读

很多现代高级语言多提供了多线程并发技术,今天服务器CPU基本上都是多核架构,在Java中,JVM能够根据处理器特性(CPU多级缓存系统、多核处理器等)适当对机器指令进行重排序,最大限度发挥机器性能。Java中的指令重排有两次,第一次发生在将字节码编译成机器码的阶段,第二次发生在CPU执行的时候,也会适当对指令进行重排。

写这篇文章的目的,是想明确下cpu指令乱序这件事。只要是熟悉计算机底层系统的同学就会知道,程序里面的每行代码的执行顺序,有可能会被编译器和cpu根据某种策略,给打乱掉,目的是为了性能的提升,让指令的执行能够尽可能的并行起来。

知道指令的乱序策略很重要,原因是这样我们就能够通过barrier(内存屏障)等指令,在正确的位置告诉cpu或者是编译器,这里我可以接受乱序,那里我不能接受乱序等等。从而,能够在保证代码正确性的前提下,最大限度地发挥机器的性能。

10多年前的程序员对处理器乱序执行和内存屏障应该是很熟悉的,但随着计算机技术突飞猛进的发展,我们离底层原理越来越远,这并不是一件坏事,但在有些情况下了解一些底层原理有助于我们更好的工作,比如现代高级语言多提供了多线程并发技术,如果不深入下来,那么有些由多线程造成问题就很难排查和理解。

前言

这里我不打算讨论编译器的乱序策略,这里讨论的指令乱序,含义稍广些,包括在多核上分别执行的指令间,在时间维度上的乱序。

如果在多核cpu层面考虑乱序执行的话,我们要来梳理清楚以下几个概念:单核和多核,乱序执行和顺序提交,store buffer和invalid queue。最后会对x86和arm/power架构的异同,做一个总结。

24a2495e-f5fc-11ed-90ce-dac502259ad0.jpg

单核 vs 多核

从多核的视角上来说,是存在着乱序的可能的。比如,假设存在变量x = 0,cpu0上执行写入W0(x, 1),对x写入1。接着在cpu1上,执行读取R1(x, 0),得到x = 0,这在x86和arm/power的cpu上都是可能出现的。原因是x86上cpu核和cache以及内存之间,存在着store buffer,当W0(x, 1)执行成功后,修改只存在于store buffer中,并未写到cache以及内存上,因此cpu1读取不到最新的x值。对于arm/power来说,同样也有store buffer,而且还可能会有invalid queue,导致cpu1读不到最新的x值。

对于没有invalid queue的x86系列cpu来说,当修改从store buffer刷入cache时,就能够保证在其他核上能够读到最新的修改。但是,对于存在invalid queue的cpu来说,则不一定。

为了能够保证多核之间的修改的可见性,我们在写程序的时候需要加上内存屏障,例如x86上的mfence指令。

乱序执行 vs 顺序提交

我们知道,在cpu中为了能够让指令的执行尽可能地并行起来,从而发明了流水线技术。但是如果两条指令的前后存在依赖关系,比如数据依赖,控制依赖等,此时后一条语句就必需等到前一条指令完成后,才能开始。

cpu为了提高流水线的运行效率,会做出比如:

1)对无依赖的前后指令做适当的乱序和调度;

2)对控制依赖的指令做分支预测;

3)对读取内存等的耗时操作,做提前预读;

等等。以上总总,都会导致指令乱序的可能。

但是对于x86的cpu来说,在单核视角上,其实它做出了Sequential consistency[1]的一致性保障。Sequential consistency的在wiki上的定义如下:

"... the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program."

也就是说,要满足Sequential consistency,必需保障每个处理器的指令执行顺序必需和程序给出的顺序一致。奇怪吧?这不就和我刚才说的指令乱序优化矛盾了嘛?其实并不矛盾,指令在cpu核内部确实是乱序执行和调度的,但是它们对外表现却是顺序提交的。

如果把ISA寄存器(如EAX,EBX等)和store buffer,作为cpu对外的接口的话,cpu只需要把内部真实的物理寄存器按照指令的执行顺序,顺序映射到ISA寄存器上,也就是cpu只要将结果顺序地提交到ISA寄存器,就可以保证Sequential consistency。

当然,以上是对x86架构的cpu来说的,ARM/Power架构的cpu在单核上的一致性保证要弱一些,无需保证Sequential consistency,因此也不需要顺序提交,只需保证控制依赖,数据依赖,地址依赖等指令的顺序即可。要想在这些弱一致性模型cpu下保证无关指令间的提交顺序,需要使用barrier指令。

Store Buffer & Invalid Queue

store buffer存在于cpu核与cache之间,对于x86架构来说,store buffer是FIFO,因此不会存在乱序,写入顺序就是刷入cache的顺序。但是对于ARM/Power架构来说,store buffer并未保证FIFO,因此先写入store buffer的数据,是有可能比后写入store buffer的数据晚刷入cache的。从这点上来说,store buffer的存在会让ARM/Power架构出现乱序的可能。store barrier存在的意义就是将store buffer中的数据,刷入cache。

在某些cpu中,存在invalid queue。invalid queue用于缓存cache line的失效消息,也就是说,当cpu0写入W0(x, 1),并从store buffer将修改刷入cache,此时cpu1读取R1(x, 0)仍是允许的。因为使cache line失效的消息被缓冲在了invalid queue中,还未被应用到cache line上。这也是一种会使得指令乱序的可能。load barrier存在的意义就是将invalid queue缓冲刷新。

X86 vs ARM/Power

对于x86架构的cpu来说,在单核上来看,其保证了Sequential consistency,因此对于开发者,我们可以完全不用担心单核上的乱序优化会给我们的程序带来正确性问题。在多核上来看,其保证了x86-tso模型,使用mfence就可以将store buffer中的数据,写入到cache中。而且,由于x86架构下,store buffer是FIFO的和不存在invalid queue,mfence能够保证多核间的数据可见性,以及顺序性。[2]

对于arm和power架构的cpu来说,编程就变得危险多了。除了存在数据依赖,控制依赖以及地址依赖等的前后指令不能被乱序之外,其余指令间都有可能存在乱序。而且,它们的store buffer并不是FIFO的,而且还可能存在invalid queue,这些也同样让并发编程变得困难重重。因此需要引入不同类型的barrier来完成不同的需求。[3]

总结

从上面的介绍可以知道,开发者想要做好并发编程是多么困难的事情,但是我们至少跨出了第一步,也就是定义困难本身。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18290

    浏览量

    222194
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10446

    浏览量

    206576
  • 多线程
    +关注

    关注

    0

    文章

    271

    浏览量

    19726
收藏 人收藏

    评论

    相关推荐

    看看技术圈现在都在谈论些什么

    电子发烧友网做为中国电子工程师娴熟者相聚互动的社区平台。在每天,每周,每月乃至每年,我们编辑,运营和产品都在紧鼓密锣地策划追踪关于电子半导体行业相关的话题、技术、设计、热点事件、创新大赛等与电子
    发表于 03-22 09:51 2060次阅读

    谈论MCU上运行什么样的应用

    作者| Rober van der Zwan(荷兰)译者|禾沐当我们谈论使用MCU的嵌入式系统时,我们在谈论MCU上运行什么样的应用?众所周知,我们
    发表于 12-22 08:19

    Lovepedal SuperSix资料分享

    非常适合缓冲、放大或收集声音。为您的吉他设置添加柔和的复古压缩或复古音色。Lovepedal Super 6 不是过载踏板,但在极端设置下可能会增加一些额外的功能。它也增加了压缩,但我们不是在谈论
    发表于 08-12 06:50

    网络建设不可忽视的功臣--网线

    网络建设不可忽视的功臣--网线 我们在谈论企业网络建设的时候,首先考虑的是路由器、服务器等的配置,但是我们往往忽视一种最
    发表于 04-14 11:47 699次阅读

    高通:当别人还在谈论5G时,我们已经开始打造5G

    现在我们正引领下一个十年及未来的5G之路。3G和4G使人与人相联,而5G将使万物互联。与前几代移动技术相比,5G将成为更强大的统一架构,在未来发挥更大的作用。它会成为重要的连接层,对我们的城市、工作、家庭和自身至关重要,也将是未来技术革命的基础。
    发表于 08-10 11:24 426次阅读

    Michael I. Jordan给AI泼冷水,人工智能革命尚未发生

    当我们在谈论 AI 时,我们到底在谈什么?人工智能三度崛起,所有的人张口闭口都是 AI,媒体的炒作让人看到未来仿佛已经来到我们的身边。
    的头像 发表于 04-27 14:37 3723次阅读

    谈论CES的发展和创客社区

    Atmel的Bob Martin经理,谈到CES多年来的发展,并着重谈论了DIY创客社区
    的头像 发表于 07-09 03:56 4142次阅读

    科技巨头扎堆 是什么催化了AIoT时代的到来

    有人形容AIoT是一个大的硬件生态、是一个全新的技术浪潮,是一个宏大的未来蓝图。那么,当我们在谈论AIoT的时候我们到底在说什么?又是什么,催化了AIoT时代的到来?
    的头像 发表于 01-23 14:12 3911次阅读

    科技巨头扎堆AIoT,华为、小米究竟看到了什么?

    编者按 :有人形容AIoT是一个大的硬件生态、是一个全新的技术浪潮,是一个宏大的未来蓝图。那么,当我们在谈论AIoT的时候我们到底在说什么?又是什么,催化了AIoT时代的到来? 20
    的头像 发表于 01-27 16:01 692次阅读

    All in AIoT,华为、小米、旷视们究竟在打什么主意?

    、是一个全新的技术浪潮,是一个宏大的未来蓝图。那么,当我们在谈论AIoT的时候我们到底在说什么?又是什么,催化了AIoT时代的到来? 我们
    的头像 发表于 01-27 16:28 571次阅读

    当我们在谈论中美领跑人工智能竞赛的时候,日本在干什么?

    人工智能技术还有望用于犯罪调查和维持社会治安,日本警察厅将从今年开始这方面的实验。实验中将摸索能否通过监控摄像头图像锁定汽车车型或在人群中发现可疑人员。日本媒体称如果能顺利实现,未来或将诞生能解决任何疑难案件的“人工智能刑警”。
    的头像 发表于 03-08 16:22 4028次阅读

    AI诗人和人类诗人,哪个更胜一筹?

    当前我们在谈论AI写的诗好不好的时候,也忘了一个问题:未来人类是否愿意读AI的诗?
    发表于 07-02 17:19 1171次阅读

    当我们在谈 8K,8K 是什么

    电影的标准格式 8192x4320,而 8K 电视的标准比例是 16:9,百分百的屏幕占比为 7680x4320。只是画幅的比例略有不同,8K 电视 3300 万像...
    的头像 发表于 12-08 22:23 2406次阅读

    我们在谈论音质的时候在谈论什么资料下载

    电子发烧友网为你提供我们在谈论音质的时候在谈论什么资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到
    发表于 04-25 08:45 10次下载
    <b class='flag-5'>我们</b><b class='flag-5'>在谈论</b>音质的<b class='flag-5'>时候</b><b class='flag-5'>在谈论</b>什么资料下载

    科普一下MR双射频技术的相关知识

    在谈论双射频技术之前,我们先来学习一个简单的物理知识:电磁波在介质中的传播。
    发表于 06-16 15:16 1119次阅读
    科普一下MR双射频技术的相关知识