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

【ARMv8/v9 异常模型入门及渐进 10 -- WFI 与 WFE 使用详细介绍 1】


请阅读【ARMv8/v9 ARM64 System Exception】


文章目录

    • WFI 与 WFE
      • 等待事件(WFE)
      • 发送事件(SEV)
      • 本地发送事件(SEVL)
      • WFE 唤醒事件
    • WFE 使用场景举例与代码实现
      • wfe睡眠函数
      • sev 事件唤醒函数
      • 全局监视器和自旋锁

WFI 与 WFE

ARMv8架构提供了几个与事件相关的指令,包括等待事件(WFE)、发送事件(SEV)和本地发送事件(SEVL),这些指令有助于减少因处理器元素(PE,Processor Element)反复尝试获取自旋锁(spin-lock)而导致的功耗和总线竞争。这些指令在应用层面上是可用的,但要完全理解它们的行为,需要系统级别的异常处理知识。下面详细介绍这三个指令的功能及其对系统性能优化的影响。

等待事件(WFE)

WFE指令使得一个处理器元素可以进入低功耗状态,直到发生以下情况之一:

  • 发生了一个异常。
  • 接收到一个事件信号。
  • 如果存在外部中断,处理器也可能被唤醒,即使这个中断最终被处理器的状态所屏蔽。

WFE指令通常用于自旋锁等待循环中,允许处理器在等待锁释放的时候降低功耗。

发送事件(SEV)

SEV指令用于在同一系统中的一个或多个处理器元素之间发送事件信号。当一个处理器执行SEV指令时,它将触发系统中所有正在执行WFE指令等待事件的处理器元素退出等待状态。 在自旋锁释放后使用SEV指令可以唤醒等待该锁的其他处理器元素,这有助于减少等待时间和功耗。

关于spin_lock与独占访问的关系推荐阅读
【ARM AMBA AXI 入门 7 - AXI 协议中的独占访问 使用背景介绍】
【ARM AMBA AXI 入门 6 - AXI3 协议中的锁定访问之AxLOCK信号】

本地发送事件(SEVL)

SEVL指令与SEV类似,但它只确保发出事件信号的处理器元素本身在下一次执行WFE指令时立即返回,而不进入等待状态。这有助于优化特定的同步模式,其中处理器元素可能需要在检查某个条件后立即继续执行,而不是等待。

WFE 唤醒事件

WFE(Wait For Event)指令让处理器进入等待状态,直到发生特定的唤醒事件(Wake-up Events)。这些事件可以来自多种不同的源,以下介绍了在AArch64状态下可以触发WFE指令唤醒处理器的事件:

  1. 执行SEV指令:在多处理器系统中,任何处理器元素(PE)执行SEV(Send Event)指令都可以作为一个唤醒事件。SEV指令用于在PE之间发送全局事件信号。
  2. 物理SError中断、IRQ中断或FIQ中断:如果PE收到物理SError中断、IRQ(Interrupt Request)中断或FIQ(Fast Interrupt Request)中断,并且该中断没有被EDSCR.INTDIS(一个调试寄存器的一部分,用于禁用中断)禁用,那么这个中断会作为一个唤醒事件。
  3. 异步外部调试请求:如果允许暂停执行(Halting),那么一个异步外部调试请求也可以作为一个唤醒事件。这种情况通常与调试过程有关。
  4. 由处理器元素的定时器事件流发送的事件:处理器元素的定时器可以配置为在特定时间点发送事件,这些事件也能唤醒处于WFE等待状态的PE。
  5. 全局监视器清除造成的事件:当PE的全局监视器从独占访问状态变为开放访问状态时,会生成一个事件,这也可以唤醒等待的PE。
  6. 由某些实现定义机制发送的事件:特定的硬件实现可能提供了其他机制来生成唤醒事件,这些机制依赖于具体的硬件设计和配置。
  7. 实现FEAT_WFXT特性时的本地超时事件:当实现了FEAT_WFXT特性,并且使用WFET指令时,如果虚拟计数器阈值(在CNTVCT_EL0寄存器中表示)被等于或超过,就会产生本地超时事件作为唤醒事件。

