深入理解计算机系统9个重点笔记

引言

深入理解计算机系统,对我来说是部大块头。说实话,我没有从头到尾完完整整的全部看完,而是选择性的看了一些我自认为重要的或感兴趣的章节,也从中获益良多,看清楚了计算机系统的一些本质东西或原理性的内容,这对每个想要深入学习编程的程序员来说都是至关重要的。只有很好的理解了系统到底是如何运行我们代码的,我们才能针对系统的特点写出高质量、高效率的代码来。这本书我以后还需要多研究几遍,今天就先总结下书中我已学到的几点知识。

深入理解计算机系统(原书第2版) PDF清晰中文版 下载见

重点笔记

编写高效的程序需要下面几类活动:

让编译器展开循环 说到程序优化,,很多人都会提到循环展开技术。现在编译器可以很容易地执行循环展开,只要优化级别设置的足够高,许多编译器都能例行公事的做到这一点。用命令行选项“-funroll-loops”调用gcc,会执行循环展开。

性能提高技术:

高级设计,为手边的问题选择适当的算法和数据结构,要特别警觉,避免使用会渐进地产生糟糕性能的算法或编码技术。基本编码原则。避免限制优化的因素,这样编译器就能产生高效代码。 消除连续的函数调用。在可能时将计算移到循环外,考虑有选择的妥协程序的模块性以获得更大效率。消除不必要的存储器引用。引入临时变量来保存中间结果,只有在最后的值计算出来时,才能将结果放到数组或全局变量中。低级优化。

说到性能提高,可能有人会有一些说法:

(1)不要过早优化,优化是万恶之源; (2)花费很多时间所作的优化可能效果不明显,不值得; (3)现在内存、CPU价格都这么低了,性能的优化已经不是那么重要了。  ……

其实我的看法是:我们也许不必特地把以前写过的程序拿出来优化下,花费N多时间只为提升那么几秒或几分钟的时间。但是,我们在重构别人的代码或自己最初开始构思代码时,就需要知道这些性能提高技术,一开始就遵守这些基本原则来写代码,写出的代码也就不需要让别人来重构以提高性能了。另外,有的很简单的技术,比如说将与循环无关的复杂计算或大内存操作的代码放到循环外,对于整个性能的提高真的是较明显的。

如何使用代码剖析程序(code profiler,即性能分析工具)来调优代码? 程序剖析(profiling)其实就是在运行程序的一个版本中插入了工具代码,以确定程序的各个部分需要多少时间。 Unix系统提供了一个profiling叫GPROF,这个程序产生两类信息:

首先,它确定程序中每个函数花费了多少CPU时间。 其次,它计算每个函数被调用的次数,以执行调用的函数来分类。还有每个函数被哪些函数调用,自身又调用了哪些函数。

使用GPROF进行剖析需要3个步骤,比如源程序为prog.c。 1)编译: gcc -O1 -pg prog.c -o prog(只要加上-pg参数即可) 2)运行:./prog  会生成一个gmon.out文件供 gprof分析程序时候使用(运行比平时慢些)。 3)剖析:gprof prog  分析gmon.out中的数据,并显示出来。 剖析报告的第一部分列出了执行各个函数花费的时间,按照降序排列。 剖析报告的第二部分是函数的调用历史。具体例子可参考网上资料。

GPROF有些属性值得注意:

静态链接和动态链接一个很重要的区别是:动态链接时没有任何动态链接库的代码和数据节真正的被拷贝到可执行文件中,反之,链接器只需拷贝一些重定位和符号表信息,即可使得运行时可以解析对动态链接库中代码和数据的引用。

存储器映射 指的是将磁盘上的空间映射为虚拟存储器区域。Unix进程可以使用mmap函数来创建新的虚拟存储器区域,并将对象映射到这些区域中,这属于低级的分配方式。 一般C程序会使用malloc和free来动态分配存储器区域,这是利用堆的方式。

造成堆利用率很低的主要原因是碎片,当虽然有未使用的存储器但不能用来满足分配请求时,就会发生这种现象。 有两种形式的碎片:内部碎片和外部碎片。两者的区别如下:

内部碎片是在一个已分配的块比有效载荷大时发生的。例如,有些分配器为了满足对其约束添加额外的1字的存储空间,这个1字的空间就是内部碎片。它就是已分配块大小和它们的有效载荷大小之差的和。外部碎片是当空闲存储器合计起来足够满足一个分配请求,但是没有一个单独的空闲块足够大可以来处理这个请求时发生的。

现代OS提供了三种方法实现并发编程:

(1)基于进程的并发服务器 构造并发最简单的就是使用进程,像fork函数。例如,一个并发服务器,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。为了了解这是如何工作的,假设我们有两个客户端和一个服务器,服务器正在监听一个监听描述符(比如描述符3)上的连接请求。下面显示了服务器是如何接受这两个客户端的请求的。

关于进程的优劣,对于在父、子进程间共享状态信息,进程有一个非常清晰的模型:共享文件表,但是不共享用户地址空间。进程有独立的地址控件爱你既是优点又是缺点。由于独立的地址空间,所以进程不会覆盖另一个进程的虚拟存储器。但是另一方面进程间通信就比较麻烦,至少开销很高。

阳光总在风雨后。只有坚强的忍耐顽强的奋斗,

深入理解计算机系统9个重点笔记

相关文章:

你感兴趣的文章:

标签云: