要写出卓越代码,首先要知道如何写出高效代码。而要写出高效的代码,又必须了解计算机系统是如何执行程序的,以及编程语言中的各种抽象是如何映射到底层硬件上的。
过去,学习高水平的编码技术首先要学习汇编语言。虽然这个方法没错,但有点用力过猛。学习汇编语言涉及两个相关主题:计算机组成(Machine Organization)和汇编语言编程。学习汇编语言真正的好处其实来自于计算机组成。因此,本书只着重于介绍计算机组成的相关内容,这样读者不必学习汇编语言也能学会如何编写卓越代码。
计算机组成是计算机体系结构的一个子集,涉及底层数据类型、CPU内部结构、内存结构和访问、底层计算机操作、大容量存储结构、外围设备及计算机和外界的通信方式。本书将集中讨论计算机体系结构和计算机组成中的部分内容,它们或对程序员可见,或有助于理解系统架构师选择特定系统设计方法的原因。学习计算机组成的目的不是自己设计CPU或者计算机系统,而是学会如何充分地利用现有的计算机设计,这也是本书的目的。我们快速地浏览一下本书的内容。
第2章、第4章和第5章介绍了基本的计算机数据表示形式,如计算机如何表示有符号与无符号整数、字符、字符串、字符集、实数值、小数值,以及其他数值或者非数值。如果不清楚计算机内部这些不同的数据类型是如何表示的,就很难理解为什么有些操作使用这些数据类型时效率特别低下。
第3章将讨论大多数现代计算机系统都会使用的二进制运算和位运算。第3章还给出了一些如何使用算术和逻辑运算写出更好代码的深层次建议,这些方法一般的初级编程课程都不会涉及。要成为卓越程序员,必须要掌握这些标准“窍门”。
第6章对内存进行了介绍,讨论了计算机如何访问内存,以及不同的内存性能。同时还介绍了CPU访问内存中不同类型的数据结构时采用的各种机器码寻址模式(Addressing Mode)。对于现代应用程序来说,很多时候就是因为程序员没有意识到内存访问的事情才造成性能问题。第6章也讨论了内存访问的影响。
第7章的话题又回到了数据类型及其表示形式上,内容涉及复合数据类型和内存对象,如指针、数组、记录、结构及联合。程序员总是不假思索地使用大型复合数据结构,根本不考虑这样做带来的内存和性能问题。知道了这些高级复合数据类型的底层表示,你就会更加清楚使用这些数据结构会有什么样的代价,就不会盲目地使用这些数据结构。
第8章讨论了布尔逻辑和数字设计。本章介绍了理解CPU和其他计算机系统组件设计所需的数学和逻辑背景知识。尤其是,本章讨论了如何优化布尔表达式,布尔表达式在各种高级编程语言中实在是太常见了,比如if和while语句中经常会使用布尔表达式。
第9章延续了第8章开始的硬件话题,介绍了CPU的体系结构。要写出卓越的代码,必须对CPU的设计和运作有一个基本的认识。按照CPU执行代码的方式来写代码,就可以使用更少的系统资源,得到更好的性能。
第10章讨论了CPU指令集体系结构。机器指令是CPU的基本执行单位,程序的执行时间由CPU执行的机器指令类型和数量决定。理解计算机架构师是如何设计机器指令的有助于深入理解有些操作就是比其他操作耗时的原因。一旦了解了机器指令的限制以及CPU是如何解释机器指令的,就可以利用这些信息来化腐朽为神奇。
第11章回到内存主题,讨论内存体系结构和组织。如果希望写出运行快速的代码,要注意学习本章的内容。本章介绍了内存层次结构及如何最大程度地利用缓存和其他快速内存组件。读了本章,你就会理解什么是颠簸,以及在自己的应用程序中如何避免性能低下的内存访问。
第12~15章的内容都和计算机系统如何与外界通信有关。许多外围(输入/输出)设备的运行速度远低于CPU和内存。即使我们能写出执行最快的指令序列,但由于不了解系统中I/O设备的限制,应用程序还是会运行缓慢。这4章讨论了通用I/O端口、系统总线、缓冲、握手、轮询和中断,同时介绍了如何有效地使用流行的PC外设,包括键盘、并行(打印机)端口、串行端口、磁盘驱动器、磁带驱动器、闪存、SCSI、IDE/ATA、USB及声卡。