diff mbox series

[FFmpeg-devel] avutil/eval: Use better PRNG

Message ID 20240103222433.18444-1-michael@niedermayer.cc
State New
Headers show
Series [FFmpeg-devel] avutil/eval: Use better PRNG | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Michael Niedermayer Jan. 3, 2024, 10:24 p.m. UTC
This is the 64bit version of George Marsaglias KISS PRNG

Compared to the LCGs these produce much better quality numbers.
Compared to LFGs this needs less state. (our LFG has 224 byte
state for its 32bit version) this has 32byte state for the 64bit version
Also the initialization for our LFG is slower.
OTOH the LFG is probably faster.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavutil/eval.c             |  24 ++--
 libavutil/kiss_prng.h        |  64 +++++++++++
 tests/fate/libswresample.mak | 210 +++++++++++++++++------------------
 tests/ref/fate/eval          |   2 +-
 4 files changed, 184 insertions(+), 116 deletions(-)
 create mode 100644 libavutil/kiss_prng.h

Comments

Stefano Sabatini Jan. 3, 2024, 11:58 p.m. UTC | #1
On date Wednesday 2024-01-03 23:24:33 +0100, Michael Niedermayer wrote:
> This is the 64bit version of George Marsaglias KISS PRNG
> 
> Compared to the LCGs these produce much better quality numbers.
> Compared to LFGs this needs less state. (our LFG has 224 byte
> state for its 32bit version) this has 32byte state for the 64bit version
> Also the initialization for our LFG is slower.
> OTOH the LFG is probably faster.
> 
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavutil/eval.c             |  24 ++--
>  libavutil/kiss_prng.h        |  64 +++++++++++
>  tests/fate/libswresample.mak | 210 +++++++++++++++++------------------
>  tests/ref/fate/eval          |   2 +-
>  4 files changed, 184 insertions(+), 116 deletions(-)
>  create mode 100644 libavutil/kiss_prng.h
> 
> diff --git a/libavutil/eval.c b/libavutil/eval.c
> index 89c61ba4bf5..20b4719a75b 100644
> --- a/libavutil/eval.c
> +++ b/libavutil/eval.c
> @@ -33,6 +33,7 @@
>  #include "eval.h"
>  #include "ffmath.h"
>  #include "internal.h"
> +#include "kiss_prng.h"
>  #include "log.h"
>  #include "mathematics.h"
>  #include "time.h"
> @@ -55,7 +56,7 @@ typedef struct Parser {
>      void *log_ctx;
>  #define VARS 10
>      double *var;
> -    uint64_t *var_uint64;
> +    KISS64State *prng_state;
>  } Parser;
>  
>  static const AVClass eval_class = {
> @@ -174,7 +175,7 @@ struct AVExpr {
>      } a;
>      struct AVExpr *param[3];
>      double *var;
> -    uint64_t *var_uint64;
> +    KISS64State *prng_state;
>  };
>  
>  static double etime(double v)
> @@ -232,10 +233,13 @@ static double eval_expr(Parser *p, AVExpr *e)
>          }
>          case e_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;
> +            KISS64State *s = p->prng_state + idx;
> +            uint64_t r;
> +
> +            if (!s->y)
> +                init_random64(s, isnan(p->var[idx]) ? 0 : p->var[idx]);
> +            r = get_random64(s);

needs to be rebased after the randomi introduction (also looks like
an incremental patch on top of your previous patch)

>              p->var[idx]= r;
> -            p->var_uint64[idx]= r;
>              return e->value * (r * (1.0/UINT64_MAX));
>          }
>          case e_while: {
> @@ -324,7 +328,7 @@ static double eval_expr(Parser *p, AVExpr *e)
>                  case e_last:return e->value * d2;
>                  case e_st :  {
>                      int index = av_clip(d, 0, VARS-1);
> -                    p->var_uint64[index] = 0;
> +                    p->prng_state[index].y = 0;
>                      return e->value * (p->var[index]= d2);
>                  }
>                  case e_hypot:return e->value * hypot(d, d2);
> @@ -346,7 +350,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);
>  }
>  
> @@ -732,8 +736,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;
>      }
> @@ -775,7 +779,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/kiss_prng.h b/libavutil/kiss_prng.h
> new file mode 100644
> index 00000000000..fb3941b5df5
> --- /dev/null
> +++ b/libavutil/kiss_prng.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2008,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
> + *
> + * 64-bit PRNG by George Marsaglia https://www.thecodingforums.com/threads/64-bit-kiss-rngs.673657/
> + *
> + */
> +
> +/**
> + * @file
> + * simple Pseudo Random Number Generator
> + *
> + * The implementation was verified to match the value after 100 milllion iterations
> + */
> +
> +#ifndef AVUTIL_KISS_PRNG_H
> +#define AVUTIL_KISS_PRNG_H
> +
> +#include <inttypes.h>
> +

> +typedef struct KISS64State{
> +    uint64_t x,y,z,c;
> +}KISS64State;

missing namespace here and in the functions below.

For this you could probably use AVKISS64PRNG (or AVKISS64), and use
av_kiss64prng_ or av_kiss64_ as function prefix (I'd probably go with
the shortest variant).

> +
> +static inline uint64_t get_random64(KISS64State *s){

av_kiss64_get() ?

> +    uint64_t
> +       t = (s->x << 58) + s->c;
> +    s->c =  s->x >> 6;
> +    s->x+= t;
> +    s->c+= s->x < t;
> +
> +    s->y ^= s->y << 13;
> +    s->y ^= s->y >> 17;
> +    s->y ^= s->y << 43;
> +
> +    s->z = 1234567 + 6906969069LL * s->z;
> +
> +    return s->x + s->y + s->z;
> +}
> +
> +static inline void init_random64(KISS64State *s, uint64_t seed){

av_kiss64_init() ?

to make it consistent with the av_lfg API.

> +    //Constants based on SHA512 of "FFmpeg" and Marsaglias values so seed=0 matches his
> +    s->x = 1234567890987654321ULL ^ seed;
> +    s->y =( 362436362436362436ULL ^ (0xd255973df01e5086*seed)) | 4;
> +    s->z =    1066149217761810ULL + seed;
> +    s->c =  123456123456123456ULL -  0x33730c0524f137da*seed;
> +}
> +
> +#endif /* AVUTIL_KISS__PRNGH */
> diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
> index 0d29f760248..ea421d45fb6 100644
> --- a/tests/fate/libswresample.mak
> +++ b/tests/fate/libswresample.mak
> @@ -359,7 +359,7 @@ fate-swr-resample_nn-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480
>  define ARESAMPLE_ASYNC
>  FATE_SWR_RESAMPLE += fate-swr-resample_async-$(3)-$(1)-$(2)
>  fate-swr-resample_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
> -fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -
> +fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(1\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -

any reason to change the random() index?

[...]  
>  Evaluating '7000000B*random(0)'
> -'7000000B*random(0)' -> 0.003078
> +'7000000B*random(0)' -> 27118453.055396

unrelated comment: we might provide a better example/reference here
James Almer Jan. 4, 2024, 12:02 a.m. UTC | #2
On 1/3/2024 8:58 PM, Stefano Sabatini wrote:
> missing namespace here and in the functions below.
> 
> For this you could probably use AVKISS64PRNG (or AVKISS64), and use
> av_kiss64prng_ or av_kiss64_ as function prefix (I'd probably go with
> the shortest variant).

It's not an installed header, so FF and ff_ if anything.
Michael Niedermayer Jan. 4, 2024, 3:19 a.m. UTC | #3
On Thu, Jan 04, 2024 at 12:58:43AM +0100, Stefano Sabatini wrote:
> On date Wednesday 2024-01-03 23:24:33 +0100, Michael Niedermayer wrote:

[...]

> 
> > +typedef struct KISS64State{
> > +    uint64_t x,y,z,c;
> > +}KISS64State;
> 
> missing namespace here and in the functions below.
> 
> For this you could probably use AVKISS64PRNG (or AVKISS64), and use
> av_kiss64prng_ or av_kiss64_ as function prefix (I'd probably go with
> the shortest variant).
> 
> > +
> > +static inline uint64_t get_random64(KISS64State *s){
> 
> av_kiss64_get() ?

as its not a public API yet, ill leave the av_ out but will
switch to your names, they are nice and short



[...]
> 
> > +    //Constants based on SHA512 of "FFmpeg" and Marsaglias values so seed=0 matches his
> > +    s->x = 1234567890987654321ULL ^ seed;
> > +    s->y =( 362436362436362436ULL ^ (0xd255973df01e5086*seed)) | 4;
> > +    s->z =    1066149217761810ULL + seed;
> > +    s->c =  123456123456123456ULL -  0x33730c0524f137da*seed;
> > +}
> > +
> > +#endif /* AVUTIL_KISS__PRNGH */
> > diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
> > index 0d29f760248..ea421d45fb6 100644
> > --- a/tests/fate/libswresample.mak
> > +++ b/tests/fate/libswresample.mak
> > @@ -359,7 +359,7 @@ fate-swr-resample_nn-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480
> >  define ARESAMPLE_ASYNC
> >  FATE_SWR_RESAMPLE += fate-swr-resample_async-$(3)-$(1)-$(2)
> >  fate-swr-resample_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
> > -fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -
> > +fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(1\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -
> 
> any reason to change the random() index?

yes because i forgot removing that hunk. That was not intended to be in the
patch

[....]
diff mbox series

Patch

diff --git a/libavutil/eval.c b/libavutil/eval.c
index 89c61ba4bf5..20b4719a75b 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -33,6 +33,7 @@ 
 #include "eval.h"
 #include "ffmath.h"
 #include "internal.h"
+#include "kiss_prng.h"
 #include "log.h"
 #include "mathematics.h"
 #include "time.h"
@@ -55,7 +56,7 @@  typedef struct Parser {
     void *log_ctx;
 #define VARS 10
     double *var;
-    uint64_t *var_uint64;
+    KISS64State *prng_state;
 } Parser;
 
 static const AVClass eval_class = {
@@ -174,7 +175,7 @@  struct AVExpr {
     } a;
     struct AVExpr *param[3];
     double *var;
-    uint64_t *var_uint64;
+    KISS64State *prng_state;
 };
 
 static double etime(double v)
@@ -232,10 +233,13 @@  static double eval_expr(Parser *p, AVExpr *e)
         }
         case e_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;
+            KISS64State *s = p->prng_state + idx;
+            uint64_t r;
+
+            if (!s->y)
+                init_random64(s, isnan(p->var[idx]) ? 0 : p->var[idx]);
+            r = get_random64(s);
             p->var[idx]= r;
-            p->var_uint64[idx]= r;
             return e->value * (r * (1.0/UINT64_MAX));
         }
         case e_while: {
@@ -324,7 +328,7 @@  static double eval_expr(Parser *p, AVExpr *e)
                 case e_last:return e->value * d2;
                 case e_st :  {
                     int index = av_clip(d, 0, VARS-1);
-                    p->var_uint64[index] = 0;
+                    p->prng_state[index].y = 0;
                     return e->value * (p->var[index]= d2);
                 }
                 case e_hypot:return e->value * hypot(d, d2);
@@ -346,7 +350,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);
 }
 
