Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c/c++ optimize for constant variable in calling functions

C/C++ compilers optimize single layer functions with constant parameters (known at compile time) only when using -Os, -O1 and -O2. They do not optimize all the layers. Only -O3 can do that. gcc is WinAVR 4.3.3 which does not support attribute "optimize".

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
}

What are the possible solutions other than the followings?

  1. -O3 hold program or file (misuse will blow up the size)
  2. attribute optimize -O3 for the functions (4.3.3 does not support)
  3. macro (error prone)

Update:

//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 is optimized but give warning '_delay_us' is static but used in inline function 'f1' which is not static due to static function problem. Others are not optimized.


Solution:

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

Inline is the key. My outer function is too large for inline. The attribute always_inline forces the function to be inline. This allows the compiler to optimize the function with less compilation cost than trying to figure out the optimization. -O3 is smart enough to do the optimization but not -Os. -Os may need some compiler options. (The keyword static is required because the inner function is also static inline.)

like image 495
keithyip Avatar asked Jan 31 '11 08:01

keithyip


2 Answers

Somewhat similar to the macro option (3), but without the disadvantages of a macro, you can make specific functions inline, which will typically result in the desired constant optimizations. Of course this only helps if you're calling the relevant functions from one place (or from a few places), otherwise code bloat becomes an issue.

Note that gcc has a provision for forcing specific inline functions to always be inlined (rather than leaving this to the compiler's discretion): __attribute__ ((always_inline)). Other compilers will typically have a similar mechanism, although it may be a command line switch or a pragma.

like image 64
Paul R Avatar answered Sep 30 '22 06:09

Paul R


In GCC at least, the -O flags just turn on a whole load of other flags, see e.g. http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html. You could just enable the ones you're interested in, although that's generally discouraged.

Note that I'm not sure that the behaviour of e.g. GCC at -O2 and -O3 is necessarily any indicator of what a completely different compiler will do.

like image 44
Oliver Charlesworth Avatar answered Sep 30 '22 06:09

Oliver Charlesworth