part 1
这部分主要是LRU的问题,我是通过维护双向链表来模拟的:
1.每当一个缓存被命中或者新加入时,将该缓存移到链表头。
2.当新加入缓存且链表个数到达上限时,需删除链表尾的节点,新结点放到链表头。
part 2
只解决了64*64的矩阵转置,耗费了我两天时间,其余问题感觉意义不大,实用性也不强,懒得做了。
因为s=5,E=1,b=5,所以对于64*64的矩阵,
第一行和第五行的元素是命中的同一块缓存,依此类推。所以块大小取8*8,实际在完成一个8*8的块的转置时,还需再分为4*4的小块。
问题主要分为两部分:
1.位于对角线的块。
2.不位于对角线的块。
先解决对角线的块:
先复制到B矩阵的非对角线的块区域,再由非对角线块转置到目的块。
转置的过程类似于非对角线块的解决办法。
从A块复制到B的非对角线块---16miss
从B非对角线块转置到对角线块---16miss
总计32miss
对角线块一共有8个,那就是8*32=256,题目的上限是1100
而非对角线块总共有56个,因此每个非对角线块的miss上限最多为18个。
非对角线的块:
对于非对角线的块,A矩阵与B矩阵中的相应块是不会占用同一块缓存的。
步骤如下(分为4个4*4小块):
1.转置左上角的小块到目的块,完成时A、B中右上角的小块已经位于缓存中。
2.将A中右上角的小块转置并存储到B右上角的小块(做容器用)中。完成时,A的左上角和右上角的小块没用了。
3.将B右上角中第一行的四个值赋值给四个临时变量,再从A中取相应的值转置到这一行中。完成时,B第一行已被填满,可以退出缓存了。
4.将临时变量的值赋值到相应位置(即第五行前四个坑,B的左下小块第一行).
重复3、4,直到完成B左下小块的转置。
5.将A右下小块转置到B右下小块中。
总计是16个miss,充分利用了缓存(实在繁琐,不知道各位大神有没有简便的方法。)
在虚拟机上跑的结果是总计1155个miss:
代码如下:
void transpose_submit(int M, int N, int A[N][M], int B[M][N])
{
if(N<16 || M<16){
trans(M, N, A, B);
}
int m, n;
int i, j;
int tem, tem2;
int col,row;
int t1,t2,t3,t4;
//diagonal block
tem = M < N ? M : N;
for(n=0;n+8<=tem;n+=8){
if(n>tem-16){// last block
row = n;
col = n - 8;
}else{
row = n;
col = n + 8;
}
//copy A diagonal block to B's block
for(i=0;i<8;i++){
for(j=0;j<8;j++){
B[row+i][col+j] = A[n+i][n+j];
}
}
//Transpose copied block to B's diagonal block
for(i=0;i<4;i++){
for(j=0;j<4;j++){
B[n+i][n+j] = B[row+j][col+i];
B[n+i][n+j+4] = B[row+i][col+j+4];
}
}
for(i=0;i<4;i++){
for(j=0;j<4;j++){
tem2 = B[row+4+i][col+j];
B[row+4+i][col+j] = B[n+j][n+i+4];
B[n+j][n+i+4] = tem2;
}
}
for(i=0;i<4;i++){
for(j=0;j<4;j++){
B[n+4+i][n+j] = B[row+4+i][col+j];
B[n+4+i][n+4+j] = B[row+4+j][col+4+i];
}
}
}
// end
for(n=0;n+8<=N;n+=8){
for(m=0;m+8<=M;m+=8){
if(m!=n){
for(i=0;i<4;i++){
for(j=0;j<4;j++){
row = n + i;
col = m + j;
B[col][row] = A[row][col];
B[col][row+4] = A[row][col+4];
}
}
for(i=0;i<4;i++){
row = m + i;
t1 = B[row][n+4];
t2 = B[row][n+5];
t3 = B[row][n+6];
t4 = B[row][n+7];
row = n + 4;
col = m + i;
for(j=0;j<4;j++){
B[col][row+j] = A[row+j][col];
}
row = m + 4 + i;
B[row][n] = t1;
B[row][n+1] = t2;
B[row][n+2] = t3;
B[row][n+3] = t4;
}
for(i=0;i<4;i++){
for(j=0;j<4;j++){
row = n + 4 + i;
col = m + 4 + j;
B[col][row] = A[row][col];
}
}
}
}
for(;m<M;m++){//边界条件处理,待优化
for(j=0;j<8;j++){
B[m][n+j] = A[n+j][m];
}
}
}
for(;n<N;n++){//边界条件处理,待优化
for(j=0;j<M;j++){
B[j][n] = A[n][j];
}
}
}
这个过不了61*67的,应该是因为边界条件没好好处理(即对于矩阵分块后的边角料),懒得处理了,网上应该有正确解答的。