[comp.sys.amiga] The great DMA -vs- non DMA disk controller war, and ...

root@sbcs.UUCP (12/10/86)

Here is a disk benchmark program I whipped up while pondering whether
a DMA disk controller really matters with Commodore's current (old Unix
style) disk format.  Any proud owners of a shiny, new Byte by Byte
(or any other derivative of the C-A DMA disk controller) want to take
a shot at running this program?  I would also like to hear from folks
running the MicroScience (?) drive which hangs off the parallel port.

					Rick Spanbauer
					SUNY/Stony Brook

----------------------------------------------------------------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	diskperf.c
#	diskperfa.uu
# This archive created: Tue Dec  9 22:29:09 1986
export PATH; PATH=/bin:$PATH
if test -f 'diskperf.c'
then
	echo shar: over-writing existing file "'diskperf.c'"
fi
cat << \SHAR_EOF > 'diskperf.c'
/*
** Disk performance benchmark.  If your Amiga configuration is substantially
** different from the ones mentioned here, please run the benchmark and
** report the results to either: ..!philabs!sbcs!rick or posting to
** comp.sys.amiga.  Thanks!
**
** To compile benchmark for Unix 4.2/4.3 SUN 3.0/3.2:
**
**	cc -o diskperf -O -DUNIX diskperf.c
**
** Amiga version was cross compiled from a SUN, so you'll have to figure out
** how to compile diskperf under your favorite compiler system.  A uuencoded
** Amiga binary version of diskperfa is included with the shar file that 
** contained this source listing.
**
** To run diskperf, simply type:
**
**	diskperf [location], e.g. (on Amiga) diskperf ram:
**
** On the Amiga, you will need at least 256K bytes of "disk" wherever you
** choose to run.  Unix systems will need about 3 mBytes free (larger size
** test files to delete buffer caching effect).
**
** Disclaimer:
**
**	This benchmark is provided only for the purpose of seeing how fast
**	_your_ system runs the program.  No claims are made on my part
**	as to what conclusions may be drawn from the statistics gathered.
**	Just consider this program the "Sieve of Eratosthenes" of disk
**	benchmarks - haggle over the numbers with friends, etc, but
**	don't base purchasing decisions solely on the numbers produced
**	by this program.
**
** Amiga timings gathered thus far:
**
-----------------------------------------------------------------------------
Amiga A-1000, ~7mHz 68000, RAM:

File create/delete:	create 5 files/sec, delete 10 files/sec
Directory scan:		5 entries/sec
Seek/read test:		51 seek/reads per second
r/w speed:		buf 512 bytes, rd 201469 byte/sec, wr 154202 byte/sec
r/w speed:		buf 4096 bytes, rd 655360 byte/sec, wr 374491 byte/sec
r/w speed:		buf 8192 bytes, rd 873813 byte/sec, wr 374491 byte/sec
r/w speed:		buf 32768 bytes, rd 873813 byte/sec, wr 436906 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000, ~7mHz 68000, DF1:

File create/delete:	create [0..1] files/sec, delete 1 files/sec
Directory scan:		43 entries/sec
Seek/read test:		18 seek/reads per second
r/w speed:		buf 512 bytes, rd 11861 byte/sec, wr 5050 byte/sec
r/w speed:		buf 4096 bytes, rd 12542 byte/sec, wr 5180 byte/sec
r/w speed:		buf 8192 bytes, rd 12542 byte/sec, wr 5130 byte/sec
r/w speed:		buf 32768 bytes, rd 12542 byte/sec, wr 5160 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000/CSA Turbo board, ~14 mHz 68020, no 32 bit ram installed, RAM:

File create/delete:	create 7 files/sec, delete 15 files/sec
Directory scan:		8 entries/sec
Seek/read test:		84 seek/reads per second
r/w speed:		buf 512 bytes, rd 187245 byte/sec, wr 145625 byte/sec
r/w speed:		buf 4096 bytes, rd 655360 byte/sec, wr 327680 byte/sec
r/w speed:		buf 8192 bytes, rd 873813 byte/sec, wr 374491 byte/sec
r/w speed:		buf 32768 bytes, rd 873813 byte/sec, wr 436906 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000, ~7 mHz 68000, Ameristar NFS  -> SUN-3/50, Micropolis 1325 disk:

File create/delete:	create 3 files/sec, delete 7 files/sec
Directory scan:		10 entries/sec
Seek/read test:		35 seek/reads per second
r/w speed:		buf 512 bytes, rd 30481 byte/sec, wr 3481 byte/sec
r/w speed:		buf 4096 bytes, rd 113975 byte/sec, wr 21664 byte/sec
r/w speed:		buf 8192 bytes, rd 145635 byte/sec, wr 38550 byte/sec
r/w speed:		buf 32768 bytes, rd 145365 byte/sec, wr 37449 byte/sec
-----------------------------------------------------------------------------
SUN-3/50, Adaptec SCSI<->ST-506, Micropolis 1325 drive (5.25", 5 mBit/sec):

File create/delete:	create 6 files/sec, delete 11 files/sec
Directory scan:		350 entries/sec
Seek/read test:		298 seek/reads per second
r/w speed:		buf 512 bytes, rd 240499 byte/sec, wr 215166 byte/sec
r/w speed:		buf 4096 bytes, rd 234057 byte/sec, wr 182466 byte/sec
r/w speed:		buf 8192 bytes, rd 233189 byte/sec, wr 179755 byte/sec
r/w speed:		buf 32768 bytes, rd 236343 byte/sec, wr 187580 byte/sec
-----------------------------------------------------------------------------

**
** Some sample figures from "large" systems: 
**

-----------------------------------------------------------------------------
SUN-3/160, Fujitsu SuperEagle, Interphase VSMD-3200 controller:

File create/delete:	create 15 files/sec, delete 18 files/sec
Directory scan:		722 entries/sec
Seek/read test:		465 seek/reads per second
r/w speed:		buf 512 bytes, rd 361162 byte/sec, wr 307200 byte/sec
r/w speed:		buf 4096 bytes, rd 419430 byte/sec, wr 315519 byte/sec
r/w speed:		buf 8192 bytes, rd 409067 byte/sec, wr 314887 byte/sec
r/w speed:		buf 32768 bytes, rd 409600 byte/sec, wr 328021 byte/sec
-----------------------------------------------------------------------------
SUN-3/75, NFS filesystem, full 8192 byte transactions:

File create/delete:	create 9 files/sec, delete 12 files/sec
Directory scan:		88 entries/sec
Seek/read test:		282 seek/reads per second
r/w speed:		buf 512 bytes, rd 238674 byte/sec, wr 52012 byte/sec
r/w speed:		buf 4096 bytes, rd 259334 byte/sec, wr 54956 byte/sec
r/w speed:		buf 8192 bytes, rd 228116 byte/sec, wr 26483 byte/sec
r/w speed:		buf 32768 bytes, rd 243477 byte/sec, wr 36174 byte/sec
-----------------------------------------------------------------------------
DEC VAX 780, RP07:

File create/delete:	create 12 files/sec, delete 12 files/sec
Directory scan:		509 entries/sec
Seek/read test:		245 seek/reads per second
r/w speed:		buf 512 bytes, rd 168041 byte/sec, wr 141064 byte/sec
r/w speed:		buf 4096 bytes, rd 210135 byte/sec, wr 239765 byte/sec
r/w speed:		buf 8192 bytes, rd 206277 byte/sec, wr 239948 byte/sec
r/w speed:		buf 32768 bytes, rd 199222 byte/sec, wr 232328 byte/sec
-----------------------------------------------------------------------------
DEC VAX 750, RA81:

File create/delete:	create 12 files/sec, delete 15 files/sec
Directory scan:		208 entries/sec
Seek/read test:		153 seek/reads per second
r/w speed:		buf 512 bytes, rd 99864 byte/sec, wr 72549 byte/sec
r/w speed:		buf 4096 bytes, rd 142663 byte/sec, wr 166882 byte/sec
r/w speed:		buf 8192 bytes, rd 147340 byte/sec, wr 153525 byte/sec
r/w speed:		buf 32768 bytes, rd 142340 byte/sec, wr 141571 byte/sec
-----------------------------------------------------------------------------

*/ 

