You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

矩阵拷贝缓存块冲突疑问及两种场景下缓存缺失率咨询

矩阵拷贝的缓存缺失问题分析

代码实现

void copy_matrix(int dest[ROWS][COLS], int src[ROWS][COLS]) {
    int i, j;
    for (i=0; i<ROWS; i++) { 
        for (j=0; j<COLS; j++) {
            dest[i][j] = src[i][j];
        }
    } 
}

核心问题

  1. 当ROWS和COLS均为128时,在大小为64K、块大小为16字节的直接映射缓存中,缓存缺失率是多少?
  2. 当ROWS=128、COLS=194时,缓存缺失率是多少?

疑问解答

疑问1:为什么dest[i][j]和src[i][j]会映射到同一个缓存行?

直接映射缓存的核心规则是:每个内存块只能对应缓存中唯一的一行,缓存行号通过内存块地址 % 缓存总行数计算。先明确几个关键参数:

  • 缓存总大小64K=65536字节,块大小16字节,因此缓存总行数=65536/16=4096行。
  • int占4字节,每个缓存块可容纳4个int元素。

假设src和dest是连续分配的内存(比如栈上连续声明或堆上连续申请),dest的起始地址比src大ROWS*COLS*4字节。当ROWS=COLS=128时,这个偏移量是128*128*4=65536字节,刚好等于缓存总大小。

计算缓存行号:

  • 设src[0][0]的内存地址为S,其所在内存块号为S/16,对应缓存行号为(S/16) % 4096。
  • dest[0][0]的地址为S+65536,内存块号为(S+65536)/16 = S/16 + 4096,对应缓存行号为(S/16 + 4096) % 4096,结果和src[0][0]的缓存行号完全一致。

所以读取src[0][0]触发缺失后,对应的缓存行被src的内存块占据;写入dest[0][0]时,因为它的内存块必须映射到同一个缓存行,直接映射缓存没有其他可选行,只能替换掉当前的缓存行——这就导致了冲突。

疑问2:ROWS=128、COLS=194时,为什么二者不会冲突,缺失率为25%?

先计算dest相对于src的内存偏移:128*194*4=99328字节,对应的内存块数为99328/16=6208。

缓存总行数是4096,6208 % 4096=2112,这意味着dest的内存块号比src的块号大6208,映射到的缓存行号等于src的缓存行号加2112(模4096),和src的缓存行完全不重叠。

此时src和dest的缓存行互不干扰:

  • 读取src的元素时,每4个元素只会触发1次缓存缺失(载入整个块),后续3次读取命中。
  • 写入dest的元素时,每4个元素只会触发1次缓存缺失(写分配策略,第一次写入时载入块),后续3次写入命中。

总访问次数为128*194*2=49664次(每个元素对应1次读+1次写),总缺失次数为128*194*(1+1)/4=12416次,缺失率=12416/49664=25%。

因为二者的缓存行无重叠,写入dest时不会替换src的缓存块,自然不会出现“写入替换后又重新载入”的情况。

内容的提问来源于stack exchange,提问作者Jared

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:20:32