“阻止”方法使代码缓存友好

时间:2016-05-05 22:29:41

标签: c caching optimization

嘿所以我正在查看矩阵移位代码,并且需要使其缓存友好(可能的缓存丢失最少)。代码如下所示:

int i, j, temp;
for(i=1;, i< M; i++){
    for(j=0; j< N; j++){
        temp = A[i][j];
        A[i][j] = A[i-1][j];
        A[i-1]][j] = temp;
    }
}

假设M和N是函数的参数,M表示行数,N表示列数。现在为了使这个缓存更友好,本书给出了两个优化问题。当矩阵是4×4,s = 1,E = 2,b = 3,并且当矩阵是128×128时,s = 5,E = 2,b = 3。 (s =设置索引位数#(S = s ^ 2是集合数,E =每组行数,b =块位数#(因此B = b ^ 2是块大小))

因此,使用阻塞方法,我应该按块大小访问矩阵,以避免错过,并且缓存必须从缓存中获取更高级别的信息。所以这就是我的假设:

每个

的块大小为9个字节

使用4x4矩阵,均匀适合块的元素数量为: blocksize *(列数/块大小) = 9 *(4/9)= 4 因此,如果每一行都适合一个块,为什么它不缓存友好?

使用128x128矩阵,具有与上述相同的逻辑,每个块将保持(9 *(128/9))= 128。

很明显,经过计算,这个等式是错误的。我正在查看此页面中的代码http://csapp.cs.cmu.edu/public/waside/waside-blocking.pdf

一旦我达到这一点,我知道我迷路了,这是你们进来的地方!它是否像说每个块保存9个字节一样简单,8个字节(两个整数)是否适合它?对不起,这个东西真让我困惑,我知道我到处都是。需要明确的是,这些是我的担忧:

你怎么知道一个块中有多少元素? 行数或数量是否会影响这个数字?如果是这样,怎么样? 对链接页面上发布的代码的任何深入解释。

真的只是想弄清楚这一点。

更新: 好的,所以这就是我所处的4x4矩阵。

我一次可以读取8个字节,即2个整数。原始函数将有缓存未命中,因为C加载到行主要顺序,所以每次它想要A [i-1] [j]它将会错过,并加载包含A [i-1] [j]的块将是A [i-1] [0]和A [i-1] [1]或A [i-1] [2]和A [i-1] [3]。

那么,最好的方法是创建另一个临时变量,然后执行A [i] [0] = temp,A [i] [1] = temp2,然后加载A [i-1] [0] A [i-1] [1]并将它们设置为temp和temp2,然后将循环设置为j <2?对于这个问题,它专门针对所描述的矩阵;我知道这不适用于所有尺寸。

1 个答案:

答案 0 :(得分:0)

这个问题的解决方案是按列主要顺序而不是行主要顺序来考虑矩阵。

希望这可以帮助将来的某个人。感谢@Michael Dorgan让我思考。

128x128矩阵的最终结果: 原文:16218未命中 优化:8196未命中