norcott@databs.enet.dec.com (Bill Norcott) (03/27/91)
Attached is my PORTABLE version of Alvin Park's IOstone benchmark of
random acccess file I/O. I have ported it from the original Unix to
both VMS and MS-DOS. This code will compile and run on all these operating
systems. I have also added in comments some statistics I have gathered for
the IOstone test.
This test is influenced by the size of the buffer cache, processor speed, and
efficiency of the C compiler. However, together with my own IOzone benchmark
(posted earlier), it will give an estimate of system performance.
I would be interested on any comment on the port or benchmark results.
Regards,
Bill Norcott
Digital Equipment Corporation
----------------------- CUT HERE -----------------------------------
/*
* "I/O Stone" Benchmark Program
*
* Written by: Arvin Park (park@princeton)
* Department of Computer Science
* Princeton University
* Princeton, New Jersey 08544
* (609) 452-6304 [--enm: no longer this phone or address]
*
* Ported to MS-DOS and VAX/VMS by William D. Norcott
* Digital Equipment Corporation
* Bill.Norcott.nuo.mts.dec.com
* "I appreciate your comments and benchmark results" Bill Norcott
*
* Version: C/1
* Date: 12/10/86
*
* Defines: If your version of "C" does not include a time(2)
* function, define NOTIME. Use a stopwatch to measure
* elapsed wall time. Divide 400000 by the elapsed time
* to get the correct number of iostones/second.
*
* To compile: cc -O io.c -o io
*
* Note: [1] This program should be run without other processes
* competing for system resources. Run it in the dead of
* night if you have to.
*
* [2] This program uses 4 megabytes of disk space. Make
* sure that at least this much space is available on
* your file system before you run the program.
*
* Results: If you get results from a new (machine/operating
* system/disk controller and drive) combination please
* send them to park@princeton. Please include complete
* ********* no! send them to eugene@ames-aurora.arpa*****
* ********* do not bother Arvin as he is no longer @princeton
* information on the machine type, operating system,
* version, disk controller, and disk drives. Also make
* a note of any system modifications that have been
* performed.
* --- Berkeley results:
* Results from Gary Casterline at Berkeley, Bill Norcott at Digital,
* Vasu Subramanian at Digital
*
* machine iostone/s stddev configuration (comment)
* ---------- --------- ---------- -------------------------------------
* 20 MHz 386 1769 n/a MS-DOS 3.3, Rodime 3259T 210MB (SCSI)
* Adaptec 1542B SCSI controller (16-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* 480 K writethrouh disk cache
* my 80386 PC., W. Norcott 3/11/91
* 20 MHz 386 1709 n/a MS-DOS 3.3, CDC Imprimis 94161-155 (SCSI)
* Adaptec 1542B SCSI controller (16-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* 480 K writethrouh disk cache
* my 80386 PC., W. Norcott 2/25/91
* 20 MHZ 386 1606 n/a MS-DOS 3.3, Seagate ST-296N (SCSI),
* Seagate ST-01 SCSI controller (8-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* 480K write through disk cache, 29% hit rate
* my 80386 PC, W. Norcott 3/22/90
* 20 MHz 386 1526 n/a MS-DOS 3.3, Rodime 3259T 210 MB (SCSI)
* Adaptec 1542B SCSI controller (16-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* NO disk cache
* my 80386 PC., W. Norcott 2/25/91
* 20 MHz 386 1311 n/a MS-DOS 3.3, CDC Imprimis 94161-155 (SCSI)
* Adaptec 1542B SCSI controller (16-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* NO disk cache
* my 80386 PC., W. Norcott 2/25/91
* 20 MHz 386 1204 n/a MS-DOS 3.3, Seagate ST296N (SCSI)
* Adaptec 1542B SCSI controller (16-bit)
* 4 MB, 80 nsec main memory, no CPU cache
* NO disk cache
* my 80386 PC., W. Norcott 2/25/91
* VAX 3500 1120 n/a VMS V5.3, VAX C 3.0, RA70, RQDX3, Q-bus,
* NO CACHE, synch I/O, W. Norcott 3/21/90
* VAX 3500 1892 n/a VMS V5.3, VAX C 3.0, RA82, KDA50, Q-bus,
* NO CACHE, synch I/O, W. Norcott 3/22/90
* VAX 3500 80,000 n/a VMS V5.3, VAX C 3.0, RA70, RQDX3, Q-bus,
* NO CACHE, asynch I/O, W. Norcott 3/21/90
* VAX 8800 200,000 n/a VMS V5.3, VAX C 3.0, RA90, HSC70, VAXBI bus,
* NO CACHE, asynch I/O, W. Norcott 3/22/90
* DS3100 4651 n/a RZ55/24M/ULTRIX V4.0
* DS5000 11764 n/a RZ57/56M/ULTRIX V3.1D
* VS2000 1568 n/a RD54/6M/ULTRIX V4.0
* VAX3500 1809 n/a RD54/16M/ULTRIX V4.0
* VAX3600 8888 n/a RA82/32M/ULTRIX V3.0
* VAX6210 30769 n/a RA81/64M/ULTRIX V4.0
* vax 11/750 1988.200 (27.408) RA81/Unibus/uda50
* dec 3100 2368.000 (158.294) scsi (ask rusty about smelt)
* dec 3max 3933.600 (131.586) scsi (ask brad about yaya)
* dec 5400 13086.400 (492.755) RA90/qbus/kda50 (ask brad about icw)
* sun 4/330 24631.900 (2095.237) scsi (ask kyle about the loaner)
*
* --- iostone.c source code:
*
* --- MODIFICATION HISTORY:
*
* 2/25/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com)
* ANSI-fy and try with Turbo C++ compiler
* 3/21/90 William D. Norcott (norcott@vmsdev.enet.dec.com), STAR::NORCOTT
* Digital Equipment Corporation, VMS Development
* Port this thing to VAX/VMS V5.x using VAX C 3.x
*
* 3/22/90 William D. Norcott (norcott@vmsdev.enet.dec.com), STAR::NORCOTT
* Digital Equipment Corporation, VMS Development
* Port this thing to MS-DOS 3.3 using Borland Turbo C V1.0
*
*
* . 3/20/90 Alex Bronstein (Alex@decwrl.dec.com): modified to let the user
* give the name of the temporary file as a command line argument. If no
* name is given, default to the old hardwired name.
*
*/
#ifdef __MSDOS__ /* Turbo C define this way for PCs... */
#define MSDOS /* Microsoft C defines this */
#endif
/* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */
#ifdef VMS_POSIX
#undef VMS
#define ANSI_RANDOM 1
#endif
#ifdef MSDOS
#define ANSI_RANDOM 1
#endif
#ifdef VMS
#define ANSI_RANDOM 1
#endif
#ifdef VMS
#include <math.h>
#include <unixio.h>
#define VMS_ASYNC_IO "fop = cbt, dlt, tmp", \
"rop = asy", \
"mbc=32", \
"mbf=12", \
"alq=8192", \
"mrs=8192", \
"rfm=fix"
#define VMS_SYNC_IO "fop = cbt, dlt, tmp", \
"mbc=32", \
"mbf=12", \
"alq=8192", \
"mrs=8192", \
"rfm=fix"
#define VMS_CREAT_OPTIONS VMS_SYNC_IO
#endif
#define FILESIZE (4L*1024L*1024L) /*size of file in bytes*/
#ifdef MSDOS
#define MAXBUFFERSIZE 65536 /*maximum buffer size*/
#else
#define MAXBUFFERSIZE (64L*1024L) /*maximum buffer size*/
#endif
#define NBLOCKSIZES 9 /*number of different block sizes*/
#define SEED 34710373L /*random number generator seed*/
#define CONST 100000L /*iostone normalization constant*/
#define ITER 4 /*number of iterations of the code*/
/* Define only one of the following two.*/
/*#define NOTIME /*define if no time function in
library*/
#define TIME /*Use time(2)function*/
#define MAXNAMESIZE 1000 /* max # of characters in filename */
char filename [MAXNAMESIZE]; /* name of temporary file */
#ifdef VMS
char *default_filename="iostone_temp_file"; /*default name of temporary file*/
#else
#ifdef MSDOS
char *default_filename="iostone.tmp"; /*default name of temporary file*/
#else
char *default_filename="/tmp/iostone_temp_file"; /*default name of temporary file*/
#endif
#endif
#ifdef MSDOS
char *buffer;
#else
char buffer [MAXBUFFERSIZE]; /*a temporary data buffer*/
#endif
unsigned int nbytes; /*number of bytes transferred*/
int fd; /*file descriptor*/
long offset; /*file offset*/
int i,j,k; /*counter variables*/
long bsize [NBLOCKSIZES]; /*array for different block sizes*/
int bfreq [NBLOCKSIZES]; /*number of accesses for each block*/
#ifdef TIME
long time();
long starttime1, starttime2;
long writetime;
long totaltime;
#endif
main(argc,argv)
int argc;
char *argv[];
{
printf("IOSTONE: Disk I/O Test.\n");
printf("\tby Alvin Park\t\tMS-DOS & VMS versions by Bill Norcott 3/22/90\n");
#ifdef MSDOS
buffer = (char *) malloc(MAXBUFFERSIZE);
#endif
if (argc > 2) {
printf("usage: %s filename \nor just: %s\nto use the default temporary file: %s\n", argv[0], argv[0], default_filename);
exit(1);
} else if (argc == 2) {
strcpy(filename,argv[1]);
} else {
strcpy(filename,default_filename);
}
printf("Now doing I/O test on: %s (Have at least 4 MB free there...)\n",filename);
printf("\nWriting the 4 MB file...");
#ifdef TIME
starttime1 = time(0);
#endif
init();
#ifdef TIME
writetime = time(0) - starttime1;
printf("%d seconds", writetime);
#endif
/*start timing*/
#ifdef NOTIME
printf("start timing\n");
#endif
printf("\nStarting random read tests...");
starttime2 = time(0);
for(k=0; k<ITER; k++) /*perform string of file operations*/
readswrites();
/*stop timer*/
#ifdef NOTIME
printf("stop timing\n");
#endif
#ifdef TIME
totaltime = time(0) - starttime2;
printf("elapsed read time = %ld\n", totaltime);
if(totaltime!=0)
printf("This machine benchmarks at %ld iostones/second\n",
(long) (CONST*ITER)/totaltime);
#endif
#ifdef MSDOS
unlink(filename); /* delete the file */
free(buffer); /* deallocate the memory */
#endif
return 0;
}
init(){
/* create a temporary file*/
#ifdef VMS
if((fd = creat(filename, 0640, VMS_CREAT_OPTIONS))<0){
printf("init: Cannot create temporary file\n");
exit(1);
}
/*To both read and write the file*/
/*it must be closed then opened*/
#else
if((fd = creat(filename, 0640))<0){
printf("init: Cannot create temporary file\n");
exit(1);
}
/*To both read and write the file*/
/*it must be closed then opened*/
close(fd);
if((fd = open(filename,2))<0){
printf("init: Cannot open temporary file\n");
exit(1);
}
/*Unlink the file so that it will*/
/*disappear when the program*/
/*terminates.*/
/* for MSDOS, unlink when done */
#ifndef MSDOS
unlink(filename);
#endif
#endif
lseek(fd,0L,0); /*write initial portion of file*/
for(i=0; i<(FILESIZE)/4096; i++){
if((nbytes = write(fd, buffer, 4096))<0){
printf("init: error writing block\n");
exit(1);
}
}
/*set file block sizes and access*/
/*frequencies.*/
bsize[0] = 256; bfreq[0] = 128;
bsize[1] = 512; bfreq[1] = 64;
bsize[2] = 1024; bfreq[2] = 64;
bsize[3] = 2048; bfreq[3] = 64;
bsize[4] = 4096; bfreq[4] = 32;
bsize[5] = 8192; bfreq[5] = 16;
bsize[6] = 16384; bfreq[6] = 8;
bsize[7] = 32768; bfreq[7] = 4;
bsize[8] = 65536; bfreq[8] = 4;
#ifdef ANSI_RANDOM
srand(SEED); /*initialize random number generator*/
#else
random(SEED); /*initialize random number generator*/
#endif
return 0;
}
readswrites(){
for(j=0; j<NBLOCKSIZES; j++){
for(i=0; i<bfreq[j]; i++){
#ifdef ANSI_RANDOM
offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]);
#else
offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]);
#endif
lseek(fd,offset,0);
if((nbytes = read(fd, buffer, bsize[j]))<0){
printf("readwrites: read error\n");
exit(1);
}
#ifdef ANSI_RANDOM
offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]);
#else
offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]);
#endif
lseek(fd, offset, 0);
if((nbytes = read(fd, buffer, bsize[j]))<0){
printf("readswrites: read error\n");
exit(1);
}
#ifdef ANSI_RANDOM
offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]);
#else
offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]);
#endif
lseek(fd, offset, 0);
if((nbytes = write (fd, buffer, bsize [j]))<0){
printf("readswrites: write error\n");
exit(1);
}
}
}
return 0;
}tbray@watsol.waterloo.edu (Tim Bray) (03/27/91)
norcott@databs.enet.dec.com (Bill Norcott) writes:
Attached is my PORTABLE version of Alvin Park's IOstone benchmark of
random acccess file I/O.
* [2] This program uses 4 megabytes of disk space. Make
* sure that at least this much space is available on
* your file system before you run the program.
Don't know about MS/DOS, but on most modern Unix systems, and I'm pretty
sure on VMS too, lots of quick "seeks" in a 4-Mb file will result in
the whole file quickly migrating into the file system cache.
The results from this program are interesting and probably very useful
in predicting the performance of certain classes of application; what is
being measured is the efficiency of the filesys cache implementation;
the results are likely pretty well independent of the performance of the
underlying disk hardware.
Cheers, Tim Bray, Open Text Systems