Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Michael Niedermayer <michael@niedermayer.cc>
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH] avutil/eval: Use even better PRNG
Date: Thu, 11 Jan 2024 03:39:27 +0100
Message-ID: <20240111023927.GV6420@pb2> (raw)
In-Reply-To: <ZZ8ewWOmHHg97hjx@mariano>


[-- Attachment #1.1: Type: text/plain, Size: 5653 bytes --]

On Wed, Jan 10, 2024 at 11:48:33PM +0100, Stefano Sabatini wrote:
> On date Tuesday 2024-01-09 02:55:21 +0100, Michael Niedermayer wrote:
[...]

> >  
> >  static const AVClass eval_class = {
> > @@ -174,7 +175,7 @@ struct AVExpr {
> >      } a;
> >      struct AVExpr *param[3];
> >      double *var;
> > -    uint64_t *var_uint64;
> > +    SFC64 *prng_state;
> >  };
> >  
> >  static double etime(double v)
> > @@ -233,10 +234,15 @@ static double eval_expr(Parser *p, AVExpr *e)
> >  
> >  #define COMPUTE_NEXT_RANDOM()                                        \
> >              int idx = av_clip(eval_expr(p, e->param[0]), 0, VARS-1); \
> > -            uint64_t r = p->var_uint64[idx] ? p->var_uint64[idx] : (isnan(p->var[idx]) ? 0 : p->var[idx]);\
> > -            r = r * 1664525 + 1013904223;                            \
> > +            SFC64 *s = p->prng_state + idx;                          \
> > +            uint64_t r;                                              \
> > +                                                                     \
> > +            if (!s->counter) {                                       \
> > +                r = isnan(p->var[idx]) ? 0 : p->var[idx];            \
> 
> > +                sfc64_init(s, r, r, r, 12);                          \
> 
> for the record, why 12?

The reference has 3 init functions
* one that uses one seed for the 3 parameters, it uses 12 rounds
* one that uses 3 seperate seeds that uses 18 rounds
* one that has "fast" in its name and does 8 rounds with one seed in 3 parameters

I will document this better


[...]
> >                      return e->value * (p->var[index]= d2);
> >                  }
> >                  case e_hypot:return e->value * hypot(d, d2);
> > @@ -356,7 +362,7 @@ void av_expr_free(AVExpr *e)
> >      av_expr_free(e->param[1]);
> >      av_expr_free(e->param[2]);
> >      av_freep(&e->var);
> > -    av_freep(&e->var_uint64);
> > +    av_freep(&e->prng_state);
> >      av_freep(&e);
> >  }
> >  
> > @@ -744,8 +750,8 @@ int av_expr_parse(AVExpr **expr, const char *s,
> >          goto end;
> >      }
> >      e->var= av_mallocz(sizeof(double) *VARS);
> > -    e->var_uint64= av_mallocz(sizeof(uint64_t) *VARS);
> > -    if (!e->var || !e->var_uint64) {
> > +    e->prng_state = av_mallocz(sizeof(*e->prng_state) *VARS);
> > +    if (!e->var || !e->prng_state) {
> >          ret = AVERROR(ENOMEM);
> >          goto end;
> >      }
> > @@ -787,7 +793,7 @@ double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
> >  {
> >      Parser p = { 0 };
> >      p.var= e->var;
> > -    p.var_uint64= e->var_uint64;
> > +    p.prng_state= e->prng_state;
> >  
> >      p.const_values = const_values;
> >      p.opaque     = opaque;
> > diff --git a/libavutil/sfc64.h b/libavutil/sfc64.h
> > new file mode 100644
> > index 00000000000..25bc43abef1
> > --- /dev/null
> > +++ b/libavutil/sfc64.h
> > @@ -0,0 +1,59 @@
> > +/*
> > + * Copyright (c) 2024 Michael Niedermayer <michael-ffmpeg@niedermayer.cc>
> > + *
> > + * This file is part of FFmpeg.
> > + *
> > + * FFmpeg is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * FFmpeg is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with FFmpeg; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> > + *
> 
> > + * This is a implementation of SFC64 a 64-bit PRNG by Chris Doty-Humphrey.
> 
> nit: This is a implementation of SFC64, a 64-bit PRNG by Chris Doty-Humphrey.
> 

> > + *
> > + * This Generator is much faster (0m1.872s) than 64bit KISS (0m3.823s) and PCG-XSH-RR-64/32 (0m2.700s)
> 
> what are these benchmarks against?

a loop that computes alot of random numbers and at the end prints their sum.

The behavior was btw quite different if the numbers are not summed and printed
as the compiler can then optimize some things out but noone would run a PRNG
and not use the values.


[...]
> > +static inline uint64_t sfc64_get(SFC64 *s) {
> > +    uint64_t tmp = s->a + s->b + s->counter++;
> > +    s->a = s->b ^ (s->b >> 11);
> > +    s->b = s->c + (s->c << 3); // This is a multiply by 9
> > +    s->c = ((s->c << 24) | (s->c >> 40)) + tmp;
> > +    return tmp;
> > +}
> > +
> > +static inline void sfc64_init(SFC64 *s, uint64_t seeda, uint64_t seedb, uint64_t seedc, int rounds) {
> > +    s->a       = seeda;
> > +    s->b       = seedb;
> > +    s->c       = seedc;
> > +    s->counter = 1;
> > +    while (rounds--)
> > +        sfc64_get(s);
> > +}
> > +
> > +#endif // AVUTIL_SFC64_H
> 
> nit: probably it still makes sense to use ff/FF prefixes even if the
> header is not public (and if this is useful, probably it could be made
> public as a faster/smaller alternative to lfg).

ok

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Take away the freedom of one citizen and you will be jailed, take away
the freedom of all citizens and you will be congratulated by your peers
in Parliament.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2024-01-11  2:39 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-09  1:55 Michael Niedermayer
2024-01-10 22:48 ` Stefano Sabatini
2024-01-11  2:39   ` Michael Niedermayer [this message]
2024-01-19  8:53 ` Michael Koch
2024-01-20  0:33   ` Michael Niedermayer
2024-01-13  3:51 Michael Niedermayer
2024-01-14 14:14 ` Stefano Sabatini
2024-01-16  0:27   ` Michael Niedermayer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240111023927.GV6420@pb2 \
    --to=michael@niedermayer.cc \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git