算法部分
这周的算法完成的是largest container,开始用的是暴力枚举比较出最大值,后来改成了两个首尾两个cursor依次收缩。大致上复杂度就变成了线性。不过我在收缩首尾时设了一个循环,这样只有新值比原值更大时才投入计算容积,不然就一直收缩。不过我看比我更快的算法时,它不做比较直接收缩。直观上看似乎计算量不小,但是性能上其实更好,毕竟内部套一个循环实际要多很多测试和跳转,对于程序是不必要的开销。
int maxArea(int* height, int heightSize){ int cur_l=0,cur_r=heightSize-1; int ht_l = height[cur_l], ht_r = height[cur_r]; int vol=0; int maxVol = 0; int move; int h; while(cur_l < cur_r) { move = ht_l < ht_r? LEFT: RIGHT; h = MIN(ht_l,ht_r); vol = (cur_r-cur_l)* h ; maxVol = vol > maxVol? vol:maxVol; if(move == LEFT) { do { cur_l++; if ((ht_l=height[cur_l])>h) { break; } }while(cur_l < cur_r); } else { do { cur_r--; if ((ht_r=height[cur_r])>h) { break; } }while(cur_l < cur_r); } } return maxVol;}复制代码
Review部分
这周倒是没有看新的部分,而是继续把CSAPP的第三章习题做完了。涉及反汇编时反推编译器是如何优化代码,以及我们怎样写程序能够使编译器编译时少用一个寄存器这个还是蛮有意思的。比如3.66和3.67反推结构体声明和原始C程序。下面附上3.67的答案(我自己在x86上测试正确)。
// CSAPP2ed 3.67void proc(union ele *up){ up->e2.next->e1.x = *(up->e2.next->e1.p) - up->e2.y;}复制代码
Tip部分
在完成CSAPP课后练习时因为需要生成超过BUFSIZE的字符串文本而且不能换行,又复习了一下shell的用法:
echo -n {0001..2048} >> test_file复制代码
使用-n
是为了不换行,不然结果就会是
000100020003...2048复制代码
使用 >>
是为了追加到原文本中,而不是全部重写。不过用来生成测试文本用>
重写一遍也没问题的。
Summary部分(计算机体系结构)
Feature size的定义为x轴或y轴上晶体管的最小尺寸。
晶体管在芯片上的尺寸线性下降,因此晶体管的密度平方阶上升。
晶体管性能的提升就稍微复杂了一点。feature size的下降意味着水平和垂直方向尺寸均在下降。垂直方向的下降意味着电压也需要下降至适配的情况。近似来看,性能的变化与feature size呈线性关系。
晶体管性能的线性提升和数目的平方阶提升既是机遇又是挑战。这一变化促进了多核处理器的转变。以及SIMD(单一指令多数据)的推广。
不过尽管晶体管密度变大了,单位长度的电阻和电容也变差了。
23页提到了微处理器的电量消耗与时钟频率,电压,电容等的关系。时钟频率越慢的处理器,单位时间耗电量更小(但不代表完成固定任务消耗的能量少)。因此25页谈到了现代处理器有几个省电的方式,其中之一就是关闭时钟(如无需浮点计算时关闭浮点单元的时钟);动态调节时钟(比如移动设备的睡眠模式,由于此时无任务需要处理,使用低频时钟,耗电量变低);主存和磁盘也据此情况设计得更为省电;为了省电,可以关闭某些核,同时使另一些核具有超过硬件规定的时钟频率做短时间的运算处理。
考虑到晶体管数目的变多会自然带来能耗的增加,而且也会增加leakage(漏电)。考察性能的度量方式不再是每平方毫米上的性能表现,而是基于每瓦或每焦耳完成的任务量(会在第4和5章继续讨论)。
======
CSAPP要继续看第四章了,也是会要说到指令集结构等关乎硬件方面的东西,感觉稍稍有些硬。计算机体系结构一书也是蛮硬的。希望能继续啃下去。