Caching 大量缓存丢失,稀疏矩阵乘法

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

问候亲爱的地球人

这是概述:

我在做一个稀疏矩阵乘法,其中有两个密集矩阵,但我只对输出的一些元素感兴趣。我有两个矩阵和一个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 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%  )