矩阵拷贝缓存块冲突疑问及两种场景下缓存缺失率咨询
矩阵拷贝的缓存缺失问题分析
代码实现
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]; } } }
核心问题
- 当
ROWS和COLS均为128时,在大小为64K、块大小为16字节的直接映射缓存中,缓存缺失率是多少? - 当
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
相关产品推荐
相关产品推荐

