当前位置: 首页 > news >正文

嵌入式Linux——解密 ARM 性能优化:LDR 未命中时,为何 STR 还能“插队”?

问题理解

  • ARM v6/v7 处理器会对以下指令顺序进行优化
    LDR r0, [r1] ;
    STR r2, [r3] ;
    
  • 假如说第一条LDR指令导致缓存未命中,这样缓存就会填充行,并需要较多的时钟周期才能完成。老的ARM处理器会等待这个动作完成,再执行下一条STR指令。而ARM v6/v7 及以后处理器会识别出下一条指令(STR)且不需要等待第一条指令完成(并不依赖r0的值),即先执行STR指令,而不是等待LDR指令完成。

什么叫缓存未命中

  • 错误理解:为什么还能LDR指令缓存未命中,那没命中岂不是没能从内存拿到数据?
  • “缓存未命中” 不等于 “获取数据失败”
  • “缓存未命中” 等于 “在最快的地方(缓存)没找到,必须去下一级更慢的地方(内存)找”

“缓存未命中”时,CPU 的完整处理流程

  • 这个流程是自动由硬件(CPU 和内存控制器)完成的,你的程序(LDR指令)不需要操心如何去做,只需要等待它完成。
  • 下述流程先抛开多级缓存和指令顺序优化。
  1. 尝试在“办公桌”(L1 Cache)上寻找

    • CPU 拿到地址 [r1]。
    • 它首先在最快的存储——你的**办公桌(L1 缓存)**上,寻找这个地址的数据。
    • 结果:没找到!这就是**“缓存未命中”(Cache Miss)**。
  2. “那怎么办?” —— CPU 停顿 (Stall)

    • 你的反应(CPU 停顿):你(CPU)不能继续执行下一条指令 STR r2, [r3],因为你必须先完成 LDR。
    • 你“哎呀”一声,停下手中的工作,开始等待。
    • 这就是“需要较多的时钟周期”的开始。 CPU 在原地空转,等待数据送达。
  3. 去“大书柜”(Main Memory / 内存)拿数据

    • 因为办公桌(Cache)上没有,你(的内存控制器)只好站起来,走到**大书柜(主内存 RAM)**那里。
    • 根据地址 [r1],你在书柜中找到了那份文件(数据)。
    • 数据肯定是在“书柜(内存)”里的。(如果连内存里都没有,那就是“缺页异常/Page Fault”,那是另一个更慢的故事了,但 LDR 指令本身假定数据在内存中)。
  4. “缓存就会填充行”(Cache Line Fill)

    • 这是最关键的一步!
    • 你(CPU)非常聪明,你不会只把 r0 需要的那 4 个字节(假设是32位ARM)从书柜拿到办公桌。
    • 你猜测:“既然我拿了这份文件,我待会儿很可能也会看它旁边的文件。”(这就是空间局部性原理)
    • 于是,你把包含 [r1] 数据的一整“行”(比如一整个文件夹,技术上称为一个 Cache Line,例如 64 字节)全部从“书柜(内存)”搬运到了“办公桌(缓存)”上。
    • 这个动作就叫做**“缓存填充行”(Cache Line Fill)**。
  5. 完成 LDR 指令

    • 现在,数据已经成功地被你从“书柜(内存)”复制到了“办公桌(缓存)”上。
    • CPU 再从“办公桌(缓存)”上,把 r0 真正需要的那 4 个字节的数据,抓取到“0号抽屉(r0 寄存器)”中。
    • LDR r0, [r1] 指令终于完成。
  6. CPU 恢复执行

    • “等待”结束。
    • CPU 继续执行下一条指令 STR r2, [r3]

