20135329李海空 家庭作业

第二章:

两分题:

20135327 郭皓 :3

20135329 李海空:1

2.67 给你一个任务,编写一个过程int_size_is_32(),当在一个int是32位的机器上运行时,该程序产生1,而其他情况则产生0.不允许使用sizeof运算符。下面是开始时的尝试:

/*The following code does not run properly on some machies*/
int bad_int_size_is_32(){
  int set_msb = 1<<31;
  int beyond_msb = 1<<32;
  return set_msb &&! beyond_msb;
}

当在SUN SPARC这样的32位机器上编译并运行时,这个过程返回的却是0.下main的编译器信息给了我们一个问题的指示。
warning:left shift count >= width of type

 

A:左移位数大于等于int长度,32位机器中最多左移31位,16位机器中最多左移15位。

 

B:用两次左移来实现<<32:

int set_msb=1<<31;

int beyond_msb=set_msb<<1;

 

C:用三次左移来实现<<31与<<32:

int temp=1<<15;

temp<<=15;

int set_msb=temp<<1;

int beyond_msb=temp<<2;

 

三分题:

20135327 郭皓 :4

20135329 李海空:2

2.69 写出具有如下原型的函数的代码

/*

 *Do rotating right shitf.  Assume 0 <= n < w

 *Examples when x = 0x12345678 and w = 32:

 *   n = 4 -> 0x81234567 ,n = 20 -> 0x45678123

*/

unsigned rotate_right(unsigned x, int n);

 

答:本题主要是编写一个循环右移的函数,具体代码如下所示:

#include <stdio.h>
unsigned rotate_right(unsigned x, int n)
{
unsigned a;
a = x<<(32-n);
printf("%x\n",x>>n|a);
}

int main()
{
unsigned x;
int n;
printf("请输入32位十六进制数");
scanf("%x",&x);
printf("请输入右移位数(小于32大于等于0)");
scanf("%d",&n);
if(n>32||n<=0)
{
printf("右移位数小于32大于等于0!!!");
return 0;
}
rotate_right(x,n);

return 0;
}

 

这里我默认w=32 因为要是32位以内的十六进制数必须更改w的取值否则系统默认为32位十六进制,如需修改只需将32改为w即可。

下图为测试结果:

试试其他数:

第六章:

6.30

两分题:

20135327 郭皓 :2.5

20135329 李海空:1.5

 

 

A:

由题意知 b=2 s=2 故 两个低位是块偏移,然后是两位的组索引,剩下的位做标记:

B:

1.对于地址0x409,块偏移(CO):0x1  组引索(CI):0x2 高速缓存标记(CT):0x40 可见该标记的有效位为0,故不命中。
2.对于地址0x40A,块偏移(CO):0x2  组引索(CI):0x2 高速缓存标记(CT):0x40  可见该标记的有效位为0,故不命中。
3.对于地址0x833,块偏移(CO):0x3  组引索(CI):0x0 高速缓存标记(CT):0x83 可见该标记的有效位为1,高速缓存的标记位与地址中的标记位匹配,故命中 读出的值为0xD0。

 

6.37

两分题:

20135327 郭皓 :2.5

20135329 李海空:1.5

A

不命中率是100%,直接映射是每组只有一个高速缓存行,块大小为32字节,表示可以存储8个int数值。 数组是按照行优先存储的,计算数组一行的大小为256*4=1024,所以高速缓存只够存数组的一行。 所以x[0]和x[1]的每一个元素对应的高速缓存是同一个块。 因此,每次请求都在加载,驱逐,替换。不命中率为100%。

B

不命中率是1/8 ,只有加载新行时发生不命中,缓存足够大,可以存储整个数组 因此只有冷不命中,而块大小为32字节,表示可以存储8个int数值 所以每次都会加载x[0][i]~x[0][i+7]共8个数值到缓存组中,这里就只有x[0][i]是不命中的 所以不命中率为1/8。

C

不命中率为1/8 ,高速缓存只有1024字节,不够存储数组,数组的第一行和第二行分别加载到缓存同一组的不同行,不会冲突,所以最后还是相当于只有冷不命中,相当于每8个数据中只有一个是不命中的 所以不命中率为1/8 。

D

不能了,块大小不变,因为冷不命中的概率不可能被减小。

E

能,因为块的大小增加,冷不命中的频率就降低。

 

6.38     2分

 

函数       N=64     N=60

sumA     0.25   0.25

sumB  1     0.25

sumC  0.25  0.25

N = 64

sumA只有冷不命中,不命中率为0.25;sumB每次都会冲突,不命中率为1;sumC有冷不命,不命中率为0.25。

N = 60

sumA只有冷不命中,不命中率为0.25;sumB消除了冲突不命中,只有冷不命中,不命中率为0.25;sumC只有冷不命中,不命中率为0.25。

 

11.8  2分

在main函数之前加入代码:

int chdEnded ;

#include <signal.h>
void child_signal(int sig) {
    pid_t pid;
    while((pid = waitpid(-1, NULL, WNOHANG)) > 0)      
    chdEnded = 1; 

}  
在main函数中添加语句 signal(SIGCHILD, child_handle); 每次accept之前,让chdEnded = 0; 并且在doit()中的serve_dynamic之后添加: while(!chdEnded) pause();//or do sth 删掉serve_dynamic里的wait(NULL);

posted @ 2015-11-22 18:08  20135329李海空  阅读(434)  评论(0编辑  收藏  举报