#ifdef UNIX

#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/stat.h>

#define SCAN_ITER       10
#define RW_ITER         3
#define RW_SIZE         (3*1024*1024)
#define SEEK_TEST_FSIZE (1024*1024)
#define OPEN_TEST_FILES 200
#define TIMER_RATE      100

/*
** Amiga compatibility library for Unix.  These are NOT full or correct 
** emulations of the Amiga I/F routines - they are intended only to 
** run this benchmark.
*/

#define MODE_OLDFILE    1005
#define MODE_NEWFILE    1006
#define ERROR_NO_MORE_ENTRIES 
#define OFFSET_BEGINNING -1
#define OFFSET_CURRENT 0

Open(name, accessMode)
        char    *name;
        long    accessMode;
{
        int     flags, file;

        flags = O_RDWR;
        if(accessMode == MODE_NEWFILE)
                flags |= O_TRUNC|O_CREAT;
        if((file = open(name, flags, 0644)) < 0)
                file = 0;
        return(file);
}

/*
** To be fair, write should be followed by fsync(file) to flush cache.  But
** since when are benchmarks fair??
*/
#define Write(file, buffer, length) write(file, buffer, length)
#define Read(file, buffer, length) read(file, buffer, length)
#define Close(file) close(file)
#define CreateDir(name) mkdir(name, 0755)
#define Seek(file, position, mode) lseek(file, position, \
                (mode==OFFSET_BEGINNING ? 0 : (mode==OFFSET_CURRENT?1:2)))
#define AllocMem(size, constraints) malloc(size)
#define FreeMem(p, size) free(p, size)
#define DeleteFile(filename) unlink(filename)

timer_init()
{
        return(1);
}

timer_quit()
{
}

timer(valp)
        long    *valp;
{
        static struct timeval ref;
        struct timeval current;
        
        if(valp == (long *)0){
                gettimeofday(&ref, 0);
                return;
        } 
        gettimeofday(&current, 0);
        *valp = (current.tv_usec - ref.tv_usec)/(1000000/TIMER_RATE);
        if(*valp < 0){
                current.tv_sec--;
                *valp += TIMER_RATE;
        }
        *valp += (current.tv_sec - ref.tv_sec)*TIMER_RATE;
}

OpenStat(filename)
        char    *filename;
{
        int     fd, result;
        struct stat statb;

        if((fd = open(filename, 0)) < 0)
                return(0);
        result = fstat(fd, &statb);
        close(fd);
        return(result == 0);
}

#else

/*
** Iteration/size definitions smaller for Amiga so benchmark doesn't take
** as long and fits on empty floppy.
*/

#include <exec/types.h>
#include <libraries/dos.h>
#include <devices/timer.h>

#define SCAN_ITER       5
#define RW_ITER         3
#define RW_SIZE         (256*1024)
#define SEEK_TEST_FSIZE (256*1024)
#define OPEN_TEST_FILES 100
#define TIMER_RATE      10              /* misnomer, should be resolution */

struct MsgPort *timerport, *CreatePort();
struct timerequest *timermsg, *CreateExtIO();
long    TimerBase;

timer_init()
{
        timerport = CreatePort(0, 0);
        if(timerport == (struct MsgPort *)0)
                return(0);
        timermsg = CreateExtIO(timerport, sizeof(struct timerequest));
        if(timermsg == (struct timerequest *)0){
                DeletePort(timerport);
                return(0);
        }
        if(OpenDevice(TIMERNAME, UNIT_VBLANK, timermsg, 0) != 0){
                DeletePort(timerport);
                DeleteExtIO(timermsg, sizeof(struct timerequest));
                return(0);
        }
        TimerBase = (long)timermsg->tr_node.io_Device;  /* Hack */
        return(1);
}

timer_quit()
{
        CloseDevice(timermsg);
        DeleteExtIO(timermsg, sizeof(struct timerequest));
        DeletePort(timerport);
}

timer(valp)
        long    *valp;
{
        static struct timeval ref;
        long    t;

        timermsg->tr_node.io_Command = TR_GETSYSTIME;
        DoIO(timermsg);
        t = timermsg->tr_time.tv_secs;
        if(valp == (long *)0)
                ref = timermsg->tr_time;
        else {
                SubTime(&timermsg->tr_time, &ref);
                *valp = timermsg->tr_time.tv_secs*TIMER_RATE +
                        (timermsg->tr_time.tv_micro/(1000000/TIMER_RATE));
        }
}

OpenStat(filename)
        char    *filename;
{
        long    lock, result;
        static struct FileInfoBlock fib;  /* must be on &fib mod 4 == 0 */

        if((lock = Lock(filename, MODE_OLDFILE)) == 0)
                return(0); 
        result = Examine(lock, &fib);
        UnLock(lock);
        return(result);
}

#endif

/*
** Benchmarks performed:
**
**      1)  Raw file read/write rates.  Tested for operation sizes of
**          512/4096/8192/65536 bytes.  Return read/write figures for each
**          tranfer size in bytes/sec.
**
**      2)  Directory create/delete rates.  Return create/delete entries
**          per second.
**
**      3)  Directory lookup rate.  Create files in directory, and
**          then measure time to lookup, open & stat entire directory contents.
**          Return entries/second.
**
**      4)  Seek speed test - create large file, then seek to various
**          positions in file & read one byte.  Seek distances intentionally
**          chosen large to reduce cacheing effectiveness - want basic
**          speed of disk format here.  Return seeks/second.
*/

char    *prepend = "";  /* prepend this path to all filenames created   */
char    scratch[8192];  /* scratch buffer used in various tests         */

