- Convert it to
switch - Make sure tiny functions can be built in (how to do this depends on the compiler, but explicitly labeling them
inlineand placing them in the compilation unit is a good bet). - Finally, you can try to optimize profiling if (it seems quite possible) the switch statement calls branches unevenly.
The goal is to avoid the overhead of functional calls and force the compiler to reorder the switch statement to reduce the number of typically encountered branches.
:, , ; . - 1,07 , 0,79 - YMMV:
template<unsigned n0,unsigned n> struct F { static inline unsigned func(unsigned val); };
template<unsigned n> struct F<0,n> { static inline unsigned func(unsigned val) { return val + n;} };
template<unsigned n> struct F<1,n> { static inline unsigned func(unsigned val) { return val - n; } };
template<unsigned n> struct F<2,n> { static inline unsigned func(unsigned val) { return val ^ n; } };
template<unsigned n> struct F<3,n> { static inline unsigned func(unsigned val) { return val * n; } };
template<unsigned n> struct F<4,n> { static inline unsigned func(unsigned val) { return (val << ( n %16)) + n*(n&0xff); } };
template<unsigned n> struct F<5,n> { static inline unsigned func(unsigned val) { return (val >> ( n %16)) + (n*(n&0xff) << 16); } };
template<unsigned n> struct F<6,n> { static inline unsigned func(unsigned val) { return val / (n|1) + val; } };
template<unsigned n> struct F<7,n> { static inline unsigned func(unsigned val) { return (val <<16) + (val>>16); } };
template<unsigned n> struct f { static inline unsigned func(unsigned val) { return F<n%8,n>::func(val); } };
typedef unsigned (*fPtr)(unsigned);
fPtr funcs[256];
template<unsigned n0,unsigned n1> inline void fAssign() {
if(n0==n1-1 || n0==n1)
funcs[n0] = f<n0>::func;
else {
fAssign<n0,(n0 + n1)/2>();
fAssign<(n0 + n1)/2,n1>();
}
}
__forceinline unsigned funcSwitch(unsigned char type,unsigned val);
__declspec(noinline) unsigned doloop(unsigned val,unsigned start,unsigned end) {
for(unsigned x=start;x<end;++x)
val = funcs[x*37&0xff](val);
return val;
}
__declspec(noinline) unsigned doloop2(unsigned val,unsigned start,unsigned end) {
for(unsigned x=start;x<end;++x)
val = funcSwitch(x*37&0xff,val);
return val;
}
, , , doloop, doloop2 funcs[?], , .
, , MSC 10, ( ) , , . PGO ; , , , , , / PGO.