这是我正在看的功能:
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;
}
我有一个测试工具,它传递所有可能的数字,大小= 5,左边用空格填充。我正在使用GCC 4.7.2。当我使用-O3编译后在callgrind下运行程序时,我得到:
I refs: 7,154,919
当我用-O2编译时,我得到:
I refs: 9,001,570
好的,所以-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]
所以我再次使用-O2编译,然后是所有上述选项。但是这让我的性能比普通的-O2更差:
I refs: 9,546,017
我发现向-O2添加-ftree-vectorize会导致性能下降。但我无法弄清楚如何将-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);
}
}
答案 0 :(得分:6)
这里已经回答了一个非常类似的问题:https://stackoverflow.com/a/6454659/483486
我已经复制了相关文字。
更新:There are questions about it in GCC WIKI:
- &#34; -O1(-O2,-O3或-Os)是否等同于个别优化选项?&#34;
没有。首先,单个优化选项(-f *)不启用优化,选项-Os或-Ox with x&gt; 0是必需的。其次,-Ox标志启用许多不受任何单独的-f *选项控制的优化。 There are no plans to add individual options for controlling all these optimizations.
- &#34; -O1(-O2,-O3或-Os)启用了哪些特定标志?&#34;
因平台和GCC版本而异。您可以通过这样做让GCC告诉您它启用了哪些标志:
touch empty.c gcc -O1 -S -fverbose-asm empty.c cat empty.s