/*
** Our `C' library for the Amiga is a bit different than Unix's, so this
** routine will look a bit obtuse to most of you.  Trying to avoid using
** sprintf()..
*/
maketemp(buf, pref)
        char    *buf;
{
        char    *p, *q;
        int     fnum;
        static  int cnt;
        
        fnum = cnt++;
        q = buf;
        if(pref)
                for(p = prepend; *p; )
                        *q++ = *p++;
        for(p = "diskperf"; *p; )
                *q++ = *p++;
        *q++ = 'A' + ((fnum>>8)&0xf);
        *q++ = 'A' + ((fnum>>4)&0xf);
        *q++ = 'A' + (fnum&0xf);
        *q++ = 0;
}

long    sptest[] = {512, 4096,  8192, 32768, 0};

void rw_test()
{
        long    i, j, k, maxsize, file, RDaccTime, WRaccTime, Dt;
        struct timeval t0, t1;
        char    *p, filename[64];

        maxsize = -1;
        for(k = 0; sptest[k] != 0; k++)
                if(sptest[k] > maxsize)
                        maxsize = sptest[k];
        if((p = (char *)AllocMem(maxsize, 0)) == (char *)0){
                printf("Could not get %d bytes of memory\n", maxsize);
                return;
        }
        for(k = 0; sptest[k] != 0; k++){
                RDaccTime = WRaccTime = 0;
                for(j = 0; j < RW_ITER; j++){

                        maketemp(filename, 1);

                        if((file = Open(filename, MODE_NEWFILE)) == 0){
                                printf("Could not create %s\n", filename);
                                return;
                        }
                        timer(0);
                        for(i = RW_SIZE/sptest[k]; i > 0; i--)
                                Write(file, p, sptest[k]);
                        timer(&Dt);
                        WRaccTime += Dt;
                        Close(file);

                        if((file = Open(filename, MODE_OLDFILE)) == 0){
                                printf("Could not open %s\n", filename);
                                return;
                        }
                        timer(0);
                        for(i = RW_SIZE/sptest[k]; i > 0; i--)
                                Read(file, p, sptest[k]);
                        timer(&Dt);
                        RDaccTime += Dt;
                        Close(file);

                        DeleteFile(filename);
                }
                printf("r/w speed:\t\tbuf %d bytes, rd %d byte/sec, wr %d byte/sec\n", 
                                sptest[k],
                                (TIMER_RATE*RW_SIZE)/(RDaccTime/RW_ITER),
                                (TIMER_RATE*RW_SIZE)/(WRaccTime/RW_ITER));

        }
        FreeMem(p, maxsize);
}

seek_test()
{
        char    fname[64];
        long    i, fd, Dt, cnt, pos, dist;

        maketemp(fname, 1);
        if((fd = Open(fname, MODE_NEWFILE)) == 0){
                printf("Could not create %s\n", fname);
                return;
        }
        for(i = SEEK_TEST_FSIZE/sizeof(scratch); i > 0; i--)
                if(Write(fd, scratch, sizeof(scratch)) != sizeof(scratch))
                        break;
        if(i == 0){
                cnt = 0;
                timer(0);
                for(dist = 256; dist <= 65536; dist <<= 2)
                        for(pos = 0; pos < SEEK_TEST_FSIZE; pos += dist){
                                cnt++;
                                Seek(fd, pos, OFFSET_BEGINNING);
                                Read(fd, scratch, 1);
                        }
                timer(&Dt);
                printf("Seek/read test:\t\t%d seek/reads per second\n", 
                                (TIMER_RATE*cnt)/Dt);
        }
        Close(fd);
        DeleteFile(fname);
}

char    tempname[OPEN_TEST_FILES][16];

open_scan_test()
{
        char    dirname[64];
        long    lock, oldlock, cDt, dDt, sDt, i, j, fd, numRead;
        struct FileInfoBlock *fib;

        maketemp(dirname, 1);
        lock = CreateDir(dirname);
#ifdef UNIX
        chdir(dirname);
#else
        oldlock = CurrentDir(lock);
#endif
        for(i = 0; i < OPEN_TEST_FILES; i++)
                maketemp(tempname[i], 0);
        
        /*
        ** Time Open of files.
        */
        timer(0);
        for(i = 0; i < OPEN_TEST_FILES; i++){
                if((fd = Open(tempname[i], MODE_NEWFILE)) == 0){
                        printf("Could not open %s/%s\n", dirname, tempname);
                        break;
                }
                Close(fd);
        }
        timer(&cDt);

        /*
        ** Time open scan of directory.
        */
        timer(0);
        numRead = 1;
        for(i = 0; i < SCAN_ITER; i++)
                for(j = 0; j < OPEN_TEST_FILES; j++)
                        if(OpenStat(tempname[i]) != 0)
                                numRead++;
        timer(&sDt);

        /*
        ** Time Close of files.
        */
        timer(0);
        for(i = 0; i < OPEN_TEST_FILES; i++)
                DeleteFile(tempname[i]);
        timer(&dDt);

        printf("File create/delete:\tcreate %d files/sec, delete %d files/sec\n",
                                (TIMER_RATE*OPEN_TEST_FILES)/cDt, 
                                (TIMER_RATE*OPEN_TEST_FILES)/dDt);
        printf("Directory scan:\t\t%d entries/sec\n", 
                                (TIMER_RATE*numRead)/sDt);
#ifdef UNIX
        chdir("..");
        rmdir(dirname);
#else
        CurrentDir(oldlock);
        DeleteFile(dirname);
#endif
}

