01 2024 档案
摘要:如果程序只是运行一个计算密集型的任务,那么分析器会自动地告诉我们程序中的热点在哪里。不过如果程序要做许多不同的处理,可能在分析器看来,没有任何一个函数是热点。程序还有可能会花费大量的时间等待 I/O 或是外部事件,这样降低了程序的性能,增加了程序的实际运行时间。在这种情况下,我们需要测量程序中各个部
阅读全文
摘要:分析器是一个可以生成另外一个程序的执行时间的统计结果的程序。分析器可以输出一份包含每个语句或函数的执行频度、每个函数的累积执行时间的报表。许多编译器套件,如 Windows 上的 Visual Studio 和 Linux 上的 GCC 都带有分析器,可以帮助我们找到程序中的热点。微软曾经只在价格昂
阅读全文
摘要:开发软件在某种意义上就是一项实验。你想让程序做一些事情,然后开始编程,最后观察程序的运行结果是否与预想的一样。性能调优则是更有正式意义的实验。在开始性能调优前,必须要有正确的代码,即在某种意义上可以完成我们所期待的处理的代码。你需要擦亮眼睛审视这些代码,然后问自己:“为什么这些代码是热点?”为什么某
阅读全文
摘要:1. 必须测量性能 人的感觉对于检测性能提高了多少来说是不够精确的。人的记忆力不足以准确地回忆起以往多次实验的结果。本内侧的知识可能会误导你,使你相信了一些并非总是正确的事情。当判断是否应当对某段代码进行优化的时候,开发人员的直觉往往差得令人吃惊。他们编写了函数,也知道这个函数会被调用,但他们并不清
阅读全文
摘要:测量和实验是所有改善程序性能尝试的基础。本内容及将介绍两种测量性能的工具软件:分析器和计时器软件。我将讨论如何设计性能测量实验,使得测量结果更有指导意义,而不是误导我们。 最基本和最频繁地执行的软件性能测量会告诉我们“需要多长时间”。执行函数需要多长时间?从磁盘读取配置文件需要多长时间?启动和退出程
阅读全文
摘要:C++ 程序表现得仿佛它们是按顺序执行的,完全遵守了 C++ 流程控制语句的控制。上句话影响优化的计算机行为 | 19中的含糊其辞的“仿佛”正是许多编译器进行优化的基础,也是现代计算机硬件的许多技巧的基础。 当然,在底层,编译器能够而且有时也确实会对语句进行重新排序以改善性能。但是编译器知道在测试一
阅读全文
摘要:在 Kernighan 和 Ritchie 的《C 程序设计语言》一书中,所有语句的性能开销都一样。一个函数调用可能包含任意复杂的计算。但一个赋值语句通常只是将保存在一个寄存器中的内容变为另外一个内容保存在另一个寄存器中。因此,以下赋值语句int i,j;...i = j;会 从 j 中 复 制 2
阅读全文
摘要:C++ 对用户所撒的最大的谎言就是运行它的计算机的结构是简单的、稳定的。为了假装相信这条谎言,C++ 让开发人员不用了解每种微处理器设备的细节即可编程,如同正在使用真实得近乎残酷的汇编语言编程一样。
阅读全文
摘要:除了最小的处理器外,其他处理器都有硬件可以确保程序之间是互相隔离的。这样,程序A 不能读写和执行属于程序 B 的物理内存。这个硬件还会保护操作系统内核不会被程序覆写。另一方面,操作系统内核需要能够访问所有程序的内存,这样程序就可以通过系统调用访问操作系统。有些操作系统还允许程序发送访问共享内存的请求
阅读全文
摘要:任何运行于现代操作系统中的程序都会与同时运行的其他程序、检查磁盘或者新的 Java 和Flash 版本的定期维护进程以及控制网络接口、磁盘、声音设备、加速器、温度计和其他外设的操作系统的各个部分共享计算机。每个程序都会与其他程序竞争计算机资源。 程序不会过多在意这些事情。它只是会运行得稍微慢一点而已
阅读全文
摘要:另一个会导致流水线停滞的原因是计算机需要作决定。大多数情况下,在执行完一条指令后,处理器都会获取下一个内存地址中的指令继续执行。这时,多数情况下,下一条指令已经被保存在高速缓存中了。一旦流水线的第一道工序变为可用状态,指令就可以连续地进入到流水线中。但是控制转义指令略有不同。跳转指令或跳转子例程指令
阅读全文
摘要:嵌入在咖啡机和微波炉中的简单的微处理器被设计为执行指令的速度与从内存中获取指令一样快。桌面级微处理器则有额外的资源并发地处理指令,因此它们执行指令的速度可以比从主内存获取指令快很多倍,多数时候都需要高速缓存去“喂饱”它们的执行单元。对优化而言,这意味着内存访问决定了计算开销。如果没有其他东西“妨碍”
阅读全文
摘要:实际上,计算机中的内存容量并非是无限的。为了维持内存容量无限的假象,操作系统可以如同使用高速缓存一样使用物理内存,将没有放入物理内存中的数据作为文件存储在磁盘上。这种机制被称为虚拟内存(virtual memory)。虚拟内存制造出了拥有充足的物理内存的假象。不过,从磁盘上获取一个内存块需要花费数十
阅读全文
摘要:处理器可以一次从内存中读取一字节的数据,但是更多时候都会读取由几个连续的字节组成的一个数字。例如,在微软的 Visual C++ 中,读取 int 值时会读取 4 字节。由于同一个 内存可以以两种不同的方式访问,设计计算机的人必须面对一个问题:首字节,即最低地址字节,是组成 int 的最高有效位还是
阅读全文
摘要:为了进一步补偿主内存的缓慢速度,许多计算机中都有高速缓存(cache memory),一种非常接近处理器的快速的、临时的存储,来加快对那些使用最频繁的内存字的访问速度。一些计算机没有高速缓存,其他一些计算机则有一层或多层高速缓存,其中每一层都比前一层更小、更快和更昂贵。当一个执行单元要获取的字节已经
阅读全文
摘要:虽然 C++ 认为每个字节都是可以独立访问的,但计算机会通过获取更大块的数据来补偿缓慢的内存速度。最小型的处理器可以每次从主内存中获取 1 字节,桌面级处理器则可以立即获取 64 字节。一些超级计算机和图形处理器还可以获取更多。当 C++ 获取一个多字节类型的数据,比如一个 int、double 或
阅读全文
摘要:计算机的主内存相对于它内部的逻辑门和寄存器来说非常慢。将电子从微处理器芯片中注入相对广阔的一块铜制电路板上的电路,然后将其沿着电路推到几厘米外的内存芯片中,这个过程所花费的时间为电子穿越微处理器内各个独立的微距晶体管所需时间的数千倍。主内存太慢,所以桌面级处理器在从主内存中读取一个数据字的时间内,可
阅读全文
摘要:只有最简单的微处理器和某些具有悠久历史的大型机才直接与 C++ 模型相符。对性能优化影响优化的计算机行为 而言非常重要的是,真实计算机的实际内存硬件的处理速度与指令的执行速率相比是很慢的。内存并非真的是以字节为单位被访问的,内存并非是一个由相同元素组成的简单的线性数组,而且它的容量也是有限的。真实的
阅读全文
摘要:C++ 程序至少会假装相信讲解过的简单的计算机基本模型中的一个版本。 其中有可以以固定字符长度的字节为单位寻址,在本质上容量是无限的内存。有一个与其他任何有效的内存地址都不同的特殊的地址,叫作 nullptr。整数 0 会被转换为 nullptr,尽管在地址 0 上不需要 nullptr。有一个概念
阅读全文
摘要:1.如今所使用的微处理器设备的种类多样,从只有几千个逻辑门且时钟频率低于 1MHz 的价值 1 美元的嵌入式设备,到有数十亿逻辑门且时钟频率达到千兆赫兹级别的桌面级设备。一台包含数千个独立执行单元的大型计算机的尺寸可以与一个大房间相当,它消耗的电力足够点亮一座小城市中所有的电灯。这很容易让人误以为这
阅读全文
摘要:1-用好的编译器并用好编译器 C++ 编译器是非常复杂的软件构件。每种编译器为 C++ 语句生成的机器码都有差别。它们所看到的优化机会是不同的,会为相同的源代码产生不同的可执行文件。如果打算为代码做出最后一丁点性能提升,那么你可以尝试一下各种不同的编译器,看看是否有一种编译器会为你产生更快的可执行文
阅读全文
摘要:说“性能无所谓”的同事也可能是想说性能对于某些特殊的应用程序——例如受人体反应约束或运行于处理器速度极快的桌面计算机上的应用程序——无所谓。但对于那些运 行于内存、电源或者处理速度受限的小型嵌入式设备和移动处理器上的应用程序来说,性能的影响非常大;对于那些运行于大型计算机上的服务器程序的影响也非常大
阅读全文