WFE 使用场景举例与代码实现

这里以 多核系统中主核 core0 启动后去唤醒处于睡眠状态的从核 core1 为例 并测试。

首先使用汇编代码实现 sevwfe 的调用函数:

wfe睡眠函数

func enter_wfewferet
endfunc enter_wfe

sev 事件唤醒函数

func arm_sevsevret
endfunc arm_sev

从核启动函数(截取部分)

    ...log_debug("\rcore%d run wfe then goto sleep\n", coreid_get());enter_wfe ();log_debug("\rcore%d wakeup from wfe\n", coreid_get());enter_wfe ();
  • 场景是主核core0先启动,然后使用命令手动去启动从核core1, core1 启动后后面执行到 enter_wfe 之后就会睡眠,
  • 然后主核执行 sev 指令来唤醒从核,然后从核醒后执行一句打印,然后再去执行 enter_wfe 继续睡眠。
    在这里插入图片描述

全局监视器和自旋锁

ARMv8架构中引入了全局监视器的概念,当处理器元素(PE)的全局监视器从独占访问状态变为开放访问状态时,会自动生成一个事件。这相当于在PE上执行了SEVL指令。因此,当一个PE释放自旋锁时,不再需要在代码中显式包含SEV指令来唤醒等待锁的其他PE,系统会自动生成相应的事件,

这简化了编程模型并有助于提高效率。 这种机制特别适用于多核处理器环境中的同步问题,可以减少因PE反复尝试获取自旋锁而导致的功耗和总线竞争,进而提升系统性能和能效。

http://www.lryc.cn/news/351295.html

相关文章:

  • @DateTimeFormat 和 @JsonFormat 的区别和使用方式
  • C++—结构体
  • 指针与引用
  • 使用 mysql-binlog-connector 监听处理 MySQLBinlog 文件
  • CF Div2 729 Plus and Multiply
  • Joomla 3.7.0 (CVE-2017-8917) SQL注入漏洞环境
  • Python高克勒-曼宁-斯特里克勒公式计算一维流量
  • 【GD32系列--基本定时器Timer + 定时1ms 灯光间隔1s闪烁例程】
  • 第11章 集合与迭代器
  • 探索Linux中的神奇工具:探秘tail命令的妙用
  • 1688商品API接口:电商数据自动化的新引擎
  • 路由器不能端口映射什么原因?如何设置内网映射?
  • 开源RAG,本地mac启动 dify源码服务
  • 【Linux取经路】基于信号量和环形队列的生产消费者模型
  • 计算机SCI期刊,中科院2区,收稿范围非常广泛!
  • JDK、JRE、编译指令和垃圾回收机制详解
  • 【ARM 嵌入式 C 入门及渐进 6.2 -- ARMv8 C 内嵌汇编读系统寄存器的函数实现】
  • 使用 LlamaParse 进行 PDF 解析并创建知识图谱
  • Oracle行迁移解析
  • 【k8s】 busybox镜像、挂载volume卷
  • 文本三剑客之 sed 编辑器
  • 【MySQL精通之路】SQL优化(1)-查询优化(3)-索引合并
  • Linux中安装配置并使用samba服务(Centos以及Ubuntu)
  • three.js能实现啥效果?看过来,这里都是它的菜(06)
  • 利用ESP32-C3将TF卡内容变成U盘进行读取
  • C++小病毒
  • 使用VUE3+TS+elementplus创建一个增加按钮
  • Python面试宝典:文件读写和上下文管理器以及输入输出流面试题(1000加python面试题助你轻松捕获大厂Offer)
  • Spring Boot | Spring Boot 实现 “记住我“ 功能
  • AGM AG32 MCU替代GD32F407/STM32F407的手持示波器方案