g ++ -O3优于-O2,并且添加了所有额外的优化

Joh*_*nck 7 c++ optimization gcc g++ compiler-optimization

这是我正在看的功能:

template <uint8_t Size>
inline uint64_t parseUnsigned( const char (&buf)[Size] )
{
  uint64_t val = 0;
  for (uint8_t i = 0; i < Size; ++i)
    if (buf[i] != ' ')
      val = (val * 10) + (buf[i] - '0');
  return val;
}
Run Code Online (Sandbox Code Playgroud)

我有一个测试工具,它传递所有可能的数字,大小= 5,左边填充空格.我正在使用GCC 4.7.2.当我使用-O3编译后在callgrind下运行程序时,我得到:

I   refs:      7,154,919
Run Code Online (Sandbox Code Playgroud)

当我用-O2编译时,我得到:

I   refs:      9,001,570
Run Code Online (Sandbox Code Playgroud)

好的,所以-O3提高了性能(我确认一些改进来自上述功能,而不仅仅是测试工具).但是我不想完全从-O2切换到-O3,我想找出要添加的特定选项.所以我咨询man g++了一下它所说的由-O3添加的选项列表:

-fgcse-after-reload                         [enabled]
-finline-functions                          [enabled]
-fipa-cp-clone                              [enabled]
-fpredictive-commoning                      [enabled]
-ftree-loop-distribute-patterns             [enabled]
-ftree-vectorize                            [enabled]
-funswitch-loops                            [enabled]
Run Code Online (Sandbox Code Playgroud)

所以我再次使用-O2编译,然后是所有上述选项.但这让我的性能比普通的-O2更差:

I   refs:      9,546,017
Run Code Online (Sandbox Code Playgroud)

我发现将-ftree-vectorize添加到-O2会导致性能下降.但我无法弄清楚如何将-O3性能与任何选项组合相匹配.我怎样才能做到这一点?

如果您想自己尝试一下,这里是测试工具(将上面的parseUnsigned()定义放在#includes下):

#include <cmath>
#include <stdint.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>

template <uint8_t Size>
inline void increment( char (&buf)[Size] )
{
  for (uint8_t i = Size - 1; i < 255; --i)
  {
    if (buf[i] == ' ')
    {
      buf[i] = '1';
      break;
    }

    ++buf[i];
    if (buf[i] > '9')
      buf[i] -= 10;
    else
      break;
  }
}

int main()
{
  char str[5];
  memset(str, ' ', sizeof(str));

  unsigned max = std::pow(10, sizeof(str));
  for (unsigned ii = 0; ii < max; ++ii)
  {
    uint64_t result = parseUnsigned(str);
    if (result != ii)
    {
      printf("parseUnsigned(%*s) from %u: %lu\n", sizeof(str), str, ii, result);
      abort();
    }
    increment(str);
  }
}
Run Code Online (Sandbox Code Playgroud)

Omn*_*ity 6

这里已经回答了一个非常类似的问题:https://stackoverflow.com/a/6454659/483486

我复制了下面的相关文字.

更新:在GCC WIKI中有关于它的问题:

  • " -O1(-O2,-O3或-Os)是否等同于个别优化选项? "

首先,单个优化选项(-f*)不启用优化,需要选项-Os或-Ox,其中x> 0.其次,-Ox标志启用许多不受任何单独的-f*选项控制的优化.没有计划添加用于控制所有这些优化的单个选项.

  • " -O1(-O2,-O3或-Os)启用了哪些特定标志? "

因平台和GCC版本而异.您可以通过执行以下操作让GCC告诉您它启用了哪些标志:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s
Run Code Online (Sandbox Code Playgroud)