当前位置:  开发笔记 > 编程语言 > 正文

你最喜欢的低级代码优化技巧是什么?

如何解决《你最喜欢的低级代码优化技巧是什么?》经验,为你挑选了11个好方法。

我知道你应该只在必要时优化事物.但是,如果认为有必要,你最喜欢的低级别(与算法级别相比)优化技巧是什么.

例如:循环展开.



1> Paul Tomblin..:
gcc -O2

编译器可以做得更好.


"......比你可以." < - 一般情况.在一些特定的实例(例如算法,DSP等)中,人类可以编写看起来相当奇怪的C例程,但是一旦编译,就会为编译器的特定目的生成更好的汇编.
"编译器可以做得比你做得好得多" - 如果你是编译器编写者,那就不是了,而且我认为这就是问题所解决的问题."我最后一次看到汇编程序并使用它来编写更好的C" - 你做得很好.查看汇编程序并使用它来编写更好的汇编程序.

2> Adam Davis..:

为过滤器,循环缓冲器等选择2的幂.

非常非常方便.

-亚当


@daspostloch - 这个想法是你经常需要对访问数据的东西进行边界检查和截断.这意味着执行`if(input> MAX_SIZE)input = input - MAX_SIZE;`.但是,如果结构的大小是2的幂,则可以使用一个"AND"操作完成检查和数学运算.例如,如果数据大小为128,则`input = input&0x7F;`将截断128以上的所有内容,否则单独保留`input`,这意味着可以删除之前的`if`语句.

3> strager..:

当然,为什么,有点笨拙的黑客!



4> Steve..:

科学代码中最有用的一个就是pow(x,4)x*x*x*x.Pow几乎总是比乘法更昂贵.接下来是

  for(int i = 0; i < N; i++)
  {
    z += x/y;
  }

  double denom = 1/y;
  for(int i = 0; i < N; i++) 
  {
    z += x*denom;
  }

但我最喜欢的低级优化是确定哪些计算可以从循环中删除.它总是更快地进行一次计算而不是N次.根据您的编译器,其中一些可能会自动为您完成.



5> MSN..:

检查编译器的输出,然后尝试强制它以更快地执行某些操作.



6> 小智..:

我不一定称之为低级优化,但通过明智地应用缓存,我通过所有低级别技巧的应用程序组合,已经节省了数量级更多的周期.其中许多方法都是特定于应用的.

具有数据库查询的LRU缓存(或任何其他基于IPC的请求).

记住上次失败的数据库查询,并在特定时间范围内重新请求时返回失败.

记住您在大型数据结构中的位置,以确保如果下一个请求是针对同一节点,则搜索是免费的.

缓存计算结果以防止重复工作.除了更复杂的情况,这常常发现iffor语句.

CPU和编译器不断变化.不管底层代码的技巧,是有道理的3个CPU芯片与前不同的编译器可能实际上是对当前建筑速度较慢,有可能是一个很好的机会,这一招可能会混淆谁是维持在未来这段代码.



7> Thomas..:

++i可以比快i++,因为它避免创建一个临时的.

对于现代C/C++/Java/C#编译器,这是否仍然适用,我不知道.对于具有重载运算符的用户定义类型,它可能是不同的,而在简单整数的情况下,它可能无关紧要.

但我开始喜欢它的语法......它读起来像"增量i",这是一个合理的顺序.


大多数现代编译器如果仅用作语句而不是表达式,则不会创建临时编译器.

8> Brian R. Bon..:

使用模板元编程在编译时而不是在运行时计算事物.



9> Justin Love..:

多年以前,有一个不那么聪明的编译器,我从函数内联,行走指针而不是索引数组获得了很大的里程,并且迭代到零而不是最大值.

如果有疑问,对汇编的一点知识将让你看看编译器产生了什么并攻击低效的部分(使用源语言,使用对编译器更友好的结构.)



10> smcameron..:

预先计算值.

例如,如果你的应用不一定需要角度非常精确,而不是sin(a)或cos(a),也许你用圆圈的1/256表示角度,并创建浮点数正弦[]和余弦[]预先计算这些角度的sin和cos.

并且,如果您经常需要一个给定长度的某个角度的矢量,您可能会预先计算所有那些已经乘以该长度的正弦和余弦.

或者,更普遍的说,交易记忆速度.

或者,更一般地说,"所有编程都是一种缓存练习" - Terje Mathisen

有些事情不太明显.例如,遍历二维数组,您可能会执行类似的操作

    for (x=0;x

如果您这样做,您可能会发现处理器缓存更喜欢它:

   for (y=0;y

或相反亦然.



11> alex strange..:

不要循环展开.不要做Duff的设备.使您的循环尽可能小,其他任何东西都会抑制x86性能和gcc优化器性能.

摆脱分支可能是有用的,所以完全摆脱循环是好的,那些无分支的数学技巧确实有效.除此之外,尽量不要离开L2缓存 - 这意味着如果浪费缓存空间,也应该避免大量的预先计算/缓存.

并且,特别是对于x86,尝试在任何时候保持使用的变量数量.很难说这些编译器会用这种东西做什么,但通常用较少的循环迭代变量/数组索引最终会得到更好的asm输出.

当然,这适用于台式机CPU; 具有快速内存访问速度的慢CPU可以预先计算更多,但在这些日子里,这可能是一个总内存很少的嵌入式系统......

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有