Caching 大量缓存丢失,稀疏矩阵乘法
问候亲爱的地球人 这是概述: 我在做一个稀疏矩阵乘法,其中有两个密集矩阵,但我只对输出的一些元素感兴趣。我有两个矩阵和一个2d索引数组:Caching 大量缓存丢失,稀疏矩阵乘法,caching,matrix,cpu,multiplication,sparse-matrix,Caching,Matrix,Cpu,Multiplication,Sparse Matrix,问候亲爱的地球人 这是概述: 我在做一个稀疏矩阵乘法,其中有两个密集矩阵,但我只对输出的一些元素感兴趣。我有两个矩阵和一个2d索引数组: float * A:[M*K] float * B:[N*K] int [][] idx: [M][nSelection] (that is there are nselection rows in B, per row in matrix A that I want to multiply) 我想计算: out=A*B' // but of course
float * A:[M*K]
float * B:[N*K]
int [][] idx: [M][nSelection] (that is there are nselection rows in B, per row in matrix A that I want to multiply)
我想计算:
out=A*B' // but of course only for the indices i,j where idx[i][k]=j for some k.
这就是问题的症结所在:
我希望在乘法时将数据保存在cpu缓存中我一次乘法16个浮点:
for (int kk = 0; kk < K; kk+=KK){
int begin = 0;
int end = M;
for (int i = begin; i < end; i++){
for (int j = 0; j < numberToAccept; j++){
int theid = idx[i * numberToAccept + j];
tempOut[i*numberToAccept+j] += blas_function_for_dotProduct(KK, A+i*K + kk, 1, B+theid*K + kk, 1);
}
}
}
所以这个想法是,如果我一点一点地解析矩阵(沿着KK的方向,16个float=1个cacheline),我将能够只加载两个矩阵一次。也就是说,矩阵A是按顺序加载的,所以除了每行的第一次加载之外,所有其他加载都应该被命中。矩阵B是以随机顺序加载的,但因为我以64字节(16个浮点)的块处理整个过程,所以它应该需要640KB。我有6MB的L1,所以如果CPU使用LRU,它应该留在那里
我使用valgrind查看缓存未命中,我得到的结果如下:
==3264== D refs: 2,383,524,642 (2,272,927,073 rd + 110,597,569 wr)
==3264== D1 misses: 114,096,428 ( 113,982,278 rd + 114,150 wr)
==3264== LLd misses: 95,822,173 ( 95,736,938 rd + 85,235 wr)
==3264== D1 miss rate: 4.7% ( 5.0% + 0.1% )
==3264== LLd miss rate: 4.0% ( 4.2% + 0.0% )
如果访问是可预测的(累计),我也会得到相同的结果
我得到了与N=512相同的结果。但在N=256时,我突然得到缓存命中(随机访问):
问题是我的移动核心i7上有6MB的缓存。512*16*浮点大小为23KB。为什么我会错过这么多?(我昨晚写了这篇文章的大部分内容,今天我找到了答案。这是缓存的关联性。我的l3是12路关联的,我还没有做计算,但将K更改为4*1024+16会一直给我带来点击率
==3264== D refs: 2,383,524,642 (2,272,927,073 rd + 110,597,569 wr)
==3264== D1 misses: 114,096,428 ( 113,982,278 rd + 114,150 wr)
==3264== LLd misses: 95,822,173 ( 95,736,938 rd + 85,235 wr)
==3264== D1 miss rate: 4.7% ( 5.0% + 0.1% )
==3264== LLd miss rate: 4.0% ( 4.2% + 0.0% )
==16546== D refs: 2,383,525,914 (2,272,928,002 rd + 110,597,912 wr)
==16546== D1 misses: 114,096,557 ( 113,982,392 rd + 114,165 wr)
==16546== LLd misses: 1,372,862 ( 1,287,624 rd + 85,238 wr)
==16546== D1 miss rate: 4.7% ( 5.0% + 0.1% )
==16546== LLd miss rate: 0.0% ( 0.0% + 0.0% )