c++ - C/C++ 行的人类可读优化版本

标签 c++ c gcc optimization

我有一长串 OR 和 AND 链接在一起的 C++ 代码行。当然,编译器在优化它方面比我好得多,我不应该试图过度智能。但是,出于学习目的,我想知道表达式是否可以优化,以及编译器在通过 -O3-Os 后如何看待它。

有没有办法做到这一点?我可以将我想要的表达式一个一个地提取出来,然后将它们放入一个新的程序中。

举个愚蠢的例子,如果我有:

if( n < 2 && n < 1 )

我想看到编译器看到了可以简化为:

if ( n < 1 )

编辑: 其他可能发生优化魔术的情况涉及字节移位,例如除以 2 的幂。

一个真实的例子是这样的:

if(((col1 < col2) && (col1 + pdim < col2))
    || ((col2 < col1) && (col2 + pdim < col1))
    || ((row1 < row2) && (row1 + pdim < row2))
    || ((row2 < row1) && (row2 + pdim < row1))){
    overlap = false;
}

这段代码检查是否有两个大小为 pdim 的正方形由左上角的坐标 (col1, row1), (col2, row2 ) 是重叠的。

这主要是为了了解编译器可以为自己做什么,而不是在生产中使用它。当然,自己编写 C 行的优化版本不是一个好主意,因为它只会损害可读性,并且只能节省几微秒的编译时间。但在某些情况下它可能会变得有用,例如,当用 Python 编写时,没有编译器,Cython 不是一个选项,访问优化版本可能会有用。

我目前在 Linux 上使用 GCC,但如果更方便的话,我可以用 Clang 或任何其他替代品做同样的事情。

最佳答案

GCC 的优化过程以一种名为 GIMPLE 的格式处理代码的中间表示。 .

使用 -fdump-* options ,你可以要求 GCC 输出树的中间状态。

例如

测试.cc

#include <iostream>
#include <cstdlib>

int main()
{
  int n(rand());

  if (n < 2 && n < 1)
    std::cout << "OK" << std::endl;

  return 0;
}

编译

g++ -O3 -o test1 -fdump-tree-all test.cc

您将获得大量 (!) 文件,其中:

test.cc.165t.optimized

;; Function int main() (main, funcdef_no=1013, decl_uid=21841, cgraph_uid=229) (executed once)

int main() ()
{
  int n;
  struct basic_ostream & _6;

  <bb 2>:
  n_4 = rand ();
  if (n_4 <= 0)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  _6 = std::operator<< <std::char_traits<char> > (&cout, "OK");
  std::endl<char, std::char_traits<char> > (_6);

  <bb 4>:
  return 0;

}

因此您可以检查 gcc 执行了哪些优化:

if (n < 2 && n < 1)    //  optimized in if (n_4 <= 0) ...

有时在 gdb 调试器中运行程序并使用 disassemble/m 命令查看与 C/C++ 代码混合的程序集是一种有效的替代方法。

关于c++ - C/C++ 行的人类可读优化版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22645745/

相关文章:

c++ - (多操作系统)获取可执行路径

python - 在c中嵌入Python,然后在c++程序中运行它不起作用

c - 如何在按 CTRL + ALT + DEL 时停止此消息?

python - 安装 python-dev 和链接库后,Cython 中的 Hello World 程序因 gcc 而失败

c++ - 为什么必须将函数必须返回的数组声明为静态数组?

c - 为什么 execve 忽略环境参数?

c - 为什么这段代码不能继续?

linux - 在不依赖任何共享库的 Linux 上构建可执行文件

gcc - 如何修复警告: missing braces around initializer?

c++ - "duplicate symbol _heating_unit in BangBangControlTest.o and BangBangControl.o"是什么意思?