ARM为什么单个STM指令通常比多个STR指令更快?

4

这与某些预取技术有关吗? 还是与DDR访问时间特性有关?

3个回答

7

据我所知,从ARMv5TE开始,写缓冲区和L1缓存的路径变为64位宽,以适应LDRD/STRD指令。这使得STM每个周期可以写入两个寄存器。

此外,您还将节省一些L1指令缓存,并仅使用双发射内核上的一个流水线,这也是额外的收益。


4
更多的指令,更多的获取周期,更多的执行指令,需要更长的时间。总线可以是或可以为64位宽,对于单个寄存器stm而言,没有收益,但对于多个寄存器来说,数据移动的总线周期可以减少,并且根据内存系统的情况(如果是64位宽),读取-修改-写入将变得缓慢。如果必须在高速缓存中进行读取-修改-写入(通常应该是写入),那么您将失去高速缓存空间以及读取的成本。即使是在高速缓存中,读取-修改-写入也可能会使您付出代价。
您可以访问ARM网站并下载AMBA / AXI规范,了解总线事务的工作原理,每个事务涉及多个时钟周期(多个事务可以同时进行)。一旦您超过开销,每传输64位数据需要一个时钟周期,因此128位比64位多需要一个时钟。传输32位和64位需要相同数量的时钟周期(如果对齐)。
我无法代表所有架构发言,但我相信至少有一个架构只有读取实际上会执行超过64位的转移。写入被分成单独的64位传输。我可能记错了。
如果移动4个字大小的数据,读取或写入,未对齐,我相信这将成为4个单独的传输,分别用于奇数字和中间64位对齐。因此,对齐可能很重要。

我认为这与AXI/AMBA无关。通常,存储器会首先命中写缓冲区,该缓冲区是核心的一部分,不连接到内部总线。 - Nico Erfurth
核心具有L1缓存,接口不是AMBA/AXI,但如果缺失,则转到位于AMBA/AXI上的L2缓存,然后如果缺失,则在另一个AMBA/AXI总线上退出。无论哪种方式,更多的指令意味着更多的单独事务,每个事务都有开销。我忘记加上MMU(如果有缓存则经常有)这进一步增加了每个事务的开销成本。 - old_timer
@dwelch:对于MMU,只会有一个(也许两个)TLB命中/失误。 对于数据而言,在这两种情况下都是相同的。 除非你在谈论代码; 多个STR获取加上多个STR填充代码缓存会减少其效率。 - artless noise
如果缺失tlb,则必须进入ram,可能会错过l1和l2并进入ram,这可能至少需要一个或两个额外的时钟周期,太多时钟周期,无论如何,这是多个str和一个stm之间可测量的明显差异。 - old_timer
是的,但您只是在谈论代码。对吗?无论如何,数据都是相同的。或者我没理解。数据将在相同的页面中,以便TLB查找无论在哪里进行,都是相同的? - artless noise
整个问题与多个str指令和单个stm指令之间的内存事务数量有关,并试图解释为什么stm可以(不总是)比多个str具有优势。多个事务意味着多个tlb查找,而单个事务则只有一个查找(是的,您会遇到跨越页面边界的问题)。第一个tlb查找的价格相同,如果有更多事务,则价格会增加。对于内部和外部总线、核心和缓存也是如此。 - old_timer

2

什么情况下是正确的?

根据这个方便的表格STM指令需要2个周期来存储一个寄存器,或者需要n个周期来存储n个寄存器,其中n > 1。

另一方面,STR总是需要1个周期。

什么时候STMSTR更快?

  • 对于一个寄存器,STM更慢。
  • 对于n个寄存器(n > 1),它们是相同的。

另一方面,上述参考资料适用于ARM9TDMI架构,而且有很多ARMS。


1
+1 表示图表正确,-1 表示我认为您没有正确阅读图表。数据总线就像您所说的那样。STR[1N] 与 STM[1N + (n-1)S],但前提是内存总线为零/对称等待状态。对于 I 通道,它是 STR[1S] 与 STM[1S+(n-1)I]。'I' 意味着如果下一条指令不依赖于寄存器,则可以立即运行。即使对于 ARM9TDMI,也存在差异。 - artless noise
最近的实践中,我发现当禁用L1缓存和MMU时,使用STM实现的memset比for循环赋值要快得多。@unwind - Mario Cao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接