第二章:
两分题:
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);