main(argc, argv)
        int     argc;
        char    **argv;
{
        if(!timer_init()){
                printf("Could not init timer\n");
                return(0);      /* Exit in most systems, but not ours! */
        }
        if(argc > 1)
                prepend = argv[1];
        open_scan_test();
        seek_test();
        rw_test();
}

SHAR_EOF
chmod +x 'diskperf.c'
if test -f 'diskperfa.uu'
then
	echo shar: over-writing existing file "'diskperfa.uu'"
fi
cat << \SHAR_EOF > 'diskperfa.uu'
begin 644 diskperfa
M   #\P         #          (   25   *GP        /I   $E4CG?_XC
MSP    PO""\ <  B/   *GPB?    9R2B>2!8 (BP%')__PC^  $   !G"\ 
M2'D     3KH1UE!/(\    &@3KH.MBYY    #$S??_Y.=4Y6  !"IT*G3KD 
M  D04$\CP   )^Q*N0  )^QF!G  8   B$AX "@O.0  )^Q.N0  ")103R/ 
M   !I$JY   !I&82+SD  "?L3KD   G.6$]P &!40J<O.0   :1(>  !2'D 
M   H3KD  !'P3^\ $$J 9R0O.0  )^Q.N0  "<Y83TAX "@O.0   :1.N0  
M"-Q03W  8! @>0   :0CZ  4   !J' !3EY.=4Y6   O.0   :1.N0  $8A8
M3TAX "@O.0   :1.N0  "-Q03R\Y   G[$ZY   )SEA/3EY.=4Y6__@N@B!Y
M   !I#%\  H '"\Y   !I$ZY   1G%A/('D   &D+6@ (/_\2JX "&8<(#D 
M  &D="#0@B! (^@ !   *  CT   )_Q@3$AY   G_" Y   !I'0@T((O $ZY
M   2/%!/('D   &D("@ (-" ) #EBM"")  @>0   :0@*  D(CP  8:@3KD 
M  X(U( @;@ ((((D+O_X3EY.=4Y6__A(> /M+RX "$ZY   0F%!/+4#__&8$
M< !@)DAY   H!"\N__Q.N0  $&Q03RU __@O+O_\3KD  !$86$\@+O_X3EY.
M=4Y6__0M>0  *0C_]%*Y   I""UN  C_^$JN  QG)"UY    $/_\8!(@;O_X
M(F[__!"14J[__%*N__@@;O_\2A!FYBU\    -?_\8!(@;O_X(F[__!"14J[_
M_%*N__@@;O_\2A!FYB!N__@@+O_TX(!R#\"!<D'0@1" 4J[_^"!N__@@+O_T
MZ(!R#\"!<D'0@1" 4J[_^"!N__@0+O_W<@_ @7)!T($0@%*N__@@;O_X0A!2
MKO_X3EY.=4Y6_XQR_RU!__!"KO_T8"P@+O_TY8!!^0   !0@, @ L*[_\&\2
M("[_].6 0?D    4+7 ( /_P4J[_]" N__3E@$'Y    %$JP" !FPD*G+R[_
M\$ZY   17%!/+4#_S&84+R[_\$AY    /DZY   *(&   ?I"KO_T8  !T$*N
M_^1"KO_H0J[_^$AX  %(;O^,80#^LE!/2'@#[DAN_XQ.N0  $+103RU _^QF
M%$AN_XQ(>0   &!.N0  "B!@  &N0J=A /V66$\@+O_TY8!!^0   !0B, @ 
M(#P !   3KD   V,+4#__& F("[_].6 0?D    4+S ( "\N_\PO+O_L3KD 
M !$L3^\ #%.N__Q*KO_\;M1(;O_@80#]/EA/("[_X-&N_^0O+O_L3KD  ! <
M6$](> /M2&[_C$ZY   0M%!/+4#_[&842&[_C$AY    =4ZY   *(&   1!"
MIV$ _/A83R N__3E@$'Y    %"(P"  @/  $  !.N0  #8PM0/_\8"8@+O_T
MY8!!^0   !0O, @ +R[_S"\N_^Q.N0  $.!/[P ,4Z[__$JN__QNU$AN_^!A
M /R@6$\@+O_@T:[_Z"\N_^Q.N0  $!Q83TAN_XQ.N0  $%A83U*N__@,K@  
M  /_^&T _IP@+O_D<@-.N0  #8PB " \ "@  $ZY   -C"\ ("[_Z'(#3KD 
M  V,(@ @/  H  !.N0  #8PO " N__3E@$'Y    %"\P" !(>0   (A.N0  
M"B!/[P 04J[_]" N__3E@$'Y    %$JP" !F /X@+R[_\"\N_\Q.N0  $<10
M3TY>3G5.5O^H2'@  4AN_\!A /S$4$](> /N2&[_P$ZY   0M%!/+4#_N&86
M2&[_P$AY    PDZY   *(%!/8   \'(@+4'_O& D2'@@ $AY   '["\N_[A.
MN0  $2Q/[P ,#(   "  9@I3KO^\2J[_O&[62J[_O&8  )Y"KO^P0J=A /MH
M6$\M?    0#_J$*N_ZQ2KO^P2'C__R\N_ZPO+O^X3KD  !#\3^\ #$AX  %(
M>0  !^PO+O^X3KD  !#@3^\ #" N_ZC1KO^L#*X !   _ZQMO.6 +4#_J RN
M  $  /^H;ZA(;O^T80#Z_EA/("[_L-" (@#E@="!(B[_M$ZY   -C"\ 2'D 
M  #73KD   H@4$\O+O^X3KD  ! <6$](;O_ 3KD  !!86$].7DYU3E;_F$AX
M  %(;O_ 80#[E%!/2&[_P$ZY   0,%A/+4#_O"\ 3KD  !!$6$\M0/^X0J[_
MJ$*G("[_J.F !H    &L+P!A /M<4$]2KO^H#*X   !D_ZAMW$*G80#Z7%A/
M0J[_J$AX ^X@+O^HZ8 &@    :PO $ZY   0M%!/+4#_H&8<2'D   &L2&[_
MP$AY   ! DZY   *($_O  Q@&B\N_Z!.N0  $!Q83U*N_Z@,K@   &3_J&VJ
M2&[_M&$ ^?A83T*G80#Y\%A/<@$M0?^<0J[_J$*N_Z0@+O^HZ8 &@    :PO
M &$ ^G!83TJ 9P12KO^<4J[_I RN    9/^D;=92KO^H#*X    %_ZAMQ$AN
M_ZQA /F@6$]"IV$ ^9A83T*N_Z@@+O^HZ8 &@    :PO $ZY   06%A/4J[_
MJ RN    9/^H;=Q(;O^P80#Y9EA/(#P   /H(B[_L$ZY   -C"\ (#P   /H
M(B[_M$ZY   -C"\ 2'D   $83KD   H@3^\ #" N_YS0@"( Y8'0@2(N_ZQ.
MN0  #8PO $AY   !5DZY   *(%!/+R[_N$ZY   01%A/2&[_P$ZY   06%A/
M3EY.=4Y6  !.N0   %1*@&822'D   %W3KD   H@6$]P & B#*X    !  AO
M#"!N  PCZ  $    $&$ _?QA /S(80#Z4$Y>3G4  $Y6__Q*K@ (9Q9(>0 !
M  $O+@ ,80 (LE!/+4#__&8$< !@("!N__P1?  %  @@;O_\0B@ "2!N__PA
M;@ (  X@+O_\3EY.=4Y6   @;@ ($7P _P ((&X "'+_(4$ %"!N  @A00 8
M+RX #"\N  AA  B^4$].7DYU  !.5O_P+HU(>/__80 (6%A/'4#_]PP __]F
M!G  8   F$AY  $  4AX ")A  @@4$\M0/_X9A00+O_W2(!(P"\ 80 (BEA/
M< !@;"!N__@A;@ (  H@;O_X$6X #P )(&[_^!%\  0 ""!N__A"*  .(&[_
M^!%N__\ #T*G80 ((EA/(&[_^"%  !!*K@ (9PPO+O_X80 'HEA/8!8J;O_X
M<A3;P4'M  0JB"M-  A"K0 $("[_^"IN__!.7DYU3E8  "!N  A*J  *9P@O
M"&$ "$A83R!N  @1? #_  @@;@ (<O\A00 4(&X "! H  \"@    /\O &$ 
M!])83TAX "(O+@ (80 'K%!/3EY.=4Y6  !"ITAN  PO+@ (80A/[P ,3EY.
M=4Y6_S1(USS\*FX ""AN  PF;@ 01>[_=&   F ,!P E9P84QV   E1![O]T
MM<AG'$A30J=![O]TE<@O"DAN_W1A  )F3^\ $$7N_W1"+O]F>  =?  @_V<,
M%0 M9@92+O]F4HT,%0 P9@@=?  P_V=2C0P5 "IG(GH $!U(@$C ?C"0ARP 
M;2)^";R';AS:A2(%Y8':@=J&8.!2C1 =2(!(P'XPD(<L "H<0B[_97XPW(=^
M+KR'9D(,%0 J9RQX & 4?@F\AVX<4B[_9=B$(@3E@=B!V(80'4B 2,!^,)"'
M+ !LWGXPW(=@$%*-$!U(@$C + !2+O]E*!P@!GYXL(=B  %X0?H!9G(-L!A4
MR?_\9@ !:-)!,#L0!D[[  (!2 !* !P /@!: $0 O !* !P /@%" 1H 6@!$
M$!U(@$C ?F2PAV<B?F^PAV<0?G6PAV<F?GBPAV<*4XU@''8()!Q@&G80)!Q@
M%'8*2I1L]A3\ "TD'$2"8 0D''8*2H)F"$J$9@04_  P0>[_:"U(__Q@+" "
M(@-.N@*<+  @;O_\?@J\AVP$<#!@ G!7T(80@%*N__P@ B(#3KH"%B0 2H)F
MT$'N_V@@+O_\L(AC*E.N__P@;O_\%-!@Z"U,__Q8C'P (&[__%*N__P4T&8"
M4XI2AGX$O(=MZD'N_W0M2/_\( J0KO_\FH L!6P"? !*+O]F9@)$AA N_V=(
M@$C +P!(4R\&E>[__"\*+R[__&%X3^\ %&  _=XM7/_\9@@M?    93__"P$
M9@8L/   ?_\D;O_\2A)GJ%.&;:12BF#T*%0J7& 4%/P )6 .>'5S<F]L9&-8
M54],1"4>'68 _9Y![O]TM<AG%DA30J=![O]TE<@O"DAN_W1A#D_O !!,[CS\
M_S1.7DYU3E;_^$C7(( J;@ (+BX #$JY   I#&9080 #UB/    I#&!$#!4 
M+68D#*X    P !AF&DAX  $@35*-2% O.0  *0QA  0&3^\ #%.'2'@  4AN
M !@O.0  *0QA  /N3^\ #%*N !!*K@ 0;;8O!TA5+SD  "D,80 #TD_O  Q@
M&DAX  %(;@ 8+SD  "D,80 #ND_O  Q3K@ 02JX $&;@3.X@@/_X3EY.=4Y6
M  !(YSP *CP    !2H!L!$2 1(4F $J!; 1$@42%* $,@0 !  !L%$) 2$" 
MP30 , . P4A , )(0& PXH#B@0* ?____P* ?____PR!  $  &SH@,$"@   
M__\D "($3KH X+: ; )3@B "2H5L D2 3-\ /$Y>3G5.5@  2.<X "8 * $,
M@0 !  !L&$A  H   /__@,$T # #@,%(0# "2$!@,.* XH$"@'____\"@7__
M__\,@0 !  !LZ(#! H   /__)  B!$ZZ ':V@&P"4X(@ DS? !Q.7DYU3E8 
M $CG,  D  R!  $  &P  !1"0$A @,$P H#!0D!(0&   #8F >* XH$"@'__
M__\"@7____\,@0 !  !L /_H@,$"@   __\B TZZ !:T@&P"D(.0@D2 3-\ 
M#$Y>3G4  $Y6  !(YS  )  F 4* , + PS("2$+$PTA#PL/2@DA!0D'0@4S?
M  Q.7DYU3E;_Y$C7., N+@ (*FX #$*G80 "H%A/+4#__"! 2J@ K&<  ,@@
M0" H *SE@"U __AA  %8(\   "?T80 !EB/    G^"/    G\"!N__@L*  0
MY88H1B9\   J6!P<2(9(QG(@O(%O!GP?8 (6W" &4X9*@&[V0AL@.0  *GCE
M@$'Y   I$"&\   J6 @ 4KD  "IX#(<   $ ;P8N/    /\F?   *5A@/ P5
M "!N"%*-4X=*AV[R2H=O*B Y   J>.6 0?D  "D0(8L( %*Y   J>& *#!4 
M(&\(%MU3ATJ';O)"&TJ';LH@.0  *GCE@$'Y   I$$*P" 1"ITAY   I$"\Y
M   J>&$ ^$)/[P ,3.XXP/_D3EY.=0  +PXB+P (+'D   &@3J[_W"Q?3G4O
M#B(O  @L>0   :!.KO^(+%].=2\.(B\ ""QY   !H$ZN_X(L7TYU+PXB+P (
M+'D   &@3J[_N"Q?3G5(YR "3.\ !@ ,+'D   &@3J[_FDS?0 1.=0  +PXL
M>0   :!.KO_*+%].=4CG( ),[P &  PL>0   :!.KO^L3-] !$YU  !(YR "
M3.\ !@ ,+'D   &@3J[_XDS?0 1.=0  +PXL>0   :!.KO_$+%].=4CG, ),
M[P . ! L>0   :!.KO_63-] #$YU  !(YS "3.\ #@ 0+'D   &@3J[_ODS?
M0 Q.=0  +PXB+P (+'D   &@3J[_IBQ?3G5(YS "3.\ #@ 0+'D   &@3J[_
MT$S?0 Q.=0  +PXB;P (+'D   &<3J[^GBQ?3G4O#DSO  , ""QY   !G$ZN
M_SHL7TYU   O#B O  @L>0   9Q.KOZV+%].=2\.(F\ ""QY   !G$ZN_CXL
M7TYU+PXB;P (+'D   &<3J[^."Q?3G4O#B)O  @L>0   9Q.KO[:+%].=2\.
M(F\ "" O  PL>0   9Q.KO\N+%].=2\.("\ ""QY   !G$ZN_K L7TYU+PX@
M;P (3.\" 0 ,(B\ %"QY   !G$ZN_D0L7TYU   O#B)O  @@+P ,+'D   &<
M3J[]V"Q?3G4O#B)O  @L>0   9Q.KOZ8+%].=2\.3.\#   (+'D   &H3J[_
MT"Q?3G4      ^P    Z         %X   "$    H    +X   #2    Y   
M 0X   $@   !+@   5(   &:   !Q@   >@   ($   "%    S(   -*   #
M?@   Y8   .^   #X@  ! P   0<   $-   !%P   2    $J@  !+8   34
M   $X@  !/    3^   %'   !48   5L   %A   !:8   7R   &"@  !E  
M  9>   &:@  !G8   :8   &I@  !O@   <6   ')@  ![@   ?B   ']   
M" (   @<   (*@  "#8   A"   (4@  "&(   !P     0    8    2    
M&    "P    T    0    $H   !F    ;    'X   ",    D@   )H   "N
M    N    ,P   #>    \    /@   $(   !&@   2@   %    !3    5H 
M  %L   !>@   8    &(   !C@   :(   &V   !^@   B@   (P   "0@  
M F8   +T   #"@   R    -$   #D    ZX   /0   $+@  !$P   1N   %
M#   !18   4P   %?@  !9P   8    &6   !KX   ;P   '!@  !Q    =B
M   'L   !_P   @D   (7   "'X   QX   ,\@  #/X   T@   -.   #50 
M  UL   /-   #SX   ]$   /5@  #W@   ^    /A@  #XX   ^B   /O   
M#\0   _.   /Z@  #_(   _^   0!   $"0  ! X   03   $&   !!X   0
MC   $*0  !#    0U   $.P  !$(   1(   $3@  !%0   19@  $7P  !&0
M   1I   $;@  !'0   1Y   $@(  !(<   2,   $D8        #\@   ^H 
M  !G9&]S+FQI8G)A<GD          9    (    0    (    (       '1I
M;65R+F1E=FEC90!D:7-K<&5R9@!#;W5L9"!N;W0@9V5T("5D(&)Y=&5S(&]F
M(&UE;6]R>0H 0V]U;&0@;F]T(&-R96%T92 E<PH 0V]U;&0@;F]T(&]P96X@
M)7,* '(O=R!S<&5E9#H)"6)U9B E9"!B>71E<RP@<F0@)60@8GET92]S96,L
M('=R("5D(&)Y=&4O<V5C"@!#;W5L9"!N;W0@8W)E871E("5S"@!3965K+W)E
M860@=&5S=#H)"25D('-E96LO<F5A9',@<&5R('-E8V]N9 H 0V]U;&0@;F]T
M(&]P96X@)7,O)7,* $9I;&4@8W)E871E+V1E;&5T93H)8W)E871E("5D(&9I
M;&5S+W-E8RP@9&5L971E("5D(&9I;&5S+W-E8PH 1&ER96-T;W)Y('-C86XZ
M"0DE9"!E;G1R:65S+W-E8PH 0V]U;&0@;F]T(&EN:70@=&EM97(*        
M   H;G5L;"D      ^P    !     0   !         #\@   ^L        #
!\@ H
 
end
SHAR_EOF
chmod +x 'diskperfa.uu'
#	End of shell archive
exit 0