不同的处理器采用不同的方法。您的问题没有单一、独特的直接答案。
更新(见下方评论)
首先,考虑包含和独占缓存的区别。
在包含缓存的情况下,如果a 在 L1 缓存中,那么它也在 L2 和 L3 中,因为这是一个内存层次结构。 a不可能在N级缓存中而不在N+1级缓存中。但是,请注意,相反的情况可能会发生,而且经常会发生(例如,在 L3 但不在 L2)。
在真正的独占缓存中,L1 中的内容永远不会出现在 L2 或 L3 中。
您的示例会发生什么取决于使用的写入策略。这里有两个不同的选项,称为 write-through 或 write-back。除此之外,还必须考虑写分配策略,该策略决定了对未缓存对象的写指令是否必须首先将该对象提取到缓存中。写分配策略可以是write-allocate,意味着丢失的对象在被写入之前被带入缓存,也可以是no-write-allocate,这意味着对象不会被带入缓存,而是直接写入后备存储中。
关于写策略:
直写意味着只要对象被写入,它在内存中的值(以及跨每个缓存级别)都会立即更新。
回写表示对象的值只在缓存中更新;仅当需要将其从缓存中取出时才会在内存中更新。
请注意,write-through 可以与任何写入分配策略一起使用;另一方面,用 no-write-allocate 策略谈论 write-back 没有多大意义。
至于你的具体问题:
处理器是否先更新L1中a的副本,然后更新L1中的副本
L2,最后是DRAM内存中的副本?
如果它同时使用写入分配策略和直写,是的,这正是发生的情况。如果是使用write-allocate with write-back,那么a += 1.0会第一时间将对象带到L3、L2和L1缓存中,后续指令只会更新L1中的副本,假设不需要替换。如果它使用no-write-allocate,则写入内存时不会将块放入缓存。
但是,请注意a += 1.0 下降到“读取 a;添加 1;更新 a”,“读取 A”步骤很可能会将 a 带入缓存,这意味着这不是真正的写入操作,而是一个先读后写的操作。因此,即使使用 no-write-allocate ,我会说 a 总是被带到缓存中,所以真正发生的事情只取决于写策略(直写或回写)。只有当我们将直接的 write 指令放入未缓存的对象中时,写入分配才相关,例如 a = 1.0;。
或者处理器是否首先更新 DRAM 内存中的 a 值,然后
然后将包含 a 的适当大小的缓存行引入 L2
然后是L1?
这永远不会发生。如果使用 no-write-allocate ,则直接操作内存。否则,对象总是被带到 L3、L2 和 L1 缓存(这是由缓存控制器“自动”处理的,CPU 本身不必担心将它分别带到每个缓存),然后会发生什么取决于写入策略。
所有这些都假设在程序执行期间不需要替换缓存中的对象,这是不现实的。一种流行的替换策略是 LRU(最近最少使用)。缓存冲突是需要替换的主要来源,它们何时发生取决于缓存的组织:它的大小、它的块大小,以及最重要的是它的关联性。维基百科对此有深入的了解;如果你想对这个问题有更严肃的看法,如果你想了解更多关于缓存的知识,我推荐计算机组织和设计的第 5 章——Patterson & Henessy 的硬件/软件接口。