dvd-sector-copy.c: Change the moving-average denominator computation.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 9 Apr 2022 17:08:05 +0000 (18:08 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 9 Apr 2022 17:08:05 +0000 (18:08 +0100)
Rather than updating this using the geometric-series formula as before,
calculate it as (1 - β^t), incorporating the initial correction from
Wikipedia.  My testing suggests that this stabilizes rather more
quickly.

dvd-sector-copy.c

index b1ca133..d60e1c1 100644 (file)
@@ -226,7 +226,7 @@ static secaddr nsectors, ndone;
 static secaddr last_pos;
 static struct timeval last_time;
 static double alpha = 0.1;
-static double wsum, wcount;
+static double avg = 0.0, corr = 0.0;
 static int bad_err;
 
 static const char throbber[] = "|<-<|>->";
@@ -263,11 +263,10 @@ static void render_perfstats(struct progress_render_state *render)
   double rate;
   const char *unit;
 
-  if (!wsum || !wcount) { rate = 0; eta = -1; }
-  else { rate = wsum/wcount; eta = (int)((nsectors - ndone)/rate + 0.5); }
+  rate = avg/(1 - corr); eta = (int)((nsectors - ndone)/rate + 0.5);
 
   rate = scale_bytes(rate*SECTORSZ, &unit);
-  progress_putright(render, "ETA %s ", rate ? fmttime(eta, timebuf) : "???");
+  progress_putright(render, "ETA %s ", avg ? fmttime(eta, timebuf) : "???");
   progress_putright(render, "%.1f %sB/s, ", rate, unit);
 }
 
@@ -333,22 +332,14 @@ static void render_badblock_progress(struct progress_item *item,
 static void update_progress(secaddr pos)
 {
   struct timeval now;
-  double t, f, g;
+  double t, beta_t, rate;
 
   gettimeofday(&now, 0); t = tvdiff(&last_time, &now);
-
-#define BETA (1 - alpha)
-
   if (t) {
-    g = wcount ? pow(BETA, t) : 0.0; f = (1 - g)/(1 - BETA);
-    wsum = f*(pos - last_pos)/t + g*wsum;
-    wcount = f + g*wcount;
-    ndone += pos - last_pos;
-    last_time = now; last_pos = pos;
+    rate = (pos - last_pos)/t; beta_t = pow(1 - alpha, t);
+    avg = rate + beta_t*(avg - rate); corr *= beta_t;
+    ndone += pos - last_pos; last_time = now; last_pos = pos;
   }
-
-#undef BETA
-
   throbix++; if (!throbber[throbix]) throbix = 0;
 }