【发布时间】:2019-10-28 20:26:14
【问题描述】:
我在 STM32H753I-EVAL2 板上对 STM32H7 进行一些评估。我使用 STMicro 示例代码在内存映射模式下配置、写入和读取 QSPI Flash。
我对一些关于 LDR 指令持续时间的数字感到惊讶:
我使用 SysTick(连接到 CPU 时钟)测量指令的周期数。据我了解:一个 SysTick 周期 = 一个 CPU 周期。
我测量了两条完全相同的指令
ldrb.w Rn, [Rp, Rq],除了 Rp 在一种情况下是 DTC-RAM 中的地址,在另一种情况下是地址 在 QSPI 闪存中。
结果是(从内部闪存执行的代码):DCTM-RAM 15 个周期,QSPI 12 个周期。
我对结果感到惊讶,我猜如果缓存了 QSPI 内容,那么它可以解释这些数字吗?
我还发现一条 LDR 指令的 15 个周期似乎很多,你觉得呢?我的程序有问题吗?
【问题讨论】:
-
代码本身是否从内部闪存运行?它是否与缓存行边界对齐?同时 RAM 是否用于其他用途,例如显示图形?
-
您是否测量了多个加载指令的展开块以隐藏测量开销?我不确定 Cortex-M 是否可以在前一个负载仍在运行时开始执行下一条指令。因此,单独测量单个指令可能不具有代表性,具体取决于 Cortex-M 的简单程度。
-
@berendi 是从内部闪存执行的代码,我没有修改映射,也没有检查缓存行对齐。 RAM 没有用于其他用途。
-
你的 CPU 确实有 16kiB 每个 L1i 和 L1d 缓存。 (因此循环可以从缓存运行,除非该内存区域或完全禁用缓存)。 STM32H753I-EVAL2 使用st.com/en/microcontrollers-microprocessors/stm32h753xi.html,即Cortex-M7 core,它是双问题超标量。所以是的,测试一条指令可能不是很好。取决于您要测量的内容,但如果您安排好指令,通常一条指令的执行将能够与之前或之后的一条指令重叠。
-
测试缓存负载吞吐量的一个好方法是将一大块
ldrb或ldr指令放在一个循环中,这样每 256 次加载或其他东西就有 1 条循环开销指令.您希望循环适合指令缓存,除非您也想测试 I-fetch 的竞争。 (使用不同的寄存器来避免 WAW 危险(或者不查看是否重复加载相同的 reg 会导致瓶颈),如果要从不同的缓存行加载,请在寻址模式中使用偏移量。例如,使它们都别名为同一个集合并获得缓存未命中。)
标签: performance assembly arm stm32 cortex-m