Skip to content

Commit 170baf4

Browse files
committed
添加4月份以前的笔记
1 parent adbb111 commit 170baf4

File tree

9 files changed

+194
-0
lines changed

9 files changed

+194
-0
lines changed

2013/10.html

+5
Large diffs are not rendered by default.

2013/11.html

+5
Large diffs are not rendered by default.

2013/12.html

+60
Large diffs are not rendered by default.

2013/7.html

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<head>
2+
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
3+
</head>
4+
5+
<div>■ 13. 代码之美:快排的简洁写法和比较次数<br>■ 13. 代码之美:图像过滤器的JIT<br>■ 13. 代码之美:python的字典优化<br>■ 14. 代码之美:运算符优先级的表达式分析<br>■ 14. 代码之美:递归的正则匹配<br>■ 15. 程序员修炼之道:可撤销性<br>■ 15. 程序设计实践:9-当编写了大量重复代码,或者解决问题的方法特别复杂,考虑换语言;如果没有合适的语言,自己创造一种记号(notation),不必像java那样强大,比如printf的格式化字符串<br>■ 15.程序设计实践:9.1-数据格式:强类型语言里,类型本身已经提供的格式的依据,但如果再要提供更多的格式化信息如对齐,就没有优势了;这时可以借鉴弱类型如c语言中的printf,用一种简单的记号来提供类型及其他信息<br>■ 15. 程序设计实践:9.2-正则表达式:简单优雅的正则实现;以及当多个*/*■同时出现时,预期的捕获情况?(最左优先)<br>■ 15. 程序设计实践:9.4-解释器、编译器和虚拟机:ast-&gt;tree-walking-&gt;tree op-&gt;linear op(suffix tree traverse, not recursive now, byte code)-&gt;jit<br>■ 15. 程序设计实践:9.5-写程序的程序:html是由程序生成的;带语义的注释,如python、java、doxygen,另外,也可以由枚举+注释生成枚举对应的字符串表示,结合makefile,每次枚举列表一变动,生成新的映射代码<br>■ 15. 程序设计实践:9.6-用宏生成代码:我经常写的"start=clock();...;clock()-start"可以用单参数的宏接受语句序列在c中实现;我的软件光栅器的模板光栅化那段代码由宏来写<br>■ 15. 程序设计实践: 9.7-JIT:算法和数据、模式一起工作,其中数据和模式是运行时的,如果算法是编译期的,则算法中嵌入的模式只能是变量,但如果算法是运行时JIT生成的,则模式被实例化为常量,于是算法可以被进一步进行常量折叠和去死代码,最终算法能得到优化。模式实例化的好例子:图像过滤器中卷积核,正则表达式中的模式串(甚至正则会退化成strstr),yacc的生成代码。<br>■ 16. valgrind: linux下的内存泄露检测工具<br>■ 16. 350行代码实现多种eval: tree-walking, stack-based vm, jit<br>■ 18. 使用AsmJit实现jit eval<br>■ 19. image filtering的gcc版jit<br>■ 21. 800行代码的tiny c<br>■ 22. 程序员修炼之道:曳光弹<br>■ 23. 英语:[AOT-ahead of time:预编译][out-of-order:乱序,如乱序处理器]<br>■ 23. CSAPP:序言,每一章的教学目的,以及一些有名的课后实验<br>■ 24. 在lua中只用lambda实现stack/list/bst三种ADT<br>■ 25. CSAPP: 第1章,计算机系统漫游<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. 信息是位+解释它的上下文<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 程序的翻译:源码-(预处理)-&gt;修改后的源码-(编译)-&gt;汇编语言-(汇编)-&gt;可重定位的目标文件-(链接)-&gt;可执行文件<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 3. 了解编译系统的意义:有能力进行性能优化;处理链接错误;应对缓冲区攻击等<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 4. 处理器的工作方式:开机过后,反复读取下一条指令,解释并执行<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 关于高速缓存:L1几乎和寄存器堆(register file)一样快!L2不一定挡在L1和主存之间?<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 硬件的三大部分:CPU、主存、IO设备。网络-&gt;磁盘-&gt;主存-&gt;L2-&gt;L1-&gt;CPU,更快、更小、更贵。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. CPU一般提供以下几种指令:(1)内存和寄存器间的读写,如mov/load/store(2)寄存器之间的修改,如add,mul(3)寄存器和IO端口直接的读写(4)PC的修改,如jmp<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 操作系统将硬件的三大部分抽象成如下部分:(1)IO设备=文件(2)磁盘(IO设备)+主存=虚拟存储器(3)IO设备+主存+CPU=进程<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 8. 在非GUI系统中,可以将文件stdin看做IO设备键盘,将stdout看做显示器,及将socket看做网络适配器。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 8. IO和主存之间的数据传输,以CPU作为中转站;DMA是个例外,可以直接在主存和磁盘之间传输<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ EXT-1. 考虑在shell中输入echo hello这个命令:IO设备之键盘-&gt;CPU-&gt;shell进程的内存-&gt;内存和CPU之间交互进行命令解析-&gt;创建新进程,从磁盘中DMA加载echo的执行文件到内存-&gt;echo内存中的hello字符串(数据段)-&gt;CPU-&gt;IO设备之显示器<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ EXT-2. 在ssh中输入echo hello:本机键盘(stdin)-&gt;CPU-&gt;内存-&gt;本机网卡(socket)-&gt;目标机网卡(socket,重定向的stdin■)-&gt;内存-&gt;解析并启动echo进程-&gt;echo进程内存中的hello字符串-&gt;目标机网卡(socket,重定向的stdout■)-&gt;本机网卡(socket)-&gt;CPU-&gt;本机显示器<br>■ 25. CSAPP: 第2章第0节<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2进制优于10进制的理由:负载信息的最小单元,显然没有1进制这种东西;实现简单,成本低;容易纠错,因此可以可靠的传输和存储。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 对世界进行二进制编码的可能性:任何整数可以用一个二进制向量表示;任何符号可以查表映射到整数再到二进制,例如位图的像素可以查表将亮度映射到整数再到二进制,字符/音符也可用同样的映射...<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 整数加、乘法有交换律结合律;因为精度原因,浮点的加乘没有交换律和结合律,比如大数加小数时。例:3.14+1e20-1e20!==0, 3.14+(1e20-1e20)==3.14<br>■ 26. CSAPP: 第2章第1节:信息的表示<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 0. 操作系统将主存、磁盘抽象成一个字节数组(虚拟存储器);编译器提供类型系统,为虚拟存储器中的字节、半字、字、双字提供不同的解释(解释为整形、浮点、指针)<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. 2进制、8进制、16进制、10进制,相互的转换<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 字长决定了整形、指针的大小。由于指针大小为字长,因此字长决定了寻址范围,即虚拟存储器的最大容量<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 3. c标准只规定了每种整形的最小尺寸。实践上,有以下经验(32/64位):char-&gt;1,short-&gt;2,int-&gt;4,long long-&gt;8,float-&gt;4,double-&gt;8;long-&gt;字长,void*-&gt;字长。故long和指针在32位和64位程序中,分别为4字节和8字节<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 4. little endian和big endian出自格列佛游记,而后者是在讽刺英法的时代冲突。以intel为主的pc的cpu一般是little endian,而ibm、sun的小型机、大型机一般是big endian。字节顺序主要影响序列化和反序列化,目标可以是文件、网络流,甚至机器码中的immdiate/displacement也受影响。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 字符串的内存表示。其中ASCII是编码无关的<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 机器码的表示。主要由cpu架构相关的机器指令,以及操作系统相关的pe格式和链接地址<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 布尔代数和环:布尔在19世纪50年代为了研究命题逻辑而提出布尔代数;20世纪30年代,信息论的奠基人,香农,将布尔代数用于设计和分析继电器网络。环是特殊的阿贝尔群。布尔代数和环有相似性,常见的环包括整数环、实数环、模数环等,也可以构建布尔环。对于布尔环的研究可以用于纠错(如播放脏的cd)。将布尔环扩展成向量,也能构成环。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 8. c中的位运算:&amp;,|,~,^<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 9. c中的逻辑运算:&amp;&amp;,||<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 10. c中的移位运算:&lt;&lt;,&gt;&gt;。左移是右边补0;右移,无符号数应该补0,而有符号数,c标准没有规定应该逻辑/算数移位,但一般编译器都实现为算数右移(补符号位)<br>■ 27. 代码大全:第23章-调试<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 类c语言中if (a = 3)这种,不必将文字常量写在左边,而是开启最高级别的警告...<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 等到出现bug需要调试的时候已经晚了,更好的办法是通过设计尽量在更早避免问题。但投入精力提高调试技巧也是有必要的,因为优秀的调试技术和拙劣的技术之间效率差距是10:1<br>■ 31. CSAPP: 第2章第2节:整数的表示<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. java只有有符号数<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. c语言标准规定了各种整形的最小尺寸,它保证:char至少1字节,short至少2字节,int至少2字节,long至少4字节。典型的,32位机上,char是1字节,short是2字节,int是4字节,long是4字节;64位机上,char是1字节,short是2字节,int是4字节,long是8字节,指针是字长<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 无符号数的位表示。B2U:各位乘以对应的2的幂再相加<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 有符号数的位表示:(1)补码,符号位以外的位乘以对应的2的幂相加,再加上符号位乘以-2^(w-1)。补码是一般的实现(2)反码(3)符号数值表示法,符号位乘以其他位的2的幂的和,TMIN和TMAX绝对值相等,但存在+0和-0<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 3. 无符号和有符号的转换:位表示不变。结果是,无符号2^(w-1)~2^(w)-1映射到-2^(w-1)~-1<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 4. c语言的有符号会自动向无符号转换,且位构成不变<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 扩展整数的位:无符号左边加0;有符号左边加符号位<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 截断整数的位:扔掉左边<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 不要使用无符号数。除非:(1)用作位域。如果用int声明位域的话,可能会浪费一位作为符号(2)用于实现大数等(3)想对一个int执行逻辑右移,(int)((unsigned)x&gt;&gt;k)<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 有符号数的~x + 1和-x是等价的<br>■ 31. CSAPP:第2章第3节:整数的运算<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. 无符号数加法的上溢<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 有符号数的加法:负+负可能下溢,正+正可能上溢。无符号加法和有符号加法的计算规则完全相同,cpu可以用相同的机器码,除了可以影响不同的标记位<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 3. 有符号数的加法逆元:各位取反再+1<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 4. 无符号数乘法:取结果的低w位<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 有符号数乘法:取结果的低w位。机器级计算方式同无符号一样,除了影响不同的标记位<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 乘以2的幂。无符号和有符号,都左移log2(n)位<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 除以2的幂。无符号和正的有符号,都右移log2(n)位;负的有符号数,应该(x+n-1)&gt;&gt;(log2(n)),因为-5/2需要得到-2而不是-3<br>■ 31: CSAPP:第2章第4节:浮点的表示<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 0. 早期各家厂商各自为战,使用不同的浮点实现,直到IEEE的754标准的推出<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 快速的将无限重复二进制小数转化为十进制:比如0.010101==1/4+1/4*(1/4)+1/4*(1/16)=(1/4)/(1-1/4)=1/3;又比如,0.100100100=4/8+4/8*(1/8)+4/8*(1/64)=(4/8)/(1-1/8)=4/7。可以看出,对0.yyyyy,其中y为k位,其十进制为y/(2^(k)-1)。换句话说,x/3,x/7,x/15,是可以很容易的写成重复二进制小数的<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 1. 10进制可以表示为1234.5678*10^(+-12345),类似的,二进制也可以表示为1001.1101*2^(+-110110)。一个有限精度的10进制小数对应的2进制小数可能是无限长的,所以在精度有限的情况下,必然有误差<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. IEEE的表示法为:(-1)^(sign)*M*2^(E)。其中sign被直接编码;M是1.fac,其中fac被编码为小数域;E被编码为指数域,一般是exp-bias的模式。单精度的符号、指数、小数域分别是1,8,23位,而双精度分别是1,11,52位。根据指数域的不同,浮点有三种解释,规格化、非规格化、特殊值。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 规格化:exp不是全0也不是全1的时候。E是exp-bias,其中bias是2^(k-1)-1(单精度是127,双精度是1023)。M是1.fac,其中1是隐含的。单精度下的范围是1.2*10^(-38)~3.4*10^(38)<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 非规格化:exp是全0的时候。E是1-bias。M是0.fac。因此非规格化值提供了0 的唯一表示。单精度下,范围是1.4*10^(-45)~1.2*10^(-38)。其中+0的位表示也为0<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 2. 特殊值:当expr全1的时候。如果fac为0,则sign为负表示负无穷,sign为正表示正无穷。如果fac非0,表示NAN(not a number)<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 4. 舍入(rounding)。常见的有4种roudning方式:向偶数舍入(默认)、向0舍入、向下舍入、向上舍入。其中偶数舍入,是指首先向最近的一边舍入,当位于精度位之间的时候,向偶数舍入。在二进制中,把0看做偶数。比如精确到两位,1.11011向下舍入,1.11111向上舍入,而1.11100则摄入为1.000,即中值是指1.11100000...。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 浮点运算。由于精度原因,浮点加、乘法都不满足结合律、交换律,所以编译器不敢擅自优化(或者说,一旦利用交换律等来提取公共子表达式,这样的优化会带来误差)。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 5. 正无穷+负无穷=NAN<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 由于c标准不要求编译器用IEEE的浮点实现float和double,所以,c中的浮点范围是用&lt;math.h&gt;来声明的。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. int-&gt;foat,舍入。int-&gt;double,没问题。float-&gt;int,溢出(TMIN和TMAX),向0截断。double-&gt;int,同上。foat-&gt;double,没问题。double-&gt;float,溢出(+-无穷),舍入。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. IA32上,浮点寄存器为80位IEEE格式的浮点,而float和double分别为32位和64位,因此,浮点数在寄存器和内存中迁移的时候,会被来回转换,在部分编译器上可能会有误差。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 6. 一般的编译器将long double看做double,但gcc认为long double有12~16字节。<br>&nbsp; &nbsp; &nbsp; &nbsp; ■ 7. 快速的将无限重复二进制小数转化为十进制:比如0.010101==1/4+1/4*(1/4)+1/4*(1/16)=(1/4)/(1-1/4)=1/3;又比如,0.100100100=4/8+4/8*(1/8)+4/8*(1/64)=(4/8)/(1-1/8)=4/7。可以看出,对0.yyyyy,其中y为k位,其十进制为y/(2^(k)-1)。换句话说,x/3,x/7,x/15,是可以很容易的写成重复二进制小数的<br><br></div>

2013/8.html

+5
Large diffs are not rendered by default.

2013/9.html

+5
Large diffs are not rendered by default.

2014/1.html

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<head>
2+
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
3+
</head>
4+
5+
<ul>
6+
<li>5. token-threading, direct-threading对比switch-threading的一个优势</li>
7+
<li style="list-style: none; display: inline">
8+
<ul>
9+
<li><span style="font-family: Simsun;">&nbsp;Either every virtual machine instruction routine has a copy of NEXT at the end, or they share one copy of NEXT and jump to it. With modern processors, the shared NEXT not only costs a jump, but also dramatically increases the misprediction rate of the indirect jump on CPUs with BTBs(branch target buffer) and similar indirect branch predictors [</span><a href="http://www.complang.tuwien.ac.at/forth/threaded-code.html#jilp" style="font-family: Simsun;" target="_blank">ertl&amp;gregg03jilp</a><span style="font-family: Simsun;">]. Therefore, I recommend not to share NEXT.</span></li>
10+
<li><span style="font-family: Simsun;">call-threading -&gt; switch-threading -&gt; replicate-switch-threading(case &amp; goto label) -&gt; token-threading(computed goto) -&gt; direct-threading(computed goto &amp; translation) -&gt; subroutine-threading --inline--&gt; JIT</span></li>
11+
</ul>
12+
</li>
13+
<li><font face="Simsun">5. v8 engine: inline-caching, hiden-class</font></li>
14+
<li style="list-style: none; display: inline">
15+
<ul>
16+
<li><font face="Simsun">hiden-class: map translation, object layout</font></li>
17+
<li><font face="Simsun">inline-caching: for property access, for method call. including monomorphic callsite, polymorphic/megamorphic callsite eg.</font></li>
18+
<li><font face="Simsun">type feedback: crankshaft use type feedback from full-compiler's IC to do type specific optimization. eliminate some range checking, type checking</font></li>
19+
<li><font face="Simsun">full-compiler (baseline compiler) use counter-based profiler to detect the hotspot</font></li>
20+
</ul>
21+
</li>
22+
<li><font face="Simsun">14. heredoc, hereis, here-string<span style="-evernote-last-insertion-point:true;"></span></font></li>
23+
</ul>

0 commit comments

Comments
 (0)