《C++性能优化指南》 linux版代码及原理解读 第一章

概述:

        

目录

概述:

性能优化的必要性:

C++代码优化策略总结

用好的编译器并用好编译器

使用更好的算法

使用更好的库

减少内存分配和复制

移除计算

使用更好的数据结构

提高并发性

优化内存管理


性能优化的必要性:

        按照当今的CPU运行速度来说,执行一条指令所需要的时间是10的-9次方的时间单位,如此快速的执行速度是否就没有性能优化的必要了呢?其实不然,性能优化与CPU的执行速度并无非常大的关系,试想一下,一段代码,如果用了10秒的时间执行,但是其中的50%的时间是可以优化的,虽然感觉起来5S这个时间不太长,但如果这个代码段是在一个大型循环当中,如果这个循环执行十万次、一百万次、甚至更多的时候,就会发现这么一个规律:冗余的代码是随着CPU的执行速度而积累的,CPU执行的越快,冗余代码所耗费的时间的积累也就越快。如果能将这这冗余代码优化掉,那么程序执行速度就会变成原来的1/2,同理,原本的代码执行的时间越长,那么优化之后,节省的时间也就越多。

        按照刚才的逻辑,我们可以发现一个规律,那就是原本的代码执行的时间越长,优化之后,相对来说节省的时间可能会越多。假定在程序中有这么两段代码,第一段代码的执行时间为100S,其中的冗余代码的执行时间仅为30%,第二段代码的执行时间为1S,其中的冗余时间代码执行时间为80%,那么可以很简单的推算出来,时间长的代码优化的意义更大一些。即使第二段代码的冗余代码的执行时间是99%,优化那1秒钟的时间在100秒下也是显得很微小。这就是一个重要的“90/10规则”。

        “90/10规则”指出,程序中只有10%的代码对于性能而言是重要的,换言之对程序中所有的代码进行性能优化是没有必要的。

        所以从性能优化的角度来说,找出那其中10%的代码对程序进行优化,这对于性能优化而言是很重要的第一步。

C++代码优化策略总结

用好的编译器并用好编译器

        C++的编译器是一个负责将语言代码转换成机器可以识别的代码的一套复杂的软件,它对某一个具体的编译平台,生成出来的机器码很大程序是不一样的。甚至对于同一个平台来说,相同的代码,相同的编译器,但是版本不同,生成的机器码也会不同,甚至执行的效率也会不同。当然,在编译时指定-o1 -o2 等等生成的机器码也会不同,这些都是影响代码执行效率的因素。

        每个编译器都可以说是一个商业软件,虽然有一些免费,但是这些编译器都是某公司或者某组织实现的,因此不同的编译器可能对于某个平台而言或者对于某种CPU而言有一些优势,这些需要根据具体的情况可以进行测试。例如Intel提供的编译器对于Intel的CPU来说应该说可能会支持的更好(按理来说)。

使用更好的算法

        或许我们从大学时期就学习过各种不同的排序算法,单单从排序算法而已,O(N)和O(logN)甚至是O(1)的时间效率就有很大的差别。但是有时候从时间复杂度上也不能完全代表这个算法一定比另一个算法更快,比如假设一个算法是O(N)的时间复杂度,但是这个算法有很好的缓存局部性,另一个算法的时间复杂度是O(logN),但是每次取数值时都会触发一次缓存未命中,导致要重新取这个数据,我们可以假设一次缓存未命中后,取出相应数据所需要的时间为100次指令的执行时间,换言之在相同的时间下,第一种算法已经进行了100次的比较(这只是假设,实际上目前的CPU每次缓存的数据没有100个数据),那么我们还能说哪种算法一定更快吗?

使用更好的库

        如果我们使用编译器提供的库来进行编程,那我们一般来说不需要对这些库进行调优或者修复bug,因为这些库有专门的人进行维护。但是不同的库对C++标准的支持情况是不一样的。

        有很多比较著名的库,他们分别实现了不同的功能,或者具有不同的性能。比如Boost Project(http://www.boost.org)和Google Code(https://code.google.com)提供了很多开源的库,其中有一些用于I/O、窗口、处理字符串(请参见4章)和并发(请参见12章)的库。

        开发人员还可以开发适合自己项目的库,通过放松标准库中的某些安全性和健壮性约束来换取更快的运行速度。

        

减少内存分配和复制

        绝大多数C++语言特性的性能开销最多只是几个指令,但是每次调用内存管理器的开销却是数千个指令。

        第4章中介绍和引导出了许多在大家所熟知的字符串处理背景下的优化概念。第6章将讲解如何既减少动态内存分配的性能开销又不放弃实用的C++编程惯用法,比如字符串和标准库容器。对缓存复制函数的一次调用也可能消耗数千个CPU周期。因此,很明显减少复制是一种提高代码运行速度的优化方式。大量复制的发生都与内存分配有关,所以修改一处往往也会消灭另一处。其他可能会发生复制的热点代码是构造函数和赋值运算符以及输入输出。第6章将讨论这个主题。

        

移除计算

        除了内存分配和函数调用外,单条C++语句的性能开销通常都很小。但是如果在循环中执行100万次这条语句,或是每次程序处理事件时都执行这条语句,那么这就是个大问题了。绝大多数程序都会有一个或多个主要的事件处理循环和一个或多个处理字符的函数。找出并优化这些循环几乎总是可以让性能优化硕果累累。

  •         第7章提出了一些帮助你找出频繁被执行的语句的建议
  •         第3章将介绍在尝试减少计算数量之前,如何确定程序中的哪部分会被频繁地执行。

        

使用更好的数据结构

        选择最合适的数据结构对性能有着深刻的影响,因为常用的插入、迭代、排序和检索元素的算法的运行时开销取决于数据结构。不同的数据结构对于这些操作在时间上的表现有很大不的不同。除此之外,不同的数据结构在使用内存管理器的方式上也有所不同。另一个原因是数据结构可能有也可能没有优秀的缓存本地化

  •         第10章将 探索C++标准库提供的数据结构的性能、行为和权衡。
  •         第9章将讨论使用标准库算法去实现基于简单矢量和C数组的表数据结构。

提高并发性

        现在的Cpu从以前的单核CPU需要用时间片轮询做到假并发,升级成了多核心多线程的Cpu结构,而现在硬件上已经支持同时运行多个线程,但是在并发的情况下,有很多问题会出现。比如死锁、数据竞争、等待、同步等导致的时间延迟。

  •         第12章探讨了如何高效地控制并发线程同步。

优化内存管理

        内存管理器作为C++运行时库中的一部分,管理着动态内存分配。它在许多C++程序中都会被频繁地执行。C++确实为内存管理提供了丰富的API,虽然多数开发人员都从来没有使用过。

  • 第13章将展示一些改善内存管理效率的技术。

        

你可能感兴趣的:(C++性能优化指南,性能优化,C++性能优化,性能优化)