直接映射写通写分配缓存中,循环并发访问两数组的缓存处理问题
直接映射缓存下数组访问的缓存行为分析(写通+写分配)
首先明确核心规则的作用:
- 直接映射缓存:每个内存块会唯一映射到一个固定的缓存块(直接映射结构中每个缓存组仅含一个块,组号等同于缓存块索引),映射规则为:
缓存块索引 = (内存块地址) % 缓存总块数。不存在“自动跳转到下一个组”或“等组满再换组”的逻辑——只要内存块的映射索引对应某个缓存块,不管该块是否有数据,新的内存块都会直接替换原有的(如果存在)。 - 写分配:写操作触发缓存缺失时,会先将目标内存块加载到缓存,再执行写操作,而非直接写入内存。
- 写通:每次写缓存的同时,立即同步写入内存,保证缓存与内存数据一致。
结合你给出的代码:
int N = 10000; int X[N]; int Y[N]; for (int i = 0; i < N; ++i) { X[i] = Y[i]; }
分阶段分析缓存行为:
第一次循环迭代(i=0)
- 访问Y[0](读操作):
缓存初始为空,触发冷缺失。根据直接映射规则计算Y[0]所在内存块对应的缓存索引,将该内存块加载到对应缓存位置,之后Y[0]的读操作命中缓存。 - 访问X[0](写操作):
X[0]所在内存块不在缓存中,触发写缺失。由于是写分配,先将X[0]所在内存块加载到它唯一对应的缓存索引位置(该位置与Y[0]的缓存位置是否重合,取决于X、Y的内存地址差与缓存总块数的关系),随后执行写操作——同时因为是写通,该操作会同步写入内存。
后续循环迭代
- Y数组的访问:
步长为1的连续访问模式下,每个内存块的第一个元素会触发冷缺失,加载到对应缓存位置后,同一块内的后续元素(比如Y[1]到Y[15],假设缓存块大小为64字节,对应16个int)都会命中缓存,直到访问下一个新块时再次触发缺失。 - X数组的访问:
同样是连续写操作,每个块的第一个元素触发写缺失(写分配加载对应块到缓存),之后同一块内的后续写操作直接命中缓存,每次写操作都会同步写入内存(写通特性)。
关键冲突场景说明
如果X和Y的对应内存块(比如X的第k个块和Y的第k个块)通过直接映射规则计算出的缓存索引相同,就会发生冲突缺失:
比如加载Y的第k个块到缓存索引M后,后续加载X的第k个块会直接替换掉Y的第k个块;当循环到需要访问Y的第k个块内的下一个元素时,该块已被替换,会再次触发缺失,反之亦然。这种情况会降低缓存命中率,具体是否发生取决于数组的内存布局和缓存的总块数。
内容的提问来源于stack exchange,提问作者WanderingGiraffe
相关产品推荐
相关产品推荐

