Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 1996 02:51:24 -0700 (PDT)
From:      asami@cs.berkeley.edu (Satoshi Asami)
To:        bde@zeta.org.au
Cc:        bde@zeta.org.au, ccd@stampede.cs.berkeley.edu, current@freebsd.org
Subject:   Re: some more on fast bcopy
Message-ID:  <199605160951.CAA01120@silvia.HIP.Berkeley.EDU>
In-Reply-To: <199605151358.XAA22996@godzilla.zeta.org.au> (message from Bruce Evans on Wed, 15 May 1996 23:58:45 %2B1000)

next in thread | previous in thread | raw e-mail | index | archive | help
By the way, if you guys want to see the effect of the fast bcopy
without building a ccd, try this:

===
/* rawread.c: repeatedly read from same block over and over */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <ufs/ffs/fs.h>

/* some constants */
#define True (1)
#define False (0)
#define Ok (0)
#define Error (1)

/* start of onfigurable parameters */

/* default buffer size */
#define BlockSize	65536

/* default size of file */
#define TotalSize	104857600

int removefile = True ;
int verbose = False ;
int writeonly = False ;
int randomize = False ;
int readonly = False ;
int noseek = False ;

/* end of configurable parameters */

/* default name of temporary file */
#define TmpFile		"disktest.tmp"

/* default line length */
#define LineLen		1024

char *myname ;

void *xmalloc(size_t size) ;
void usage(int retval) ;
void error(char *msg) ;
void flushoutput(void) ;
void cuechild(void) ;

int main(int argc, char **argv)
{
    int i ;
    char *filename ;
    int blocksize = BlockSize ;
    int totalsize = TotalSize ;
    int iterations ;
    void *buffer, *buffer2 ;
    int fd ;
    int count ;
    struct timeval tv_start, tv_end ;
    double elapsed ;
    int docopy = False ;
    int offset = 0 ;
    int seek = 0 ;

    myname = argv[0] ;
    filename = argv[argc-1] ;

    if (argc < 2)	usage(Error) ;
    for (i = 1 ; i < argc-1 ; i++) {
	if (argv[i][0] == '-') { /* option */
	    if (!strcmp(argv[i], "-b")) {
		if (i+1 == argc)
		    usage(Error) ;
		blocksize = atoi(argv[i+1]) ;
		if (blocksize <= 0)
		    usage(Error) ;
		i++ ;
	    }
	    else if (!strcmp(argv[i], "-s")) {
		if (i+1 == argc)
		    usage(Error) ;
		totalsize = atoi(argv[i+1]) ;
		if (totalsize <= 0)
		    usage(Error) ;
		i++ ;
	    }
	    else if (!strcmp(argv[i], "-k")) {
		if (i+1 == argc)
		    usage(Error) ;
		seek = atoi(argv[i+1]) ;
		if (seek < 0)
		    usage(Error) ;
		i++ ;
	    }
	    else if (!strcmp(argv[i], "-o")) {
		if (i+1 == argc)
		    usage(Error) ;
		offset = atoi(argv[i+1]) ;
		if (offset < 0 || offset > 32)
		    usage(Error) ;
		i++ ;
	    }
	    else if (!strcmp(argv[i], "-c"))
		docopy = True ;
	    else if (!strcmp(argv[i], "-n"))
		noseek = True ;
	    else if (!strcmp(argv[i], "-h"))
		usage(Ok) ;
	    else
		usage(Error) ;
	}
	else
	    usage(Error) ;
    }

    iterations = totalsize / blocksize ;

    if (filename[0] == '-')
	usage(Error);

    buffer = xmalloc(blocksize+2048) ;
    {
	unsigned long tmp = buffer;
	tmp += 1024;
	tmp &= ~1024;
	tmp += offset;
	buffer = tmp;
    }
    if (docopy)
	buffer2 = xmalloc(blocksize) ;

    if ((fd = open(filename, O_RDONLY, 0)) < 0) {
	fprintf(stderr, "file: %s\n", filename) ;
	error("open") ;
    }
    gettimeofday(&tv_start, NULL) ;
    for (count = 0 ; count < iterations ; count++) {
	if (!noseek)
	    lseek(fd, seek, SEEK_SET) ;
	if (read(fd, buffer, blocksize) != blocksize)
	    error("read") ;
	if (docopy)
	    memcpy(buffer2, buffer, blocksize) ;
    }
    gettimeofday(&tv_end, NULL) ;
    elapsed = tv_end.tv_sec-tv_start.tv_sec
	+ ((double) tv_end.tv_usec-tv_start.tv_usec)/1000000 ;
    if (verbose)
	printf("%d reads of %d bytes in %f seconds\n",
	       count, blocksize, elapsed) ;
    printf("%d bytes transferred in %d secs (%d bytes/sec) from \"%s\"\n",
	   totalsize, (int) elapsed, (int) (totalsize/elapsed), filename) ;
    fflush(stdout) ;
    close(fd) ;
    return Ok ;
}

void usage(int retval)
{
    fprintf(stderr, "usage: %s [-b bufsize] [-s size] [-o offset] [-k seek] [-n] [-c] filename\n",
	    myname) ;
    exit(retval) ;
}

void *xmalloc(size_t size)
{
    void *vp ;
    if ((vp = malloc(size)) == NULL) {
	fprintf(stderr, "panic: memory exausted with request size %d\n", size) ;
	exit(Error) ;
    }
    return vp ;
}

void error(char *msg)
{
    perror(msg) ;
    exit(Error) ;
}
===

Use it like "rawread /kernel".  If you specify a regular file, the
data will come from the disk buffer so the speed pretty much reflects
the copyout bandwidth.  (I initially designed this to measure the
bandwidth of SCSI strings across the PCI bus by reading from the raw
device node -- hence the name.)

On my P5-90 (SiS), it jumps from about 21MB/s to 36MB/s. :)

Satoshi



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605160951.CAA01120>