大量缓存未命中,稀疏矩阵乘法

时间:2015-06-16 08:56:22

标签: 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 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);
            }
        }
    }

我正在使用的数字是:

M = 2048; N=10240; K=4096; nSelection=100;

所以我的想法是,如果我按小部分解析矩阵(在16个浮点数= 1个高速缓存行的KK方向上),我将只能加载两个矩阵。也就是说,矩阵A是按顺序加载的,因此除了每行的第一次加载之外,所有其他加载都应该是命中。矩阵B以随机顺序加载,但因为我以64字节(16个浮点数)的块处理整个事件,所以它应该需要640KB。我有6 MB的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时,我突然得到缓存命中(随机访问):

==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%  )

问题是我的移动核心i7上有6MB缓存。并且512 * 16 *浮点大小为23 KB。那么为什么我会得到这么多的失误呢? (我昨晚写了大部分内容,今天我找到了答案。

1 个答案:

答案 0 :(得分:1)

它是缓存的关联性。我的l3是12路关联的,我还没有完成计算,但是将K改为4 * 1024 + 16让我一路打击!