You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cortex-M4测量函数执行耗时两种方法的优缺点对比

Cortex-M4平台两种函数执行耗时测量方案对比

在搭载Cortex-M4内核的SOC上测量函数执行耗时,你找到的两种方案都是内核寄存器级的原生实现,不需要外挂外设,各自的适用场景、优劣势差异很明显:


方案1:基于DWT_CYCCNT周期计数器实现

参考实现代码如下:

REGISTER(DEMCR_ADDR) |= 1 << 24 ; // 开启DWT组件的TRACE访问权限
REGISTER(DWT_CTRL) |= 1; // 启动CYCCNT计数
startTime = REGISTER(DWT_CYCCNT);
// 运行待测量的目标函数/逻辑
elapsedTime = REGISTER(DWT_CYCCNT) - startTime;
REGISTER(DWT_CTRL) &= ~1; // 关闭DWT计数

优势

  • 精度为单个CPU时钟周期,是Cortex-M平台能达到的最高计时精度,测量纳秒级、微秒级的短函数时几乎没有精度损失
  • 计数过程完全不产生中断,测量逻辑本身不会触发上下文切换、中断进出栈等额外开销,对被测代码的运行干扰极小
  • CYCCNT是32位递增计数器,以Cortex-M4常见的168MHz主频计算,单次计数溢出周期约25秒,覆盖绝大多数普通函数的执行时长范围,短时间测量不需要额外写溢出处理逻辑
  • 整个测量过程不需要修改SysTick的原有配置,不会和已经占用SysTick做系统节拍的RTOS、裸机延时组件产生冲突,接入成本极低

缺陷

  • DWT属于内核调试组件,部分车规、高安全等级的量产SOC会永久锁死DWT的访问权限,量产固件中可能无法正常开启该功能
  • DWT计数的时钟和内核时钟绑定,当CPU进入休眠停钟、动态降频场景时,DWT计数会随内核时钟暂停/变慢,测量结果和实际墙钟时间会有偏差,不适合带低功耗逻辑的长流程测量
  • 原生配置没有溢出中断支持,如果要测量超过25秒(168MHz主频下)的长流程,需要额外实现轮询溢出的逻辑,使用起来不如带中断的定时器方便

方案2:基于SysTick系统定时器实现

参考实现代码如下,注意原示例里的耗时计算逻辑存在错误:SysTick是递减计数器,正确的计数值差应该用初始值减去结束值,否则会得到负数结果:

// 测量前初始化
SysTick->LOAD  = SysTick_LOAD_RELOAD_Msk;                         /* 配置重装载值为计数器最大量程 */
SysTick->VAL   = 0UL;                                             /* 清零当前计数 */
SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                 SysTick_CTRL_ENABLE_Msk;                         /* 选择内核时钟作为时钟源,启动定时器 */

startTime = SysTick->VAL;
// 运行待测量的目标函数/逻辑
elapsedTime = startTime - SysTick->VAL; // 原示例写为SysTick->VAL - startTime为逻辑错误

// 测量结束后复位寄存器
SysTick->LOAD  = SysTick_LOAD_RELOAD_Msk;                         
SysTick->VAL   = 0UL;                                             
SysTick->CTRL  = 0UL; // 关闭SysTick

优势

  • SysTick是Cortex-M架构强制要求标配的内核外设,所有量产Cortex-M4芯片100%支持,不存在DWT那样被厂商锁死无法访问的问题,兼容性最好
  • 自带溢出中断功能,即使测量数分钟级别的长流程,只需要在中断服务函数里累加溢出次数就能实现无回绕的连续计时,长时测量逻辑实现简单
  • 时钟源可配置,既可以选内核时钟,也可以选外部常开门的参考时钟,部分低功耗场景下即使内核休眠停钟,也能通过外部时钟获得准确的墙钟时间

缺陷

  • 直接操作SysTick寄存器做测量会覆盖系统原有配置:绝大多数裸机框架、RTOS都依赖SysTick产生系统调度节拍、毫秒级延时,测量过程中修改SysTick配置会直接导致系统延时不准、任务调度异常,除非系统专门预留了计时接口,否则适配成本很高
  • SysTick的计数寄存器只有24位,配置为最大量程时,以168MHz主频计算单次无溢出计数窗口仅约0.1秒,测量执行时间稍长的函数就必须处理溢出,否则结果完全错误
  • 如果开启SysTick中断处理溢出,中断响应、进出栈的固定开销会给被测流程引入额外误差,测量微秒级短函数时,这个误差的占比会非常高,结果参考价值低
  • 测量初始化和收尾需要操作3个寄存器,测量逻辑本身的代码开销比DWT方案高,测极短函数时,测量代码本身的耗时占比更明显,容易拉高结果误差

内容的提问来源于stack exchange,提问作者RDF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:15:51