@@ -732,8 +736,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;
     }
@@ -775,7 +779,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/kiss_prng.h b/libavutil/kiss_prng.h
new file mode 100644
index 00000000000..fb3941b5df5
--- /dev/null
+++ b/libavutil/kiss_prng.h
@@ -0,0 +1,64 @@ 
+/*
+ * Copyright (c) 2008,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
+ *
+ * 64-bit PRNG by George Marsaglia https://www.thecodingforums.com/threads/64-bit-kiss-rngs.673657/
+ *
+ */
+
+/**
+ * @file
+ * simple Pseudo Random Number Generator
+ *
+ * The implementation was verified to match the value after 100 milllion iterations
+ */
+
+#ifndef AVUTIL_KISS_PRNG_H
+#define AVUTIL_KISS_PRNG_H
+
+#include <inttypes.h>
+
+typedef struct KISS64State{
+    uint64_t x,y,z,c;
+}KISS64State;
+
+static inline uint64_t get_random64(KISS64State *s){
+    uint64_t
+       t = (s->x << 58) + s->c;
+    s->c =  s->x >> 6;
+    s->x+= t;
+    s->c+= s->x < t;
+
+    s->y ^= s->y << 13;
+    s->y ^= s->y >> 17;
+    s->y ^= s->y << 43;
+
+    s->z = 1234567 + 6906969069LL * s->z;
+
+    return s->x + s->y + s->z;
+}
+
+static inline void init_random64(KISS64State *s, uint64_t seed){
+    //Constants based on SHA512 of "FFmpeg" and Marsaglias values so seed=0 matches his
+    s->x = 1234567890987654321ULL ^ seed;
+    s->y =( 362436362436362436ULL ^ (0xd255973df01e5086*seed)) | 4;
+    s->z =    1066149217761810ULL + seed;
+    s->c =  123456123456123456ULL -  0x33730c0524f137da*seed;
+}
+
+#endif /* AVUTIL_KISS__PRNGH */
diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
index 0d29f760248..ea421d45fb6 100644
--- a/tests/fate/libswresample.mak
+++ b/tests/fate/libswresample.mak
@@ -359,7 +359,7 @@  fate-swr-resample_nn-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480
 define ARESAMPLE_ASYNC
 FATE_SWR_RESAMPLE += fate-swr-resample_async-$(3)-$(1)-$(2)
 fate-swr-resample_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
-fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -
+fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(1\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -c:a pcm_s16le -
 
 fate-swr-resample_async-$(3)-$(1)-$(2): CMP = stddev
 fate-swr-resample_async-$(3)-$(1)-$(2): CMP_UNIT = $(5)
@@ -367,17 +367,17 @@  fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.1
 fate-swr-resample_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav
 endef
 
-fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 4020.60
-fate-swr-resample_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 2311.87
+fate-swr-resample_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 11186.66
-fate-swr-resample_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 8806.69
+fate-swr-resample_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 4020.71
-fate-swr-resample_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 2311.94
+fate-swr-resample_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 11186.94
-fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 8806.88
+fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
 define ARESAMPLE_EXACT
 FATE_SWR_RESAMPLE += fate-swr-resample_exact-$(3)-$(1)-$(2)
@@ -641,77 +641,77 @@  fate-swr-resample_exact_async-$(3)-$(1)-$(2): FUZZ = 0.1
 fate-swr-resample_exact_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav
 endef
 
-fate-swr-resample_exact_async-dblp-44100-48000: CMP_TARGET = 7791.50
-fate-swr-resample_exact_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_async-dblp-44100-48000: CMP_TARGET = 2300.82
+fate-swr-resample_exact_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_async-dblp-44100-8000: CMP_TARGET = 4022.87
-fate-swr-resample_exact_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_async-dblp-44100-8000: CMP_TARGET = 2310.06
+fate-swr-resample_exact_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_async-dblp-48000-44100: CMP_TARGET = 1923.97
-fate-swr-resample_exact_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_async-dblp-48000-44100: CMP_TARGET = 1923.17
+fate-swr-resample_exact_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_async-dblp-48000-8000: CMP_TARGET = 2592.00
-fate-swr-resample_exact_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_async-dblp-48000-8000: CMP_TARGET = 1892.12
+fate-swr-resample_exact_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_async-dblp-8000-44100: CMP_TARGET = 11187.24
-fate-swr-resample_exact_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-dblp-8000-44100: CMP_TARGET = 8806.68
+fate-swr-resample_exact_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-dblp-8000-48000: CMP_TARGET = 11326.80
-fate-swr-resample_exact_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-dblp-8000-48000: CMP_TARGET = 8806.93
+fate-swr-resample_exact_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-fltp-44100-48000: CMP_TARGET = 7791.50
-fate-swr-resample_exact_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_async-fltp-44100-48000: CMP_TARGET = 2300.82
+fate-swr-resample_exact_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_async-fltp-44100-8000: CMP_TARGET = 4022.87
-fate-swr-resample_exact_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_async-fltp-44100-8000: CMP_TARGET = 2310.06
+fate-swr-resample_exact_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_async-fltp-48000-44100: CMP_TARGET = 1923.97
-fate-swr-resample_exact_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_async-fltp-48000-44100: CMP_TARGET = 1923.17
+fate-swr-resample_exact_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_async-fltp-48000-8000: CMP_TARGET = 2592.00
-fate-swr-resample_exact_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_async-fltp-48000-8000: CMP_TARGET = 1892.12
+fate-swr-resample_exact_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_async-fltp-8000-44100: CMP_TARGET = 11187.24
-fate-swr-resample_exact_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-fltp-8000-44100: CMP_TARGET = 8806.68
+fate-swr-resample_exact_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-fltp-8000-48000: CMP_TARGET = 11326.80
-fate-swr-resample_exact_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-fltp-8000-48000: CMP_TARGET = 8806.93
+fate-swr-resample_exact_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-s16p-44100-48000: CMP_TARGET = 7791.50
-fate-swr-resample_exact_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_async-s16p-44100-48000: CMP_TARGET = 2300.80
+fate-swr-resample_exact_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_async-s16p-44100-8000: CMP_TARGET = 4023.05
-fate-swr-resample_exact_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_async-s16p-44100-8000: CMP_TARGET = 2310.13
+fate-swr-resample_exact_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_async-s16p-48000-44100: CMP_TARGET = 1923.96
-fate-swr-resample_exact_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_async-s16p-48000-44100: CMP_TARGET = 1923.19
+fate-swr-resample_exact_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_async-s16p-48000-8000: CMP_TARGET = 2592.15
-fate-swr-resample_exact_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_async-s16p-48000-8000: CMP_TARGET = 1892.21
+fate-swr-resample_exact_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_async-s16p-8000-44100: CMP_TARGET = 11187.58
-fate-swr-resample_exact_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-s16p-8000-44100: CMP_TARGET = 8806.89
+fate-swr-resample_exact_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-s16p-8000-48000: CMP_TARGET = 11327.48
-fate-swr-resample_exact_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-s16p-8000-48000: CMP_TARGET = 8807.32
+fate-swr-resample_exact_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-s32p-44100-48000: CMP_TARGET = 7791.50
-fate-swr-resample_exact_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_async-s32p-44100-48000: CMP_TARGET = 2300.81
+fate-swr-resample_exact_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_async-s32p-44100-8000: CMP_TARGET = 4022.87
-fate-swr-resample_exact_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_async-s32p-44100-8000: CMP_TARGET = 2310.06
+fate-swr-resample_exact_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.96
-fate-swr-resample_exact_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.19
+fate-swr-resample_exact_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_async-s32p-48000-8000: CMP_TARGET = 2592.00
-fate-swr-resample_exact_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_async-s32p-48000-8000: CMP_TARGET = 1892.13
+fate-swr-resample_exact_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_async-s32p-8000-44100: CMP_TARGET = 11187.24
-fate-swr-resample_exact_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-s32p-8000-44100: CMP_TARGET = 8806.68
+fate-swr-resample_exact_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 11326.79
-fate-swr-resample_exact_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 8806.94
+fate-swr-resample_exact_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
 define ARESAMPLE_EXACT_LIN
 FATE_SWR_RESAMPLE += fate-swr-resample_exact_lin-$(3)-$(1)-$(2)
@@ -975,77 +975,77 @@  fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2): FUZZ = 0.1
 fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav
 endef
 
