山那边是海 发表于 2015-1-16 11:05:00

CentOS教程之C\C++代码优化的27个倡议

当你经过一段时间的学习后就应该扩充自己的知识,多学习linux命令,但是不要在初学阶段就系统的学习linux命令。
  1.记着阿姆达尔定律:







[*]funccost是函数func运转工夫百分比,funcspeedup是你优化函数的运转的系数。
[*]以是,假如你优化了函数TriangleIntersect实行40%的运转工夫,使它运转快了近两倍,而你的程序会运转快25%。
[*]这意味着不常常利用的代码不必要做较多优化思索(大概完整不优化)。
[*]这里有句鄙谚:让常常实行的路径运转加倍高效,而运转希少的路径准确运转。
  2.代码先包管准确,然后再思索优化



[*]这其实不意味着用8周工夫写一个全功效的射线追踪算法,然后用8周工夫往优化它。
[*]分多步来做功能优化。
[*]先写准确的代码,当你意想到这个函数大概会被常常挪用,举行分明的优化。
[*]然后再寻觅算法的瓶颈,并办理(经由过程优化大概改善算法)。一般,改善算法能明显地改善瓶颈——大概是接纳一个你还没有料想到的办法。一切频仍挪用的函数,都必要优化。
  3.我所懂得的那些写出十分高效代码的人说,他们优化代码的工夫,是写代码工夫的两倍。

  4.跳转和分支实行价值高,假如大概,只管罕用。



[*]函数挪用必要两次跳转,外加栈内存操纵。
[*]优先利用迭代而不是递回。
[*]利用内联函数处置短小的函数来打消函数挪用开支。
[*]将轮回内的函数挪用挪动到轮回外(比方,将for(i=0;i<100;i++)DoSomething();改成DoSomething(){for(i=0;i<100;i++){…}})。
[*]if…elseif…elseif…elseif…很长的分支链实行到最初的分支必要良多的跳转。假如大概,将其转换为一个switch声明语句,编译器偶然候会将其转换为一个表查询单次跳转。假如switch声明不成行,将最多见的场景放在if分支链的最后面。
  5.细心思索函数下标的按次。



[*]两阶或更高阶的数组在内存中仍是以一维的体例在存储在内存中,这意味着(关于C/C++数组)array和array是相邻的,可是array和array大概相距很远。
[*]以得当的体例会见存储实践内存中的数据,能够明显地提拔你代码的实行效力(偶然候能够提拔一个数目级乃至更多)。
[*]古代处置器从主内存中加载数据各处理器cache,会加载比单个值更多的数据。该操纵会猎取哀求数据和相邻数据(一个cache行巨细)的整块数据。这意味着,一旦array已在处置器cache中,array很年夜大概也已在cache中了,而array大概还在内存中。
  6.利用指令层的并行机制



[*]只管很多程序仍是依附单线程的实行,古代处置器在单核中也供应了很多的并行性。比方:单个CPU能够同时实行4个浮点数乘,守候4个内存哀求并实行一个分支预判。
[*]为了最年夜化使用这类并行性,代码块(在跳转之间的)必要充足的自力指令来同意处置器被充实使用。
[*]思索睁开轮回来改善这一点。
[*]这也是利用内联函数的一个好来由。
  7.制止或削减利用当地变量。



[*]当地变量一般都存储在栈上。不外假如数目对照少,它们能够存储在CPU存放器中。在这类情形下,函数不仅失掉了更快会见存储在存放器中的数据的优点,也制止了初始化一个栈帧的开支。
[*]不要将大批数据转换为全局变量。
  8.削减函数参数的个数。



[*]和削减利用当地变量的来由一样——它们也是寄存在栈上。
  9.经由过程援用传送布局体而不是传值



[*]我在射线追踪中还找不到一个场景必要将布局体利用传值体例(包含一些复杂布局如:Vector,Point和Color)。
  10.假如你的函数不必要前往值,不要界说一个。

  11.只管制止数据转换。



[*]整数和浮点数指令一般操纵分歧的存放器,以是转换必要举行一次拷贝操纵。
[*]短整型(char和short)仍旧利用一全部存放器,而且它们必要被添补为32/64位,然后在存储回内存时必要再次转换为小字节(不外,这个开支必定比一个更年夜的数据范例的内存开支要多一点)。
  12.界说C++工具时必要注重。



