编译器如何优化我们的代码?

Ami*_*deh 10 c c++ compiler-construction optimization compiler-optimization

当我回答另一个人的问题时,我遇到了这个问题.编译器如何优化代码?const,...等关键字可以帮忙吗?除了挥发性和内联函数以及如何通过自己优化代码之外的事实!

小智 11

编译器可以自由地优化代码,只要它们可以保证代码的语义不会改变.

我建议从编译器优化维基百科页面开始,因为在许多不同阶段执行了许多不同类型的优化.

正如您所看到的,现代编译器在优化代码方面非常"智能"(编译的C代码通常比手写编译快,除非程序员真正知道如何利用所有特定的处理器指令和怪癖).正如其他人所说,首先基于良好的设计来写清楚.


Ale*_*ece 6

您可以做的一件非常重要的事情(超出编译器可以为您做的事情)是要了解缓存.由于访问内存非常耗时,因此缓存会尝试不仅存储您访问它的数据,还会存储附近的元素.这就是为什么foo跑得比以前快得多bar:

array[ NUM_ROWS ][ NUM_COLS ];

foo() 
{
    int row, col;
    int sum = 0;

    // accesses the elements in the array continuously
    for ( row = 0; row < NUM_ROWS ; row++ ) 
    {
         for ( col = 0; col < NUM_COLS; col++ )
         {
              sum += array[ row ][ col ];
         }
    }
}

bar() 
{
    int row, col;
    int sum = 0;

    // skips from row to row ( big jumps that might miss the cache )
    for ( col = 0; col < NUM_COLS ; col++ ) 
    {
         for ( row = 0; row < NUM_ROWS; row++ )
         {
              sum += array[ row ][ col ];
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 要注意的另一件事是重复字符串连接.做错了,这可以使代码看起来O( n )实际上在其中运行O( n^2 )- 请参阅有关Joel on Software的文章

编辑: s/disk/memory /

  • 您的示例代码与访问磁盘有什么关系? (4认同)
  • 知道缓存会比++行节省更多:P @jayrdub:这涉及到内存*实际*如何在机器中工作的解释.基本上,`array [row] [col]`是对主内存的调用,它最初存储在硬盘上.由于硬盘移动速度比CPU慢得多,因此计算机会将信息存储在更容易访问的"缓存"中. (4认同)
  • 我觉得你有一台怪异的电脑 (4认同)
  • @Alex Reece - 我认为没有人这么说.反对意见是你在提到记忆时说"磁盘". (3认同)
  • @Alex:gcc(-floop-interchange)请参阅http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html,我认为这是llvm中名为loop-rotate的那个:http:// llvm.组织/文档/ Passes.html#环旋转 (3认同)
  • @Armen Tsirunyan - 这里没有使用表达式`row ++`的值.在这种情况下,您的编译器可能会为`++ row`和`row ++`生成相同的代码. (2认同)
  • @Alex:对于大多数情况(即不涉及数组大小主存储器大小的那些情况),处理行主要与列主要数组访问方案时遇到的问题的缓存是*CPU的一个或多个级别*缓存并与*disk*缓存无关. (2认同)
  • @Alex Reece:维基百科的文章:http://en.wikipedia.org/wiki/Loop_interchange (2认同)