Extreme memory demand compiling not-too-complicated expression: gcc bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear gcc-ers,
    I need to compile fairly complex (automatically generated)
expressions using gcc. An example is attached. To allow the code to
run reasonably fast, I assumed it would be reasonable to macro-ise the
functions where possible (most operators need to be protected against
overflow, since I can't control the expressions that are generated),
and inline the rest. Inlining works fine (the code compiles in a
fraction of a second), but macro-ising doesn't. This version of the
code ran up to 14GB of (real) memory and ~15 minutes compilation time
before I killed it. While it doesn't matter much to me (the inlined
version is still a huge speed-up on the interpreter I was using till
now), it does seem a little surprising that compiling a relatively
simple expression should generate such overheads. I could understand
it, I guess, if I were using aggressive optimisations; but the same
overheads appeared even under minimum optimisation. So back to the
question: does this look like a bug to you? Should I be reporting it?
Even better, can anyone suggest a combination of switches that will
allow it to compile in a reasonable time and memory?
    Thanks and Best Wishes
    Bob
#include "math.h"

#define VCB_V_alk        98
#define VCB_V_ba         76
#define VCB_V_bz         75
#define VCB_V_cd         73
#define VCB_V_do         3
#define VCB_V_lgt        77
#define VCB_V_n          53
#define VCB_V_p          16
#define VCB_V_ph         2
#define VCB_V_sd         97
#define VCB_V_si         102
#define VCB_V_tb         15
#define VCB_V_tmp        115

#define INFPLUS  exp(700)
#define INFMINUS -exp(700)//#define EXPOVL 650
#define PVAL(y) ((y==HUGE_VAL)?(INFPLUS):((y==-HUGE_VAL)?(-INFMINUS):(y)))

#define DIVISION_BY_ZERO_MULTIPLIER 100000 // When division by zero happens, this number is multiplied to the numerator.
#define DIVISION_BY_ZERO_EPSILON 0.000001

#define FN_PLUS(X,Y) (PVAL(X+Y))
#define FN_MINUS(X,Y) (PVAL(X-Y))
#define FN_MULTIPLY(X,Y) (PVAL(X*Y))
// Can't #define DIVIDE(X,Y)  because protected - must inline
#define FN_SIN(X) (sin(X))		// range -1..1, no protection needed
#define FN_COS(X) (cos(X))		// range -1..1, no protection needed
#define FN_CARET(X) (PVAL(exp(X)))	
// Can't #define LOG(X) because protected - must inline

inline double FN_DIVIDE(double x, double y) {
	if (fabs(y - 0) > DIVISION_BY_ZERO_EPSILON) { // Protected division
		return PVAL(x/y);
	} else {
		return x * DIVISION_BY_ZERO_MULTIPLIER;
	}
}

inline double FN_LOG(double x) { //log (base e)
        if (x > 0) { // Protected logarithm
                return log(fabs(x));
        } else {
                return 1;
        }
}

double ba_eval(double vval[]) {
double retvalue;
retvalue = FN_MINUS(FN_MULTIPLY(vval[VCB_V_ba],FN_MINUS(FN_MULTIPLY(FN_DIVIDE(vval[VCB_V_lgt],30),FN_MULTIPLY(FN_DIVIDE(1,FN_PLUS(1,FN_CARET(FN_MULTIPLY(-1.5,FN_PLUS(vval[VCB_V_si],-2.5))))),FN_MULTIPLY(FN_DIVIDE(1,FN_PLUS(1,FN_CARET(FN_MULTIPLY(-25,FN_PLUS(vval[VCB_V_p],-0.1))))),FN_MULTIPLY(FN_DIVIDE(1,FN_PLUS(1,FN_CARET(FN_MULTIPLY(-0.2,FN_PLUS(vval[VCB_V_n],-2))))),FN_MULTIPLY(0.0334,FN_MULTIPLY(FN_CARET(FN_MINUS(1,FN_DIVIDE(vval[VCB_V_lgt],30))),FN_PLUS(FN_MULTIPLY(FN_DIVIDE(vval[VCB_V_tmp],27),FN_CARET(FN_MINUS(1,FN_DIVIDE(vval[VCB_V_tmp],27)))),FN_MULTIPLY(FN_DIVIDE(vval[VCB_V_tmp],4),FN_CARET(FN_MINUS(1,FN_DIVIDE(vval[VCB_V_tmp],4))))))))))),FN_MULTIPLY(0.0284681,FN_CARET(FN_MULTIPLY(0.038,vval[VCB_V_tmp]))))),FN_MULTIPLY(vval[VCB_V_bz],FN_MULTIPLY(0.00375,FN_DIVIDE(vval[VCB_V_ba],FN_PLUS(250,vval[VCB_V_ba])))));
return retvalue;
}

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux