assembly 简单延迟环路上的ARM Cortex-M7组件时序-如何解释结果?

cczfrluj  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(171)

由于AFAIK周期计时尚未公布,我决定尝试使用STM32 H750-DK上的DWT计数器测量周期计数;作为第一个例子,我正在测量一个简单的延迟环路。
Cortex-M7似乎每个周期可以执行两条指令。如果将它们转换为16位指令,我就能理解这一点。但如果使用寄存器R8及以上,并将指令转换为32位指令,结果也是如此。
分支预测真的是这里的主要参与者吗?在第一次运行时,我得到了更多的周期,但是在随后的重复中,不管N是多少,都注意到了6个周期的增加。
是否有更多关于Cortex-M7流水线的信息可以帮助解释我得到的结果?我甚至不确定结果是否有意义。我是否正确解释了这些结果?

//-------------- not measured --------------------------
//      ldr r5,=N
// ------------- code under cycle measurement ------
// tloop:  subs r5,r5,#1
//         bne  tloop
// ------------- konec kode ------------------------
/*
// Timings - usually in second or more repetitions
// (on first one cycles are higher in brackets)
╔═══════╤════════════════╗
║ N     │ DWT_CYCCNT(1st)║
╠═══════╪════════════════╣
║ 50    │ 56     (78)    ║
╟───────┼────────────────╢
║ 100   │ 106    (128)   ║
╟───────┼────────────────╢
║ 200   │ 206            ║
╟───────┼────────────────╢
║ 500   │ 506            ║
╟───────┼────────────────╢
║ 1000  │ 1006           ║
╟───────┼────────────────╢
║ 64000 │ 64006 (64028)  ║
╚═══════╧════════════════╝
Comment: difference: R5 instructions are 16-bit, R8 instructions are 32-bit,
         but both with same timing.
         If nop is added, for N=64000, results are 96030 (first run) and 96006.
Conclusion: it seems that branch prediction is the main influencer here.
eeq64g8w

eeq64g8w1#

你在一个STM32上,所以有一个闪存缓存和预取器。如果你是从闪存运行,那么这将影响你的结果。
该特定芯片还需要闪存等待状态,这取决于时钟频率和电压,进而影响读取速率。
Cortex-M7有一个很大的提取线,在小循环对齐的地方,这可能/将对整体性能产生巨大影响(相同机器代码的执行时间增加了几十个百分点)。
Cortex-M7有一个分支预测器,虽然不确定他们是否使用了这个术语,但它确实存在,如果我没记错的话,它默认启用。
这不是一个PIC。我们不看指令和计算时钟,我们编写应用程序,然后在需要的时候分析它们。特别是在这样的架构/内核上,添加或删除一行高级语言代码就可能在两个方向上产生两位数的性能变化。人们和我争论说,这些内核实际上是可预测的。也就是说,相同的代码序列在没有其他非确定性影响的情况下,将运行相同数量的时钟,而且它确实会运行相同数量的时钟。我已经多次演示了这一点。但是,添加NOP来更改代码的对齐,则该代码的时钟数量可能会更改,这些都是流水线处理器,虽然不是很深(对于Cortex-M0等),这意味着不可预测(从检查指令和计数周期,就像过去的好日子一样)。
你也有系统性的影响。ARM制造处理器核心,IP,而不是芯片。芯片供应商在执行性能方面扮演着巨大的角色(x86也是如此-我们已经很长时间没有处理器绑定了)、如何处理这些总线以及他们购买的闪存和SRAM的IP、仲裁等等。如上所述,ST在Cortex-M产品方面的做法与TI和恩智浦不同,所有这些产品都会对闪存性能产生负面影响,即使是零等待状态,这通常意味着处理器时钟速度的一半。(必须使用TI或恩智浦,ST无法做到这一点),闪存上的零等待状态,对于相同的机器代码,性能是SRAM的一半,相同的对齐(至少我已经看到,在一些产品上,与ST你可以玩一些游戏,以刷新该高速缓存并采取一个单一的运行在代码)。
如果您的目标是查看Cortex-M7是否是超标量,请在SRAM中填充成百上千条指令,然后循环执行。一个大循环,占被测指令的99.99... %。关闭分支预测和任何缓存(此时,分支预测的几个时钟实际上应该是无用的),然后看看你看到了什么。关于这个问题,我已经阅读了数据手册和数据手册,但我没有回过头来了解SRAM的性能。ARM等高性能内核对系统、读取、加载和存储都很敏感。MCU在时钟域方面会使情况变得更糟。而外设则完全是另一回事(在环路中对GPIO引脚进行采样并不像大多数人想象的那么快)。
编译器也不知道这个系统,他们将执行一个PC相对加载来提取一个困难的常数(0x 12345678)写入寄存器而不是Thumb-2扩展,我记不清手头的MOVT或其他内容,先加载一半,然后再加载一半,64位指令,但这是一个线性提取,而不是停止,并从慢闪存执行一个加载周期,这会消耗更多时钟。程序员也没有意识到这一点,如果他们试图计数时钟来提高性能。如果这是你在这里的最终目标。
你不受处理器的限制是底线,你不能考虑流水线和指令序列,等等,除非你在模拟中运行内核,并且你有一个完美的模拟内存,其中读数据总线在第一个可用的时钟周期响应读地址总线。使用这个内核,即使在这种情况下,你仍然会看到分支预测和取线对齐的效果。进入真实的的MCU,您总是会遇到闪存问题,有时会遇到SRAM问题,有时还会遇到一般的芯片粘合/实现问题。

相关问题