深入理解计算机系统家庭作业第六章

/*

***6.23

*/

等价于求xr(1 - x)的最大值,由代数知识得x=0.5的时候取得最大。


/*

***6.24

*/

0.5 * 60 / 12000 * 1000 + 60 / 12000 * 1000 /500 + 3 = 5.51ms


/*

***6.25

*/

定位时间 = 3 + 2.5 = 5.5ms

A.     3072 / 500 * 5 + 5.5 = 36.22ms

B.     5.5 * 3072 = 16896ms


6.26,6.27 根据公式C = B * E * S即可推得,此处略之


/*

***6.28

*/

A.     0x1238, 0x1239, 0x123a, 0x123b

B.     0x8a4, 0x8a5, 0x8a6, 0x8a7                       0x704, 0x705, 0x706, 0x707


/*

***6.29

*/

A.     0x1bdc, 0x1bdd, 0x1bde, 0x1bdf

B.     0xe34, 0xe35, 0xe36, 0xe37

C.     0x18f0, 0x18f1, 0x18f2, 0x18f3     0xb0, 0xb1, 0xb2, 0xb3

D.     不会命中


/*

***6.30

*/ 

B.     1.不命中,有效位为0

         2.命中。在1中已加载

         3.命中。值为D0


/*

***6.31

*/

A.     C= E*B*S = 128

B.     CO   最后两位

         CI   除去最后两位的后三位

         CT   前8位


/*

***6.32

*/

A.     0011100011000

B.     CO      0x0

         CI      0x6

         CT      0x38

         没有命中


/*

***6.33

*/

A.     1011011101100

B.     CO      0x0

         CI      0x3

         CT      0xB7

         没有命中

    

/*

***6.34

*/

0x1314, 0x1315, 0x1316, 0x1317

0x1794, 0x1795, 0x1796, 0x1797


/*

***6.35

*/

缓存一共有两个块,src[0],src[2],dst[0],dst[2]访问缓存第一个块,src[1],src[3],dst[1],dst[3]访问缓存第二个块。


dst数组

m  h  m  h

m  m  h  m

m  h  m  h

m  m  h  m


src数组

m  m  m  m 

m  m  m  m

m  m  m  m

m  m  m  m


/*

***6.36

*/

当总大小为128时,能容纳下src与dst数组中的所有元素

dst数组

m  h  h  h

m  h  h  h

m  h  h  h

m  h  h  h


src数组

m  h  h  h

m  h  h  h

m  h  h  h

m  h  h  h


/*

***6.37

*/

A.   x[0][i]和x[1][i]是同一个缓存条目。不命中率为100%,属于交叉不命中

B.   缓存大小可容纳数组所有内容。不命中率为1/8。

C.    x[0][i]和x[1][i]加载到不同行。不命中率为1/8.

D.   不能,存在冷不命中。

E.   能。加大块大小能减小冷不命中概率。


/*

***6.38

*/

N=64时:

sumA:   1/4

sumB:   1

sumC:   1/2


N= 60时:

sumA ,sumB,sumC的缓存不命中率均为   1/4


比较难判断的是N = 60时sumB的缓存不命中率(sumC与sumB是一样的),我写了一个函数返回不命中次数,将形参n赋值60即可。

//高速缓存命中率函数,返回不命中次数
int noHitPercentage(int n)
{
	//不命中的次数
	int result = 0;
	//总共要循环的次数
	int count;
	//存储块的标记位
	int a[256];
	for(int i =0;i < 256;i++)
	{
		a[i] = -1;
	}
	for(int j = 0;j < n;j++)
		for(int i = 0;i < n;i++)
		{
			//求出这个数的相对索引
			count = i * n + j;
			//求这个索引对应的块号
			int blockNo = (count/4) % 256;
			//求出标记t
			int t = (count/4)/256;
			//如果标记位不相等则不明中
			if(t != a[blockNo])
			{
				a[blockNo] = t;
				result++;
			}


		}

		return result;	
}

/*

***6.39

*/

