你能帮我理解 ARM Cortex-A9 上的缓存行为吗?

Posted

技术标签:

【中文标题】你能帮我理解 ARM Cortex-A9 上的缓存行为吗?【英文标题】:Can you help me understand the cache behaviour on an ARM Cortex-A9? 【发布时间】:2015-03-18 11:25:03 【问题描述】:

我试图了解在 LOAD 和/或 STORE 指令期间发生了什么。因此,我进行了 4 次测试,每次都测量 CPU 周期数 (CC)/缓存命中数 (CH)/未命中数 (CM)/数据读取数 (DR)/写入数 (DW)。

读取不同的计数器后,我只刷新 L1(I/D 缓存)。

测试1:

LDRB    R3, [R4,#1]!
STR     R3, [SP,#0x48+var_34]

Results: 4 (CC) 3(CH) 1(CM) 1(DR) 2(DW)

测试2:

 LDR     R3, [SP,#0x48+var_34]
 LDR     R3, [R3]

 Results: 4 3 1 2 1

测试3:

LDR     R3, [SP,#0x48+var_38]
LDR     R3, [R3]
STR     R3, [SP,#0x48+var_30]

Results: 4 4 1 2 2 
var_30 is returned at the end of the current function.

测试4:

LDR     R2, [SP,#0x48+var_34]
LDR     R3, [R2] 

Results: 4 3 1 2 1  

这是我的理解:

1.缓存未命中

在每个测试中,我们都有 1 次缓存未命中,因为当一次执行时

LDR reg, something

"Something" 将被缓存,并且会出现缓存未命中。

而且……这几乎是我能做出的唯一“合乎逻辑”的解释…… 我不明白缓存命中、数据读取和数据写入的不同值。

有什么想法吗?

【问题讨论】:

【参考方案1】:

infocenter.arm.com 上的 arm 文档非常清楚地说明了 amba/axi 文档中的 axi/amba 总线上发生的情况。现在处理器到 L1 是紧密耦合的,而不是 amba/axi,都在内核中。如果您只清除 L1,则 L2 可能仍包含这些值,因此如果 L2 未命中,一个实验与其他实验相比可能会显示不同的结果。此外,您不仅要测量加载和存储,还要测量指令的获取,即使有两条指令,如果高速缓存行位于它们之间,它们的对齐方式也会改变结果,性能可能与它们在一起时不同。有一些实验可以根据一行内的对齐来确定何时以及是否另一个缓存行提取。

在这样的处理器上尝试获得确定性数字也有点困难,尤其是在缓存开启的情况下。如果您在裸机以外的任何设备上运行这些实验,则没有理由期待任何有意义的结果。对于裸机,结果仍然值得怀疑,但可以使其更具确定性。

如果您只是想了解非特定于 arm 或任何其他平台的缓存基础知识,那么只需 google 一下,去***等。那里有大量信息。缓存只是更快的内存,更接近处理器的时间以及快速(更昂贵)的内存。所以很简单,缓存会查看您的地址,在一个表或一组表中查找它并确定命中或未命中,如果命中则返回值或接受写入数据并完成事务的处理器端(允许处理器继续,但随后去写缓存,基本上火了就忘了)。如果未命中,则它必须确定缓存中是否有用于该数据的空闲开口,如果没有,则必须通过将其写出来驱逐某些内容,或者如果已经有一个空点,则可以读取缓存行这通常比您要求的阅读量大。这以与 l1 相同的方式命中 l2,命中或未命中驱逐或不命中等等,直到它命中缓存层,或者直到它命中最终的 ram 或从中获取数据的外围设备。然后在返回 l1 的途中将其写入所有缓存层,然后处理器获取它所要求的一点点数据。如果处理器现在请求该缓存行中的另一个数据项,它在 l1 中并且返回非常快。 l2 通常比 l1 大,依此类推,l1 中的所有内容都在 l2 中,但 l2 中的所有内容都在 l1 中,因此您可以从 l1 驱逐到 l2,如果出现某些情况,它可能会错过 l1,但命中 l2 并且仍然比慢速 DRAM 快得多。这有点像将工具或参考资料或您最常使用的任何东西放在办公桌前,而您不常将东西放在更远的地方,因为没有空间容纳所有东西,因为您更改项目或发展最常用的东西最不经常改变的是,桌子上的位置也会改变。

【讨论】:

好的,我会检查 axi/amba 规范。我现在也刷新 L2,CC/CH/CM/DR/DW 的值现在相当稳定。例如,对于第 4 次测试,我得到 4 3 2 2 1。 当您说“没有理由期待任何有意义的结果”时,您是对的。我会尝试用裸机进行测试。我了解了缓存基础知识(几乎),我只是想更好地了解我正在使用的当前平台(ARM cortex-A9)上的缓存行为。 l1 通常是核心的一部分,它是您正在使用的特定核心的 arm 网站上的技术参考手册。如果您有一个希望芯片供应商指定的项目,l2 是一个附加项目,也是来自 arm 网站的单独技术参考手册。那么除此之外的任何东西都是特定于芯片供应商的,如果重要的话,你必须去找芯片供应商。 要尝试获得意味着您可能需要从干净的缓存开始的结果,尝试选择与测试程序正在访问的东西不对齐的地址,诸如此类的东西,做数据缓存您需要启用 mmu,这样您就可以仅在被测数据地址空间上启用缓存,而其余部分甚至不缓存指令。尽管指令会影响结果,但您需要控制指令在缓存行中的偏移量,在您的实验中移动它 您可能还想启用 i 缓存,使用不在 d 缓存空间中的地址或在调用之后刷新缓存但基本上您想要获得I 缓存中的指令,让这些传输全部解决,然后执行 dcache 指令,以便仅测量 dcache 延迟。除非您希望同时应用 I 和 D 缓存延迟。如果 i 和 d 已启用并且您在第一次执行被测指令之前没有运行/缓存它们

以上是关于你能帮我理解 ARM Cortex-A9 上的缓存行为吗?的主要内容,如果未能解决你的问题,请参考以下文章

你能帮我理解指针和地址吗?

var that = this - 你能帮我理解吗[重复]

你能帮我理解这个吗? “常见的 REST 错误:会话无关紧要”

ARM Cortex-A9 (tiny 4412)

为啥 GCC 会为 ARM Cortex-A9 产生非法未对齐访问

谁能帮我翻译一下