什么叫指令顺序优化

  • 简单来说,就是 CPU 不严格按照你写的代码顺序来执行指令,而是在保证程序最终结果正确的前提下,打乱顺序,谁的条件先满足,谁就先执行,以此来“压榨”CPU的性能。

  • 想象一下,你(CPU)早上起床做早餐,你的“指令列表”如下:

    • 烧水(需要10分钟)
    • 烤面包(需要3分钟)
    • 从冰箱拿果酱(需要30秒)
  1. 场景一:老的ARM处理器(按序执行 In-Order Execution)

    • 这种处理器是个“死脑筋”,它严格按照指令顺序来:
      • 执行 烧水:打开水壶。
      • 等待:站在原地干等10分钟,直到水烧开。(这就像LDR缓存未命中,CPU在“停顿/Stall”)。
      • 执行 烤面包:水烧开后,把面包放进烤面包机。
      • 等待:再等3分钟。
      • 执行 拿果酱:面包烤好后,跑去冰箱拿果酱。
    • 总耗时:10分钟 + 3分钟 + 30秒 = 13.5 分钟。 效率极低!
  2. 场景二:ARM v6/v7 处理器(乱序执行 Out-of-Order Execution)

    • 这种处理器非常聪明,它会“预读”整个指令列表,并分析它们之间的依赖关系:

    • 烤面包 需要依赖 烧水 吗?不需要。

    • 拿果酱 需要依赖 烧水 或 烤面包 吗?也不需要。

    • 于是,它的执行流程变成:

      • 执行 烧水:打开水壶。(这是一个耗时操作,CPU知道它需要等,于是把它丢给“水壶”去处理)。
      • 立即执行 烤面包:在水壶烧水的同时,把面包放进烤面包机。(这就是你例子中的 STR 指令)。
      • 立即执行 拿果酱:在水壶烧水和面包机烤面包的同时,跑去冰箱拿果酱。
      • 等待:现在,所有能“偷跑”的指令都执行了,CPU只需等待最长的那个任务(烧水)完成即可。
    • 总耗时:取决于最长的那个任务 = 10 分钟。 效率极高!

http://www.dtcms.com/a/574535.html

相关文章:

  • 怎样可以查看网站是由哪个公司做的做网站每个月可以赚多少钱
  • 铜陵市建设工程管理局网站网站文字不能编辑器
  • 【从模仿到创造:大模型如何通过“先SFT后RL”实现能力进化?】
  • 外贸网站建设wordpresswordpress数据库加密方式
  • 徐州网站建设优化宣传做网站要租服务器
  • 做生存曲线网站清远市建设工程交易中心网站
  • 解决Linux串口登录界面重复输入密码
  • 【iso8601库】ISO 8601 低层解析器详解(parsers.rs)
  • 有什么网站可以接手工加工做在线免费看电视剧的网站
  • 类似享设计的网站做贸易选哪家网站
  • 算法笔记 10
  • 锛网站开封seo公司
  • Linux 进程资源占用分析指南
  • 电子商务网站建设评估的指标wordpress程序图片打开慢
  • 网站开发时如何设计英文版本山东手机网站建设
  • 算法题种类与解题思路全面指南:基于LeetCode Hot 100与牛客Top 101
  • Web开发身份认证技术解析
  • 做汽车网站怎么挣钱吗深圳网站建设公司好
  • 网站建设素材网页apache 创建网站
  • 虚函数指针与虚函数表:C++多态的实现奥秘
  • 小说类网站怎么做建设推广营销型网站应该注意什么
  • ubuntu 安装 SRS (Simple RTMP Server) 是一个开源的流媒体服务器
  • 怎么自己设计网站外贸公司 网站
  • 【仓颉纪元】仓颉鸿蒙应用深度开发:待办事项 App 全流程实战
  • 领英被封?账号受限该怎么处理?
  • 信誉好的镇江网站建设网站备案名称中国开头
  • 【C语言】localtime和localtime_r;strftime和strftime_l
  • 扁平化设计网站代码打开网站后直接做跳转
  • Go 语言依赖注入实战指南:从基础到高级实践
  • 全场景自动化 Replay 技术:金仓 KReplay 如何攻克数据库迁移 “难验证“ 难题