[Ffmpeg-devel] [PATCH] optimize ff_eval

Michael Niedermayer michaelni
Thu Oct 26 22:25:23 CEST 2006


Hi

On Thu, Oct 26, 2006 at 08:45:02PM +0200, Oded Shimon wrote:
> I took the liberty of optimizing ff_eval for multiple runs by seperating 
> the parsing/compiling and runtime steps.
> 
> before:
> 97730 dezicycles in ff_eval, 1023 runs, 1 skips
> after:
> 13643 dezicycles in ff_parse, 1023 runs, 1 skips

great :)
what about the eval.o size?


> 
> 
> What should I do with this? Deperecate or keep old ff_eval? update current 
> calls for ff_eval to this new thing?

hmm, id say deprecate "now" and remove with the next major version increase
and update all in a seperate patch as soon as this is cleaned up reviewed and
commited


> 
> Patch is very obviously not cleaned up (there isn't even a free function 
> yet), just shows what I did...

understood, still some random comments below


[...]

> Index: libavcodec/eval.c
> ===================================================================
> --- libavcodec/eval.c	(revision 6797)
> +++ libavcodec/eval.c	(working copy)
> @@ -57,8 +57,6 @@
>      char **error;
>  } Parser;
>  
> -static double evalExpression(Parser *p);
> -
>  static int8_t si_prefixes['z' - 'E' + 1]={
>      ['y'-'E']= -24,
>      ['z'-'E']= -21,
> @@ -126,23 +124,64 @@
>      return 1;
>  }
>  
> -static double evalPrimary(Parser *p){
> -    double d, d2=NAN;
> +typedef struct expr_s expr_t;
> +struct expr_s {
> +    int type;
> +    double value; // is sign in other types
> +    int const_index;

> +    double (*func0)(double);
> +    double (*func1)(void *, double);
> +    double (*func2)(void *, double, double);

IMHO union or void* 


> +    expr_t * param[2];
> +};
> +
> +static double evalsquish(          double d           ) { return 1/(1+exp(4*d)); }
> +static double evalgauss (          double d           ) { return exp(-d*d/2)/sqrt(2*M_PI); }
> +static double evalmod   (void * a, double d, double d2) { return d - floor(d/d2)*d2; }
> +static double evalmax   (void * a, double d, double d2) { return d >  d2 ?   d : d2; }
> +static double evalmin   (void * a, double d, double d2) { return d <  d2 ?   d : d2; }
> +static double evalgt    (void * a, double d, double d2) { return d >  d2 ? 1.0 : 0.0; }
> +static double evalgte   (void * a, double d, double d2) { return d >= d2 ? 1.0 : 0.0; }
> +static double evaleq    (void * a, double d, double d2) { return d == d2 ? 1.0 : 0.0; }
> +static double evalpow   (void * a, double d, double d2) { return pow(d, d2); }
> +static double evalmul   (void * a, double d, double d2) { return d * d2; }
> +static double evaldiv   (void * a, double d, double d2) { return d / d2; }
> +static double evaladd   (void * a, double d, double d2) { return d + d2; }
> +
> +static double eval_expr(Parser * p, expr_t * e) {
> +    if (e->type == 0) return e->value;
> +    else switch(e->type) {
> +        case 1: return e->value * p->const_value[e->const_index];
> +        case 2: return e->value * e->func0(eval_expr(p, e->param[0]));
> +        case 3: return e->value * e->func1(p->opaque, eval_expr(p, e->param[0]));
> +        case 4: return e->value * e->func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1]));
> +        default: assert(0); return 0;
> +    }
> +}

now while this looks nice, i think it isnt optimal, what about putting all 
the "non user" functions in the switch/case? i think it might be faster
if not then iam fine with the above 


> +
> +static expr_t * parse_expr(Parser *p);
> +
> +static expr_t * parse_primary(Parser *p) {
> +    expr_t * d = calloc(1, sizeof(expr_t));

av_malloc()/av_free()

[...]


-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is




More information about the ffmpeg-devel mailing list