![为什么 RAM 的写入速度低于读取速度?缓存又是如何发挥作用的?](https://linux22.com/image/1385869/%E4%B8%BA%E4%BB%80%E4%B9%88%20RAM%20%E7%9A%84%E5%86%99%E5%85%A5%E9%80%9F%E5%BA%A6%E4%BD%8E%E4%BA%8E%E8%AF%BB%E5%8F%96%E9%80%9F%E5%BA%A6%EF%BC%9F%E7%BC%93%E5%AD%98%E5%8F%88%E6%98%AF%E5%A6%82%E4%BD%95%E5%8F%91%E6%8C%A5%E4%BD%9C%E7%94%A8%E7%9A%84%EF%BC%9F.png)
首先,这是真的,对吧?我觉得读取总是比写入快,还有这个家伙这里做了一些实验来“证明”这一点。他没有解释原因,只是提到了“缓存问题”。(而且他的实验似乎并不担心预取)
但我不明白为什么。如果这很重要,我们假设我们谈论的是 Nehalem 架构(如 i7),它为每个核心提供 L1、L2 缓存,然后是共享的包容性 L3 缓存。
可能是因为我没有正确理解读写的工作原理,所以我会写下我的理解。如果有错误,请告诉我。
If I read some memory, following steps should happen: (assume all cache misses)
1. Check if already in L1 cache, miss
2. Check if in L2 cache, miss
3. Check if in L3 cache, miss
4. Fetch from memory into (L1?) cache
不确定最后一步。数据是否会渗透到缓存中,这意味着如果发生缓存未命中,内存会先读入 L3/L2/L1,然后从那里读取?或者它可以“绕过”所有缓存,然后缓存并行进行以供以后使用。(读取 = 访问所有缓存 + 从 RAM 提取到缓存 + 从缓存读取?)
Then write:
1. All caches have to be checked (read) in this case too
2. If there's a hit, write there and since Nehalem has write through caches,
write to memory immediately and in parallel
3. If all caches miss, write to memory directly?
再次不确定最后一步。写入可以“绕过”所有缓存来完成吗?或者写入总是先读入缓存,修改缓存副本,然后让写入硬件实际写入 RAM 中的内存位置?(写入 = 读取所有缓存 + 从 RAM 提取到缓存 + 写入缓存,并行写入 RAM ==> 写入几乎是读取的超集?)
答案1
内存必须以两种状态存储数据,这两种状态之间存在较大的能量屏障,否则即使是最小的影响也会改变数据。但在写入内存时,我们必须主动克服这种能量屏障。
克服 RAM 中的能量障碍需要等待能量移动。只需查看位设置为何值即可,所需时间更少。
有关详细信息,请参阅MSalters 对类似问题的出色回答。
我不太清楚缓存如何与 RAM 交互的细节,因此无法权威地回答该部分问题,所以我将把它留给其他人。
答案2
写案例:如果您有内容要写入内存,并且您有一个良好的内存控制器,忽略所有缓存,您所要做的就是将要写入的数据发送到内存控制器。由于内存排序规则,一旦事务离开核心,您就可以继续执行下一条指令,因为您可以假设硬件正在处理对内存的写入。这意味着写入几乎不需要任何时间。
阅读案例:另一方面,读取是完全不同的操作,缓存可以大大帮助读取。如果您需要读取数据,则在实际获得数据之前,您无法继续执行程序的下一步。这意味着您需要先检查缓存,然后检查内存以查看数据在哪里。根据数据所在的位置,您的延迟会相应受到影响。在非线程、非流水线核心、非预取系统中,您只是在消耗核心周期等待数据返回,以便继续执行下一步。缓存和内存比核心速度/寄存器空间慢几个数量级。这就是读取比写入慢得多的原因。
回到写入事务,您可能遇到的唯一速度问题是,如果您在对同一地址的写入事务之后执行读取。在这种情况下,您的架构需要确保您的读取不会跳过您的写入。如果跳过,您将得到错误的数据。如果您有一个非常智能的架构,当该写入向内存传播时,如果出现对同一地址的读取,硬件可以在数据到达内存之前返回数据。即使在这种先读后写的情况下,从核心的角度来看,需要一段时间的不是写入,而是读取。
从 RAM 角度来看:即使我们不讨论核心,而只讨论 RAM/内存控制器,对 MC 进行写入也会导致 MC 将其存储在缓冲区中并发送响应,表明事务已完成(即使尚未完成)。使用缓冲区,我们不必担心实际的 DIMM/RAM 写入速度,因为 MC 会处理这个问题。这种情况的唯一例外是当您执行大量写入并超出 MC 缓冲区的功能时。在这种情况下,您必须开始担心 RAM 写入速度。这就是链接文章所指的。然后,您必须开始担心 David 的回答中提到的读取与写入速度的物理限制。通常,这对核心来说是一件愚蠢的事情;这就是发明 DMA 的原因。但这是另一个话题。