[*]利用类初始化而不是利用赋值(Colorc(black);比Colorc;c=black;更快)
  13.使类机关函数尽量轻量。



[*]特别是经常使用的复杂范例(好比,color,vector,point等等),这些类常常被复制。
[*]这些默许机关函数一般都是在隐式实行的,这也许不是你所希冀的。
[*]利用类初始化列表(UseColor::Color():r(0),g(0),b(0){},而不是初始化函数Color::Color(){r=g=b=0;}.)
  14.假如能够的话,利用位移操纵>>和<<来取代整数乘除法

  15.当心利用表查找函数



[*]很多人都勉励将庞大的函数(好比:三角函数)转化为利用预编译的查找表。关于射线追踪功效来讲,这一般招致了不用要的内存查找,这很高贵(其实不断增加),而且这和盘算一个三角函数并从内存中猎取值一样快(特别你思索到三角查找打乱了cpu的cache存取)。
[*]在其他情形下,查找表会很有效。关于GPU编程一般优先利用表查找而不是庞大函数。
  16.对年夜多半类,优先利用+=、-=、*=和/=,而不是利用+、-、*、和?/



[*]这些复杂操纵必要创立一个匿名一时两头变量。
[*]比方:Vectorv=Vector(1,0,0)+Vector(0,1,0)+Vector(0,0,1);?创立了五个匿名一时Vector:Vector(1,0,0),Vector(0,1,0),Vector(0,0,1),Vector(1,0,0)+Vector(0,1,0),和Vector(1,0,0)+Vector(0,1,0)+Vector(0,0,1).
[*]对上述代码举行复杂转换:Vectorv(1,0,0);v+=Vector(0,1,0);v+=Vector(0,0,1);仅仅创立了两个一时Vector:Vector(0,1,0)和Vector(0,0,1)。这勤俭了6次函数挪用(3次机关函数和3次析构函数)。
  17.关于基础数据范例,优先利用+?、?-?、?*?、?和?/,而不是+=?、?-=?、?*=和/=

  18.推延界说当地变量



[*]界说一个工具变量一般必要挪用一次函数(机关函数)。
[*]假如一个变量只在某些情形下必要(比方在一个if声明语句内),仅在其必要的时分界说,如许,机关函数仅在其被利用的时分挪用。
  19.关于工具,利用前缀操纵符(++obj),而不是后缀操纵符(obj++)



[*]这在你的射线追踪算法中大概不是一个成绩
[*]利用后缀操纵符必要实行一次工具拷贝(这也招致了分外的机关和析构函数挪用),而前缀的机关函数不必要一个一时的拷贝。
  20.当心利用模板



[*]对分歧的是实例完成举行分歧的优化。
[*]尺度模板库已经由优秀的优化,不外我倡议你在完成一个交互式射线追踪算法时制止利用它。
[*]利用本人的完成,你晓得它怎样利用算法,以是你晓得怎样最无效的完成它。
[*]最主要的是,我的履历告知我:调试STL库十分低效。一般这也不是一个成绩,除非你利用debug版本做功能剖析。你会发明STL的机关函数,迭代器和其他一些操纵,占用了你15%的运转工夫,这会招致你剖析功能输入加倍费力。
  21.制止在盘算时举行静态内存分派



[*]静态内存关于存储场景和运转时代其他数据都很有效。
[*]可是,在很多(年夜多半)的体系静态内存分派必要猎取把持会见分派器的锁。关于多线程使用程序,实际中利用静态内存因为分外的处置器招致了功能下落,由于必要守候分派器锁和开释内存。
[*]即使关于单线程使用,在堆上分派内存也比在栈上分派内存开支年夜很多。操纵体系还必要实行一些操纵来盘算并找到合适尺寸的内存块。
  22.找到你体系内存cache的信息并使用它们



[*]假如一个是数据布局恰好合适一个cache行,处置全部类从内存中只必要做一次猎取操纵。
[*]确保一切的数据布局都是cache行巨细对齐(假如你的数据布局和一个cache行巨细都是128字节,仍有大概由于你的布局体中的一个字节在一个cache行中,而其他127字节在别的一个cahce行中)。
  23.制止不必要的数据初始化



[*]假如你必要初始化一年夜段的内存,思索利用memset。
  24.尽早停止轮回和尽早前往函数挪用