-fate-swr-resample_exact_lin_async-dblp-44100-48000: CMP_TARGET = 7791.72
-fate-swr-resample_exact_lin_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_lin_async-dblp-44100-48000: CMP_TARGET = 2300.45
+fate-swr-resample_exact_lin_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_lin_async-dblp-44100-8000: CMP_TARGET = 4023.01
-fate-swr-resample_exact_lin_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_lin_async-dblp-44100-8000: CMP_TARGET = 2309.71
+fate-swr-resample_exact_lin_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_lin_async-dblp-48000-44100: CMP_TARGET = 1923.79
-fate-swr-resample_exact_lin_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_lin_async-dblp-48000-44100: CMP_TARGET = 1922.82
+fate-swr-resample_exact_lin_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_lin_async-dblp-48000-8000: CMP_TARGET = 2591.72
-fate-swr-resample_exact_lin_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_lin_async-dblp-48000-8000: CMP_TARGET = 1891.82
+fate-swr-resample_exact_lin_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 11187.24
-fate-swr-resample_exact_lin_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 8807.02
+fate-swr-resample_exact_lin_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-dblp-8000-48000: CMP_TARGET = 11326.80
-fate-swr-resample_exact_lin_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-dblp-8000-48000: CMP_TARGET = 8807.22
+fate-swr-resample_exact_lin_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-fltp-44100-48000: CMP_TARGET = 7791.72
-fate-swr-resample_exact_lin_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_lin_async-fltp-44100-48000: CMP_TARGET = 2300.45
+fate-swr-resample_exact_lin_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_lin_async-fltp-44100-8000: CMP_TARGET = 4023.01
-fate-swr-resample_exact_lin_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_lin_async-fltp-44100-8000: CMP_TARGET = 2309.71
+fate-swr-resample_exact_lin_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_lin_async-fltp-48000-44100: CMP_TARGET = 1923.79
-fate-swr-resample_exact_lin_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_lin_async-fltp-48000-44100: CMP_TARGET = 1922.82
+fate-swr-resample_exact_lin_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_lin_async-fltp-48000-8000: CMP_TARGET = 2591.72
-fate-swr-resample_exact_lin_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_lin_async-fltp-48000-8000: CMP_TARGET = 1891.82
+fate-swr-resample_exact_lin_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_lin_async-fltp-8000-44100: CMP_TARGET = 11187.25
-fate-swr-resample_exact_lin_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-fltp-8000-44100: CMP_TARGET = 8807.02
+fate-swr-resample_exact_lin_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-fltp-8000-48000: CMP_TARGET = 11326.80
-fate-swr-resample_exact_lin_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-fltp-8000-48000: CMP_TARGET = 8807.22
+fate-swr-resample_exact_lin_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-s16p-44100-48000: CMP_TARGET = 7791.72
-fate-swr-resample_exact_lin_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_lin_async-s16p-44100-48000: CMP_TARGET = 2300.45
+fate-swr-resample_exact_lin_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_lin_async-s16p-44100-8000: CMP_TARGET = 4023.19
-fate-swr-resample_exact_lin_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_lin_async-s16p-44100-8000: CMP_TARGET = 2309.79
+fate-swr-resample_exact_lin_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_lin_async-s16p-48000-44100: CMP_TARGET = 1923.79
-fate-swr-resample_exact_lin_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_lin_async-s16p-48000-44100: CMP_TARGET = 1922.83
+fate-swr-resample_exact_lin_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_lin_async-s16p-48000-8000: CMP_TARGET = 2591.85
-fate-swr-resample_exact_lin_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_lin_async-s16p-48000-8000: CMP_TARGET = 1891.90
+fate-swr-resample_exact_lin_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_lin_async-s16p-8000-44100: CMP_TARGET = 11187.57
-fate-swr-resample_exact_lin_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-s16p-8000-44100: CMP_TARGET = 8807.23
+fate-swr-resample_exact_lin_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-s16p-8000-48000: CMP_TARGET = 11327.48
-fate-swr-resample_exact_lin_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-s16p-8000-48000: CMP_TARGET = 8807.62
+fate-swr-resample_exact_lin_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-s32p-44100-48000: CMP_TARGET = 7791.72
-fate-swr-resample_exact_lin_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300
+fate-swr-resample_exact_lin_async-s32p-44100-48000: CMP_TARGET = 2300.46
+fate-swr-resample_exact_lin_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20488
 
-fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 4023.02
-fate-swr-resample_exact_lin_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
+fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 2309.71
+fate-swr-resample_exact_lin_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
 
-fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1923.77
-fate-swr-resample_exact_lin_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298
+fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1922.82
+fate-swr-resample_exact_lin_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20486
 
-fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 2591.71
-fate-swr-resample_exact_lin_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304
+fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 1891.82
+fate-swr-resample_exact_lin_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
 
-fate-swr-resample_exact_lin_async-s32p-8000-44100: CMP_TARGET = 11187.25
-fate-swr-resample_exact_lin_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-s32p-8000-44100: CMP_TARGET = 8807.02
+fate-swr-resample_exact_lin_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20486
 
-fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 11326.81
-fate-swr-resample_exact_lin_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344
+fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 8807.23
+fate-swr-resample_exact_lin_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20486
 
 $(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s16p,s16le,s16)
 $(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s32p,s32le,s16)
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
index 5b4d93f4274..e50f77a9c5e 100644
--- a/tests/ref/fate/eval
+++ b/tests/ref/fate/eval
@@ -257,7 +257,7 @@  Evaluating 'root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)'
 'root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)' -> 60.965601
 
 Evaluating '7000000B*random(0)'
-'7000000B*random(0)' -> 0.003078
+'7000000B*random(0)' -> 27118453.055396
 
 Evaluating 'squish(2)'
 'squish(2)' -> 0.000335