A.   16 * 16 * 4 = 1024

B.   64

C.   1/16


/*

***6.40

*/

A.   1024

B.   256

C.   1/4


/*

***6.41

*/

A.   1024

B.   64 + 64 = 128

C.   1/8


/*

***6.42

*/

25%


/*

***6.43

*/

25%


/*

***6.44

*/

100%


/*

***6.46

*/

void betterTranspose(int *dst,int *src,int dim)
{
	int i, j;
	int iCount,jCount;


	//以4 * 4 的方阵为单位依次计算,增加了写的缓存命中率,多个元素一起读写还减少了循环开销
	for(i = 0;i < dim - 3;i += 4)
	{
		iCount = i * dim;
		for(j = 0;j < dim - 3;j += 4)
		{
			jCount = j * dim;


			dst[jCount + i] = src[iCount + j];      //dst[j][i] = src[i][j]
			dst[jCount + i + 1] = src[iCount + dim + j];  //dst[j][i + 1] = src[i + 1][j]
			dst[jCount + i + 2] = src[iCount + dim * 2 + j];   //dst[j][i + 2] = src[i + 2][j]
			dst[jCount + i + 3] = src[iCount + dim * 3 + j];   //dst[j][i + 3] = src[i + 3][j]


			dst[jCount + dim + i] = src[iCount + j + 1];      //dst[j + 1][i] = src[i][j + 1]
			dst[jCount + dim + i + 1] = src[iCount + dim + j + 1];  //dst[j + 1][i + 1] = src[i + 1][j + 1]
			dst[jCount + dim + i + 2] = src[iCount + dim * 2 + j + 1];   //dst[j + 1][i + 2] = src[i + 2][j + 1]
			dst[jCount + dim + i + 3] = src[iCount + dim * 3 + j + 1];   //dst[j + 1][i + 3] = src[i + 3][j + 1]


			dst[jCount + dim * 2 + i] = src[iCount + j + 2];      //dst[j + 2][i] = src[i][j + 2]
			dst[jCount + dim * 2 + i + 1] = src[iCount + dim + j + 2];  //dst[j + 2][i + 1] = src[i + 1][j + 2]
			dst[jCount + dim * 2 + i + 2] = src[iCount + dim * 2 + j + 2];   //dst[j + 2][i + 2] = src[i + 2][j + 2]
			dst[jCount + dim * 2+ i + 3] = src[iCount + dim * 3 + j + 2];   //dst[j + 2][i + 3] = src[i + 3][j + 2]


			dst[jCount + dim * 3 + i] = src[iCount + j + 3];      //dst[j + 3][i] = src[i][j + 3]
			dst[jCount + dim * 3 + i + 1] = src[iCount + dim + j + 3];  //dst[j + 3][i + 1] = src[i + 1][j + 3]
			dst[jCount + dim * 3 + i + 2] = src[iCount + dim * 2 + j + 3];   //dst[j + 3][i + 2] = src[i + 2][j + 3]
			dst[jCount + dim * 3 + i + 3] = src[iCount + dim * 3 + j + 3];   //dst[j + 3][i + 3] = src[i + 3][j + 3]
			
		}
	}


	//记录当前行和列的索引,以便执行完剩余的项
	int curIndex = i;


	//处理剩余项,简单的交换处理
	for(i = 0;i < curIndex;i++)
		for(j = curIndex;j < dim;j++)
		{
			dst[j * dim + i] = src[i * dim + j];
		}


	for(i = curIndex;i < dim;i++)
		for(j = 0;j < dim;j++)
		{
			dst[j * dim + i] = src[i * dim + j];
		}
}



/*

***6.47

*/