[*]思索一个射线和三角形交织,一般的情形是射线会超出三角,以是这里能够优化。
[*]假如你决意将射线和三角面板交织。假如射线和面板交织t值是正数,你能够当即前往。这同意你跳过射线三角交织一泰半的质心坐标盘算。这是一个年夜的勤俭,一旦你晓得这个交织不存在,你就应当当即前往交织盘算函数。
[*]一样的,一些轮回也应当尽早停止。比方,当设置暗影射线,关于近处的交织一般都是不用须的,一旦有相似的的交织,交织盘算就应当尽早前往。(这里的交织寄义不太分明,多是专业辞汇,译者注)
  25.在稿纸上简化你的方程式



[*]很多方程式中,一般都能够大概在某些前提中作废盘算。
[*]编译器不克不及发明这些简化,可是你能够。作废一个外部轮回的一些高贵操纵能够抵消你在其他中央的好几天的优化事情。
  26.整数、定点数、32位浮点数和64位双精度数字的数学运算差别,没有你设想的那末年夜



[*]在古代CPU,浮点数运算和整数运算差未几具有一样的效力。在盘算麋集型使用(好比射线追踪),这意味这能够疏忽整数和浮点数盘算的开支差别。这也就是说,你不用要对算数举行整数处置优化。
[*]双精度浮点数运算也不比单精度浮点数运算更慢,特别是在64位呆板上。我在统一台呆板测试射线追踪算法全体利用double比全体利用floats运转偶然候更快,反过去测试也看到了一样的征象(这里的原文是:Ihaveseenraytracersrunfasterusingalldoublesthanallfloatsonthesamemachine.Ihavealsoseenthereverse)。
  27.精益求精你的数学盘算,以打消高贵的操纵



[*]sqrt()常常能够被优化失落,特别是在对照两个值的平方根是不是分歧时。
[*]假如你反复地必要处置除x操纵,思索盘算1/x的值,乘以它。这在向量标准化(3次除法)运算中博得了年夜的改善,不外我比来发明也有点难以断定的。不外,这仍旧有所改善,假如你要举行三次或更多除法运算。
[*]假如你在实行一个轮回,那些在轮回中实行不产生变更的部分,确保提取到轮回内部。
[*]思索看看你的盘算值是不是能够在轮回中修正失掉(而不每次都从头入手下手轮回盘算)。
  原文链接:cs.clemson.edu翻译:伯乐在线-周昌鸿
对于开发环境的选择尽量要轻量级和高度可定制,航空母舰级别的工具往往会让你迷惑不解;

深爱那片海 发表于 2015-1-18 07:47:30

其实早在本科一年级就学过C++,当年好像也比较认真的学过,至少成绩上算是认真学过的,只是当年大脑没怎么开化,学的半生不熟的,高级编程自然不用说。

再现理想 发表于 2015-1-25 14:46:31

见过太多得帖子问如何学习C++,也听过很多人说找不到方法,其实所有人一开始都有这样得困惑,我只想写出自己的心得。

金色的骷髅 发表于 2015-2-2 22:34:21

我当初学习MFC三个月,连门都没有进去,我非常懊恼,看着人家学VB得轻松就做出窗口程序,而自己还是在控制台下苦战,向导生成得代码实在不懂。

仓酷云 发表于 2015-2-8 18:12:17

在与别人合作中,可以学习到她们的优点,可以得到自己想不到的学习方法,与此同时,还可以增进我们的友谊。

海妖 发表于 2015-2-25 22:34:21

说起来,C++Primer和那本Plus思路不一样,这本书第3章就开始教你用标准库,用string对象与vector容器,所以对基础薄弱的同学来说上手有点难。

飘灵儿 发表于 2015-3-8 09:11:33

通过实际操作,学会 C++语言程序编程的基本步骤、基本方法,开发了自己的逻辑思维能力,培养了分析问题、解决问题的能力。深刻体会到“没有做不到的,

谁可相欹 发表于 2015-3-15 22:27:57

实训的项目是高级语言程序设计。说实话,在这么多科目中,这是我学得最糟糕的一科。刚开始,我对这实训没什么信心,不知能否按时完成。
页: [1]
查看完整版本: CentOS教程之C\C++代码优化的27个倡议