[xiph-commits] r15249 - trunk/cdparanoia/paranoia

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Thu Sep 4 07:02:56 PDT 2008


Author: xiphmont
Date: 2008-09-04 07:02:55 -0700 (Thu, 04 Sep 2008)
New Revision: 15249

Modified:
   trunk/cdparanoia/paranoia/cachetest.c
Log:
Don't use this one.


Modified: trunk/cdparanoia/paranoia/cachetest.c
===================================================================
--- trunk/cdparanoia/paranoia/cachetest.c	2008-09-03 22:41:05 UTC (rev 15248)
+++ trunk/cdparanoia/paranoia/cachetest.c	2008-09-04 14:02:55 UTC (rev 15249)
@@ -29,13 +29,90 @@
 #define printC(...) {if(progress){fprintf(progress, __VA_ARGS__);}}
 #define logC(...) {if(log){fprintf(log, __VA_ARGS__);}}
 
-static float ms_per_sector_at(int lba, float *waypoint){
-  int waypos = (lba+44999)/45000;
-  if(waypos<0)waypos=0;
-  while(waypos>=0 && waypoint[waypos]==-1)waypoint--;
-  return waypoint[waypos];
+static int time_drive(cdrom_drive *d, FILE *progress, FILE *log, int lba, int len){
+  int i,j,x;
+  int latency[len];
+  int sectors[len];
+  double sum=0;
+  double sumsq=0;
+  int sofar;
+  int ret;
+
+  logC("\n");
+  
+  for(i=0,sofar=0;sofar<len;i++){
+    int toread = (i==0?1:len-sofar);
+    int ret;
+    /* first read should also trigger a short seek; one sector so seek duration dominates */
+    if((ret=cdda_read(d,NULL,lba+sofar,toread))<=0){
+      /* media error! grr!  retry elsewhere */
+      if(ret==-404)return -404;
+      return -1;
+    }
+
+    x = cdda_milliseconds(d);
+    if(x>9999)x=9999;
+    if(x<0)x=0;
+    logC("%d:%d ",ret,x);
+    
+    latency[i]=x;
+    sectors[i]=ret;
+    sofar+=ret;
+    if(i){
+      sum+=x;
+      sumsq+= x*x /(float)ret;
+    }
+  }
+  
+  /* ignore upper outliers; we may have gotten random bursts of latency */
+  {
+    double mean = sum/(float)(len-1);
+    double stddev = sqrt( (sumsq/(float)(len-1) - mean*mean));
+    double upper= mean+((isnan(stddev) || stddev*2<1.)?1.:stddev*2);
+    int ms=0;
+
+    mean=0;
+    sofar=0;
+    for(j=1;j<i;j++){
+      double per = latency[j]/(double)sectors[j];
+      if(per<=upper){
+	ms+=latency[j];
+	sofar+=sectors[j];
+      }
+    }
+    mean=ms/(double)sofar;
+    
+    printC("%4dms seek, %.2fms/sec read [%.1fx]",latency[0],mean,1000./75./mean);
+    logC("\n\tInitial seek latency (%d sectors): %dms",len,latency[0]);
+    logC("\n\tAverage read latency: %.2fms/sector (raw speed: %.1fx)",mean,1000./75./mean);
+    logC("\n\tRead latency standard deviation: %.2fms/sector",stddev);
+    
+    return (int)rint(mean*sofar);
+  }
 }
 
+static float retime_drive(cdrom_drive *d, FILE *progress, FILE *log, int lba, int readahead, float oldmean){
+  int sectors = 2000;
+  int total;
+  float newmean;
+  if(sectors*oldmean > 5000) sectors=5000/oldmean;
+  readahead*=10;
+  readahead/=9;
+  if(readahead>sectors)sectors=readahead;
+
+  printC("\bo");
+  logC("\n\tRetiming drive...                               ");
+  
+  total = time_drive(d,NULL,log,lba,sectors);
+  newmean = total/(float)sectors;
+
+  logC("\n\tOld mean=%.2fms/sec, New mean=%.2fms/sec\n",oldmean,newmean);
+  printC("\b");
+
+  if(newmean>oldmean)return newmean;
+  return oldmean;
+}
+
 int paranoia_analyze_verify(cdrom_drive *d, FILE *progress, FILE *log){
 
   /* Some assumptions about timing: 
@@ -77,14 +154,10 @@
   int readahead;
   int rollbehind;
   int cachegran;
-  float waypoint[10]={-1,-1,-1,-1, -1,-1,-1,-1, -1,-1};
   int speed = cdda_speed_get(d);
+  float mspersector;
   if(speed<=0)speed=-1;
 
-  /* set up a default pessimal take on drive behavior */
-  //d->private->cache_backseekflush=0;
-  //d->private->cache_sectors=1200;
-
   reportC("\n=================== Checking drive cache/timing behavior ===================\n");
   d->error_retry=0;
 
@@ -113,12 +186,6 @@
   /* Dump some initial timing data to give a little context for human
      eyes.  Take readings ten minutes apart (45000 sectors) and at end of disk. */
   {
-    int x;
-    int latency[current];
-    int sectors[current];
-    double sum;
-    double sumsq;
-    int sofar;
     int best=0;
     int bestcount=0;
     int iterating=0;
@@ -131,6 +198,8 @@
       int m = offset/4500;
       int s = (offset-m*4500)/75;
       int f = offset-m*4500-s*75;
+      int sofar;
+
       if(iterating){
 	reportC("\n");
       }else{
@@ -138,73 +207,27 @@
 	logC("\n");
       }
       reportC("\t[%02d:%02d.%02d]: ",m,s,f);
-      sum=0;
-      sumsq=0;
 
       /* initial seek to put at at a small offset past end of upcoming reads */
       if((ret=cdda_read(d,NULL,offset+current+1,1))<0){
 	/* media error! grr!  retry elsewhere */
 	if(ret==-404)return -1;
-	reportC("\n\tWARNING: media error during setup; continuing at next offset...");
-	goto next;
+	reportC("\n\tWARNING: media error during read; continuing at next offset...");
+	offset = (offset-firstsector+44999)/45000*45000+firstsector;
+	offset-=45000;
+	continue;
       }
-
-      logC("\n");
-      
-      for(i=0,sofar=0;sofar<current;i++){
-	int toread = (i==0?1:current-sofar);
-	int ret;
-	/* first read should also trigger a short seek; one sector so seek duration dominates */
-	if((ret=cdda_read(d,NULL,offset+sofar,toread))<=0){
-	  /* media error! grr!  retry elsewhere */
-	if(ret==-404)return -1;
-	  reportC("\n\tWARNING: media error during read; continuing at next offset...");
-	  goto next;
-	}
-
-	x = cdda_milliseconds(d);
-	if(x>9999)x=9999;
-	if(x<0)x=0;
-	logC("%d:%d ",ret,x);
-
-	latency[i]=x;
-	sectors[i]=ret;
-	sofar+=ret;
-	if(i){
-	  sum+=x;
-	  sumsq+= x*x /(float)ret;
-	}
-      }
-      
-      /* ignore upper outliers; we may have gotten random bursts of latency */
-      {
-	double mean = sum/(float)(current-1);
-	double stddev = sqrt( (sumsq/(float)(current-1) - mean*mean));
-	double upper= mean+((isnan(stddev) || stddev*2<1.)?1.:stddev*2);
-	
-	mean=0;
-	sofar=0;
-	for(j=1;j<i;j++){
-	  double per = latency[j]/(double)sectors[j];
-	  if(per<=upper){
-	    mean+=latency[j];
-	    sofar+=sectors[j];
-	  }
-	}
-	mean/=sofar;
-	
-	{
-	  int waypos = offset/45000;
-	  if(waypoint[waypos]==-1 || waypoint[waypos]>mean)
-	    waypoint[waypos]=mean;
-	}
-
-	printC("%4dms seek, %.2fms/sec read [%.1fx]",latency[0],mean,1000./75./mean);
-	logC("\n\tInitial seek latency (%d sectors): %dms",current,latency[0]);
-	logC("\n\tAverage read latency: %.2fms/sector (raw speed: %.1fx)",mean,1000./75./mean);
-	logC("\n\tRead latency standard deviation: %.2fms/sector",stddev);
-
-	sofar=mean*current;
+  
+      sofar=time_drive(d,progress, log, offset, current);
+      if(offset==firstsector)mspersector = sofar/(float)current;
+      if(sofar==-404)
+	return -1;
+      else if(sofar<0){
+	reportC("\n\tWARNING: media error during read; continuing at next offset...");
+	offset = (offset-firstsector+44999)/45000*45000+firstsector;
+	offset-=45000;
+	continue;
+      }else{
 	if(!iterating){
 	  if(best==0 || sofar*1.01<best){
 	    best= sofar;
@@ -361,25 +384,37 @@
   */
 
   {
-    int upper=hi;
     int lower=0;
     int gran=64;
+    int it=2;
+    int tests=0;
+    int under=1;
     readahead=0;
     
-    while(lower+1<upper){
-      int under=0;
-      if(lower+gran>=upper)
+    while(gran>1 || under){
+      tests++;
+      if(tests>8 && gran<64){
+	gran<<=3;
+	tests=0;
+	it=2;
+      }
+      if(gran && !under){
 	gran>>=3;
-      
+	tests=0;
+	if(gran==1)it=10;
+      }
+
+      under=0;
       readahead=lower+gran;
 
       printC("\r");
-      printC("\tTesting background readahead past read cursor... %d/%d",lower,readahead);
+      logC("\n");
+      reportC("\tTesting background readahead past read cursor... %d",readahead);
       printC("           \b\b\b\b\b\b\b\b\b\b\b");
-      for(i=0;i<10;i++){
+      for(i=0;i<it;i++){
 	int sofar=0,ret,retry=0;
 	logC("\n\t\t%d >>> ",i);
-	
+
 	while(sofar<cachesize){
 	  ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
 	  if(ret<=0)goto error;
@@ -393,9 +428,13 @@
 	  sofar+=ret;
 	}
 	
-	/* Pause 5x what we'd predict is needed to let the readahead process work. */
+	printC(".");
+
+	/* what we'd predict is needed to let the readahead process work. */
 	{
-	  int usec=ms_per_sector_at(offset,waypoint)*(readahead)*(4+i)*500;
+	  int usec=mspersector*(readahead)*(2+i)*1000;
+	  int max= 13000*2*readahead; /* corresponds to .5x */
+	  if(usec>max)usec=max;
 	  logC("sleep=%dus ",usec);
 	  usleep(usec);
 	}
@@ -403,19 +442,19 @@
 	/* seek to offset+cachesize+readahead */
 	ret = cdda_read(d,NULL,offset+cachesize+readahead-1,1);
 	if(ret<=0)break;
-	logC("ahead=%d:%d\n",readahead,cdda_milliseconds(d));
+	logC("ahead=%d:%d",readahead,cdda_milliseconds(d));
 	if(cdda_milliseconds(d)<9){
 	  under=1;
 	  break;
+	}else if(i&1){
+	  /* retime the drive just to be conservative */
+	  mspersector=retime_drive(d, progress, log, offset, readahead, mspersector);
 	}
-	printC(".");
       }
       
-      if(under){
+      if(under)
 	lower=readahead;
-      }else{
-	upper=readahead;
-      }
+
     }
     readahead=lower;
   }
@@ -428,54 +467,58 @@
   }
   
   reportC("\tTesting cache tail cursor");
-  rollbehind=cachesize;
-  
-  for(i=0;i<10 && rollbehind;i++){
-    int sofar=0,ret,retry=0;
-    logC("\n\t\t>>> ");
-    printC(".");
-    while(sofar<cachesize){
-      ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
-      if(ret<=0)goto error;
-      logC("%d:%d ",ret,cdda_milliseconds(d));
-      sofar+=ret;
-    }
+
+  while(1){
+    rollbehind=cachesize;
     
-    /* Pause 5x what we'd predict is needed to read cachesize more sectors to let the readahead process work. */
-    {
-      int usec=ms_per_sector_at(offset+cachesize,waypoint)*cachesize*5000;
-      logC("\n\t\tsleeping %d microseconds",usec);
-      usleep(usec);
-    }
+    for(i=0;i<10 && rollbehind;i++){
+      int sofar=0,ret,retry=0;
+      logC("\n\t\t>>> ");
+      printC(".");
+      while(sofar<cachesize){
+	ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
+	if(ret<=0)goto error;
+	logC("%d:%d ",ret,cdda_milliseconds(d));
+	sofar+=ret;
+      }
     
-    /* read backwards until we seek */
-    logC("\n\t\t<<< ");
-    sofar=rollbehind;
-    while(sofar>0){
-      sofar--;
-      ret = cdda_read(d,NULL,offset+sofar,1);
-      if(ret<=0)break;
-      logC("%d:%d ",sofar,cdda_milliseconds(d));
-      if(cdda_milliseconds(d)>8){
-	rollbehind=sofar+1;
-	break;
+      /* Pause what we'd predict is needed to let the readahead process work. */
+      {
+	int usec=mspersector*readahead*5000;
+	logC("\n\t\tsleeping %d microseconds",usec);
+	usleep(usec);
       }
-      rollbehind=sofar;
-    }
-  error:
-    if(ret<=0){
-      offset+=cachesize;
-      retry++;
-      if(retry>10 || offset+cachesize>lastsector){
-	reportC("\n\tToo many read errors while performing drive cache checks;"
-		"\n\t  aborting test.\n\n");
-	return(-1);
+      
+      /* read backwards until we seek */
+      logC("\n\t\t<<< ");
+      sofar=rollbehind;
+      while(sofar>0){
+	sofar--;
+	ret = cdda_read(d,NULL,offset+sofar,1);
+	if(ret<=0)break;
+	logC("%d:%d ",sofar,cdda_milliseconds(d));
+	if(cdda_milliseconds(d)>8){
+	  rollbehind=sofar+1;
+	  break;
+	}
+	rollbehind=sofar;
       }
-      reportC("\n\tRead error while performing drive cache checks;"
-	      "\n\t  choosing new offset and trying again.\n");
-      continue;
+    error:
+      if(ret<=0){
+	offset+=cachesize;
+	retry++;
+	if(retry>10 || offset+cachesize>lastsector){
+	  reportC("\n\tToo many read errors while performing drive cache checks;"
+		  "\n\t  aborting test.\n\n");
+	  return(-1);
+	}
+	reportC("\n\tRead error while performing drive cache checks;"
+		"\n\t  choosing new offset and trying again.\n");
+	continue;
+      }
     }
-  }
+
+    /* verify that the drive timing didn't suddenly change */XXXXXXXXX
   
   logC("\n");
   printC("\r");
@@ -499,17 +542,19 @@
       sofar+=ret;
     }
     
-    /* Pause 5x what we'd predict is needed to read cachesize more sectors to let the readahead process work. */
+    /* Pause what we'd predict is needed to let the readahead process work. */
     {
-      int usec=ms_per_sector_at(offset+cachesize,waypoint)*cachesize*5000;
+      int usec=mspersector*readahead*(2+i)*1000;
+      int max= 13000*2*readahead; /* corresponds to .5x */
+      if(usec>max)usec=max;
       logC("\n\t\tsleeping %d microseconds",usec);
       usleep(usec);
     }
-    
+
     /* read backwards until we seek */
     logC("\n\t\t<<< ");
     sofar=cachegran;
-    while(sofar>1){
+    while(sofar){
       sofar--;
       ret = cdda_read(d,NULL,offset+sofar,1);
       if(ret<=0)break;



More information about the commits mailing list