void better_col_convert(int *G,int dim)
{
	int i, j;
	int iCount,jCount;

	//以4 * 4 的方阵为单位依次计算,增加了写的缓存命中率,多个元素一起读写还减少了循环开销
	for(i = 0;i < dim - 3;i += 4)
	{
		iCount = i * dim;
		for(j = 0;j < dim - 3;j += 4)
		{
			jCount = j * dim;

			G[jCount + i] = G[iCount + j] || G[jCount + i];      //G[j][i] = G[i][j] || G[j][i]
			G[jCount + i + 1] = G[iCount + dim + j] || G[jCount + i + 1];  //G[j][i + 1] = G[i + 1][j] || G[j][i + 1]
			G[jCount + i + 2] = G[iCount + dim * 2 + j] || G[jCount + i + 2];   //G[j][i + 2] = G[i + 2][j] || G[j][i + 2]
			G[jCount + i + 3] = G[iCount + dim * 3 + j] || G[jCount + i + 3];   //G[j][i + 3] = G[i + 3][j] || G[j][i + 3]

			G[jCount + dim + i] = G[iCount + j + 1] || G[jCount + dim + i];      //G[j + 1][i] = G[i][j + 1] || G[j + 1][i]
			G[jCount + dim + i + 1] = G[iCount + dim + j + 1] || G[jCount + dim + i + 1];  //G[j + 1][i + 1] = G[i + 1][j + 1] || G[j +1][i + 1]
			G[jCount + dim + i + 2] = G[iCount + dim * 2 + j + 1] || G[jCount + dim + i + 2];   //G[j + 1][i + 2] = G[i + 2][j + 1] || G[j +1][i + 2]
			G[jCount + dim + i + 3] = G[iCount + dim * 3 + j + 1] || G[jCount + dim + i + 3];   //G[j + 1][i + 3] = G[i + 3][j + 1] || G[j + 1][i + 3]

			G[jCount + dim * 2 + i] = G[iCount + j + 2] || G[jCount + dim * 2 + i];      //G[j + 2][i] = G[i][j + 2] || G[j +2][i]
			G[jCount + dim * 2 + i + 1] = G[iCount + dim + j + 2] || G[jCount + dim * 2 + i +1];  //G[j + 2][i + 1] = G[i + 1][j + 2] || G[j +2][i + 1]
			G[jCount + dim * 2 + i + 2] = G[iCount + dim * 2 + j + 2] || G[jCount + dim * 2 + i + 2];   //G[j + 2][i + 2] = G[i + 2][j + 2] || G[j +2][i + 2]
			G[jCount + dim * 2+ i + 3] = G[iCount + dim * 3 + j + 2] || G[jCount + dim * 2 + i + 3];   //G[j + 2][i + 3] = G[i + 3][j + 2] || G[j + 2][i + 3]

			G[jCount + dim * 3 + i] = G[iCount + j + 3] || G[jCount + dim * 3 + i];      //G[j + 3][i] = G[i][j + 3] || G[j +3][i]
			G[jCount + dim * 3 + i + 1] = G[iCount + dim + j + 3] || G[jCount + dim * 3 + i + 1];  //G[j + 3][i + 1] = G[i + 1][j + 3] || G[j +3][i + 1]
			G[jCount + dim * 3 + i + 2] = G[iCount + dim * 2 + j + 3] || G[jCount + dim * 3 + i + 2];   //G[j + 3][i + 2] = G[i + 2][j + 3] || G[j + 3][i + 2]
			G[jCount + dim * 3 + i + 3] = G[iCount + dim * 3 + j + 3] || G[jCount + dim * 3 + i + 3];   //G[j + 3][i + 3] = G[i + 3][j + 3] || G[j + 3][i + 3]

		}
	}

	//记录当前行和列的索引,以便执行完剩余的项
	int curIndex = i;

	//处理剩余项,简单的交换处理
	for(i = 0;i < curIndex;i++)
		for(j = curIndex;j < dim;j++)
		{
			G[j * dim + i] = G[i * dim + j] || G[j * dim + i];
		}

		for(i = curIndex;i < dim;i++)
			for(j = 0;j < dim;j++)
			{
				G[j * dim + i] = G[i * dim + j] || G[j * dim + i];
			}
}


你可能感兴趣的:(深入理解计算机系统家庭作业)