【问题标题】:cache read system memory vs cpu read system memory缓存读取系统内存 vs cpu 读取系统内存
【发布时间】:2017-04-26 01:44:56
【问题描述】:

在运行 Android/Linux 的基于 arm 的 SoC 上,我观察到以下情况:

  1. 将内存区域分配为未缓存用于设备 DMA 输入。 DMA 完成后,这个内存区域的内容被复制到另一个系统内存区域。
  2. 为设备 DMA 输入分配一个内存区域作为缓存。 DMA完成后,使内存范围无效,然后将此内存区域的内容复制到另一个系统内存区域。

分配的内存区域大小约为 2MB,大于缓存大小(L2 缓存大小为 256KB)。

方法 2 比方法 1 快 10 倍

即:方法2的内存复制操作比方法1快10倍

我推测方法 2 在复制时使用 cache line size 从系统内存读取缓存,而方法 1 需要通过 bus transaction size 从系统内存读取 cpu 绕过缓存硬件。

但是,我找不到明确的解释。感谢谁能帮忙提供详细的解释。

【问题讨论】:

  • 问题不仅仅在于“缓存”版本能够通过缓存访问服务所有后续请求,而未缓存版本必须一直通过内存获取数据。

标签: memory arm cpu-architecture cpu-cache


【解决方案1】:

涉及的硬件项目太多,很难具体说明。 SOC 在很大程度上决定了这一点。但是,您观察到的在现代 ARM 系统的性能方面是典型的。

主要因素是SDRAM。所有 DRAM 都由“行”和“列”构成。DRAM history 在 DRAM 芯片上,一次可以读取整个“行”。即,有一个晶体管矩阵,并且有一个物理点/布线可以读取整行(实际上可能有 SRAM 将 ROW 存储在芯片上)。当您阅读另一个“列”时,您需要“取消充电/预充电”接线以访问新的“行”。这需要一些时间。要点是 DRAM 可以非常快速地大块读取顺序内存。此外,由于内存随每个时钟沿流出,因此没有命令开销。

如果您将内存标记为未缓存,则 CPU/SOC 可能会发出单拍读取。通常这些会在单次读/写期间“预充电”消耗额外的周期,并且必须将许多额外的命令发送到 DRAM 设备。

SDRAM 也有“银行”。一个银行有一个单独的“ROW”缓冲区(静态 RAM/多晶体管存储器),它允许您从一个银行读取到另一个银行,而无需重新充电/重新读取。银行往往相距甚远。如果您的操作系统已将“未缓存”内存物理分配到与第 2nd“缓存”区域不同的银行中,那么这也会增加额外的效率。在操作系统中,单独管理缓存/非缓存内存很常见(针对 MMU 问题)。内存池通常足够远,可以位于不同的存储区中。

【讨论】:

  • 如您所说:如果您将内存标记为未缓存,则 CPU/SOC 可能会发出单拍读取。缓存的情况如何?我知道这可能取决于实现,是否有一个常见的做法来读取数据(通过缓存控制器)?谢谢
  • 缓存是命中(在缓存中)或未命中。如果是未命中,则将其放入缓存中,但必须清除某些内容。这是通过“方式”机制和随机或 LRU(最近一次使用)替换来完成的。但是,对于memcpy(),缓存无关紧要。您不要重复使用数据,因此缓存对写得很好的memcpy()没有任何好处。
  • “惯例”始终是高速缓存行。它通常是一个或两个 SDRAM 突发读/写大小(不是行长度)。您不必重新发出命令(预充电)是您按顺序读取一行。典型的最大 DDR bw 大约是时钟速率。即,由于命令开销,16bit 500MHz DDR 约为 1GB/s。
猜你喜欢
  • 2020-11-07
  • 1970-01-01
  • 2016-10-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多