考慮到能看到這篇文章的基本都是“同道中人”了,我就開門見山地寫東西不過多介紹了。。這次lab主要考察的是cache的內容,Part A要求用LRU規則模擬Cache,Part B則是將代碼優化成Cache-Friendly-Code。。體感難度是下下位吧,不耗時間但是略吃智力,P-B優化想不出來可能就沒戲了系列。。廢話不多說。上效果圖:
Part A
Part B
M=32,N=32
如果把矩陣和set的對應關係畫出來的話,策略是一目瞭然的(據說書上也有),如圖,每個格子代表8個int,對應數字表示對應的set
顯然的,我們使用矩陣分塊策略,以8*8爲單位,完成一個一個小矩陣的轉化,可以發現,基本上,原始的小矩陣和目標的小矩陣都完全在cache裏了,當然減少了很多的衝突。然而單單這樣並沒有達到滿分的要求(
還有一步重要的優化核心在對角線,因爲可以發現,對角線上的元素賦值時會造成緩存切換,這將會造成一部分的miss,不過我們可以用題中所說的“額外變量”來解決這個問題!(代碼最後一起附)
M=61,N=67
M=64,N=64
void transpose_submit(int M, int N, int A[N][M], int B[M][N])
{
int i,j,p,q;
int t1,t2,t3,t4;//t5,t6,t7,t8;
if (M==32){
for (i=0;i<4;i++){
for (j=0;j<4;j++){
for (p=0;p<8;p++){
for (q=0;q<8;q++){
if (8*i+q==8*j+p){
t1 = A[8*i+q][8*j+p];//avoid same row conflict
t2 = 8*i+q;
}else{
B[8*i+q][8*j+p]=A[8*j+p][8*i+q];
}
}
if (i==j){
B[t2][t2] = t1;//set back
}
}
}
}
}else if (M==61){
for (j=0;j<5;j++){
for (i=0;i<5;i++){
for (p=0;p<16 && (16*i+p)<61;p++){
for (q=0;q<16 && (16*j+q)<67;q++){
if (16*i+p==16*j+q){
t1 = A[16*i+p][16*j+q];//avoid same row conflict
t2 = 16*i+p;
}else{
B[16*i+p][16*j+q]=A[16*j+q][16*i+p];
}
}
if (i==j){
B[t2][t2] = t1;//set back
}
}
}
}
}else if (M==64){
for (i=0;i<64;i+=8){
// dui jiao xian
for (p=0;p<4;p++){
for (q=0;q<8;q++){
B[p][q+8] = A[i+p][i+q];
}
for (q=0;q<8;q++){
B[p][q+16] = A[i+p+4][i+q];
}
}
for (p=0;p<4;p++){
for (q=0;q<4;q++){
B[i+p][i+q] = B[q][p+8];
B[i+p][i+q+4] = B[q][p+16];
}
for (q=0;q<4;q++){
B[i+p+4][i+q] = B[q][p+12];
B[i+p+4][i+q+4] = B[q][p+20];
}
}
}
for (i=0;i<64;i+=8){
for (j=0;j<64;j+=8){
//[i][j] a 8*8 block
if (i!=j){
//not special 8 blocks
for (q=i;q<i+4;q++){
for (p=j;p<j+4;p++){
B[p][q] = A[q][p];//convert 4*4
B[p][q+4] = A[q][p+4];//convert 4*4 in a temp place on right
}
}
for (p=j;p<j+4;p++){
t1 = B[p][i+4];
t2 = B[p][i+5];
t3 = B[p][i+6];
t4 = B[p][i+7];// save temp before cache tag change
B[p][i+4] = A[i+4][p];
B[p][i+5] = A[i+5][p];
B[p][i+6] = A[i+6][p];
B[p][i+7] = A[i+7][p];// correct the temp B line
B[p+4][i] = t1;
B[p+4][i+1] = t2;
B[p+4][i+2] = t3;
B[p+4][i+3] = t4;// replace temp line and change cache tag
for (q=i;q<i+4;q++){
B[p+4][q+4] = A[q+4][p+4];// normal convert
}
}
}
}
}
}
}