6

C/C++ 编译器仅在使用 -Os、-O1 和 -O2 时使用常量参数(在编译时已知)优化单层函数。它们不会优化所有层。只有 -O3 可以做到这一点。gcc 是 WinAVR 4.3.3,它不支持属性“优化”。

void inner(double value)
{
    //operations using value
    //...
}

void outer(double value)
{
    //few operations using value
    //...
    inner(value);
}

int main()
{
    inner(1); //optimize
    outer(1); //only optimize by using -O3
}

除了以下之外,还有哪些可能的解决方案?

  1. -O3 保存程序或文件(滥用会炸毁大小)
  2. 函数的属性优化-O3(4.3.3不支持)
  3. 宏(容易出错)

更新:

//inner function
static inline void _delay_us(double __us) __attribute__((always_inline));
//outer function
void f(double);
inline f1(double);
static inline f2(double);
static f3(double);

f1 已优化,但警告“_delay_us”是静态的,但用于内联函数“f1”,由于静态函数问题,该函数不是静态的。其他没有优化。


解决方案:

static inline void outer(double) __attribute__((always_inline));

内联是关键。我的外部函数对于内联来说太大了。属性 always_inline 强制函数内联。这允许编译器以低于试图找出优化的编译成本来优化函数。-O3 足够聪明,可以进行优化,但 -Os 不行。-Os 可能需要一些编译器选项。(关键字 static 是必需的,因为内部函数也是静态内联的。)

4

4 回答 4

3

有点类似于宏选项 (3),但没有宏的缺点,您可以制作特定的函数inline,这通常会导致所需的常量优化。当然,这仅在您从一个地方(或几个地方)调用相关函数时才有帮助,否则代码膨胀会成为一个问题。

请注意,gcc 规定强制特定的内联函数始终被内联(而不是让编译器自行决定)__attribute__ ((always_inline)):其他编译器通常具有类似的机制,尽管它可能是命令行开关或编译指示。

于 2011-01-31T08:48:52.050 回答
1

一般来说,如果您增加提供给编译器的信息,那么它可能能够执行更好的优化。

例如,假设这些是唯一的调用innerouter那么您可以将它们声明为static限制它们的范围,并允许编译器在优化它们方面有更大的灵活性。

根据函数的实际内容,您还可以将它们的参数声明为const这让编译器立即知道如果不分析代码就无法更改它们

static void inner(const double value)
{
    //operations using value
}

static void outer(const double value)
{
    //few operations using value
    //...
    inner(value);
}
于 2011-01-31T12:20:00.397 回答
1

至少在 GCC 中,这些-O 标志只是打开一大堆其他标志,参见例如http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html。您可以只启用您感兴趣的那些,尽管通常不鼓励这样做。

请注意,我不确定例如 GCC 的行为-O2是否-O3一定是完全不同的编译器会做什么的任何指标。

于 2011-01-31T08:31:25.240 回答
0

How about introducing a function 'outerFast', defined in it's own cpp, including the definitions of inner and outer, and compiling only that file with -O3?

It has its own disadvantages, though.

于 2011-01-31T12:58:55.967 回答