v17i065: iozone - sequential file I/O benchmark fo UNIX, VMS & DOS, Part01/01
Bill Norcott
norcott at databs.enet.dec.com
Sat Mar 23 07:28:46 AEST 1991
Submitted-by: Bill Norcott <norcott at databs.enet.dec.com>
Posting-number: Volume 17, Issue 65
Archive-name: iozone/part01
Attached is a benchmark called IOzone which I have written. It was inspired
by Alvin Park's IOstone benchmark (which tests random access I/O). IOzone
tests sequential file I/O using the C language. It writes, then reads, a
sequential file of fixed length records, and measures the read & write
rates in bytes per second. The default is to create a 1 megabyte file
consisting of 2048, 512-byte records -- however, these parameters can be
changed from the command line. On UNIX systems, the results will be influenced
by the effect of the buffer cache -- however, we can largely negate the
effect of caching by using a file size greater than twice the size of the
cache. This will allow a fairer comparison between various disk drives
attached to the system. IOzone IS NOT a direct test of disk performance. Its
results are a combination of disk speed, CPU speed, amount of cache, and the
efficiency of the C compiler & runtime library. This is also true of IOstone,
in fact I intend this program as a companion piece to IOstone.
This benchmark is portable and has been tested on these operating systems:
VAX/VMS V5.4
Ultrix V4.1
MS-DOS V3.1
OSF/1
IOZONE.C is free and in the public domain. I would appreciate your
comment and test results.
Bill Norcott (Bill.Norcott.nuo.mts.dec.com)
------------------------------ CUT HERE -----------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents: iozone.c
# Wrapped by kent at sparky on Fri Mar 22 15:25:03 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive."'
if test -f 'iozone.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'iozone.c'\"
else
echo shar: Extracting \"'iozone.c'\" \(7723 characters\)
sed "s/^X//" >'iozone.c' <<'END_OF_FILE'
X/*
X* "IO Zone" Benchmark Program
X*
X* Author: Bill Norcott (Bill.Norcott at nuo.mts.dec.com)
X* 4 Dunlap Drive
X* Nashua, NH 03060
X*
X* "Copyright 1991, William D. Norcott
X* This is free software. License to freely use and distribute this
X* software is hereby granted by the author, subject to the condition
X* that this copyright notice remains intact."
X*
X* "This test writes a 4 MEGABYTE sequential file in 512 byte chunks, then
X* rewinds it and reads it back. [The size of the file should be
X* big enough to factor out the effect of any disk cache.]
X*
X* The file is written (filling any cache buffers), and then read. If the
X* cache is >= 4 MB, then most if not all the reads will be satisfied from
X* the cache. However, if it is less than or equal to 2 MB, then NONE of
X* the reads will be satisfied from the cache. This is becase after the
X* file is written, a 2 MB cache will contain the upper 2 MB of the test
X* file, but we will start reading from the beginning of the file (data
X* which is no longer in the cache)
X* In order for this to be a fair test, the length of the test file must
X* be AT LEAST 2X the amount of disk cache memory for your system. If
X* not, you are really testing the speed at which your CPU can read blocks
X* out of the cache (not a fair test)
X*
X* IOZONE does NOT test the raw I/O speed of your disk or system. It
X* tests the speed of sequential I/O to actual files. Therefore, this
X* measurement factors in the efficiency of you machines file system,
X* operating system, C compiler, and C runtime library. It produces a
X* measurement which is the number of bytes per second that your system
X* can read or write to a file. For UNIX systems I call fsync() to force
X* the writes to disk. This gives a test of the time it takes to
X* actually get data onto the disk.
X*
X* This program has been ported and tested on the following computer
X* operating systems:
X* VAX/VMS V5.4, Ultrix V4.1, OSF/1 and MS-DOS 3.3"
X*
X* --- MODIFICATION HISTORY:
X*
X* 3/7/91 William D. Norcott (Bill.Norcott at nuo.mts.dec.com)
X* created
X* 3/22/91 Bill Norcott tested on OSF/1 ... it works
X*
X*/
X#ifdef __MSDOS__ /* Turbo C define this way for PCs... */
X#define MSDOS /* Microsoft C defines this */
X#endif
X/* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */
X#ifdef VMS_POSIX
X#undef VMS
X#define ANSI_RANDOM 1
X#endif
X#ifdef MSDOS
X#define ANSI_RANDOM 1
X#endif
X
X#if defined(VMS)
X#define ANSI_RANDOM 1
X#include <math.h>
X#include <unixio.h>
X#include <ssdef.h>
X#include <file.h>
X
X#elif defined(MSDOS)
X#include <fcntl.h>
X#elif defined(unix)
X#include <sys/file.h>
X#include <limits.h>
X#endif
X
X#define MEGABYTES 1 /* number of megabytes in file */
X#define RECLEN 512 /* number of bytes in a record */
X#define FILESIZE (MEGABYTES*1024*1024) /*size of file in bytes*/
X#define NUMRECS FILESIZE/RECLEN /* number of records */
X#define MAXBUFFERSIZE 16*1024 /*maximum buffer size*/
X#define TOOFAST 10
X#define USAGE "\tUsage:\tiozone [megabytes] [record_length] [[path]filename]\n\n"
X#define THISVERSION "V1.01"
X
X/* Define only one of the following two.*/
X/*#define NOTIME define if no time function in library*/
X#define TIME /*Use time(2)function*/
X
X#define MAXNAMESIZE 1000 /* max # of characters in filename */
X
Xmain(argc,argv)
X int argc;
X char *argv[];
X{
Xint fd;
Xchar filename [MAXNAMESIZE]; /* name of temporary file */
X#ifdef VMS
Xchar *default_filename="iozone_temp_file"; /*default name of temporary file*/
X#else
X#ifdef MSDOS
Xchar *default_filename="iozone.tmp"; /*default name of temporary file*/
X#else
Xchar *default_filename="/tmp/iozone_temp_file"; /*default name of temporary file*/
X#endif
X#endif
X#ifdef MSDOS
Xchar *buffer;
X#else
Xchar buffer [MAXBUFFERSIZE]; /*a temporary data buffer*/
X#endif
Xint i, status;
Xunsigned long megabytes = MEGABYTES, goodmegs;
Xunsigned long reclen = RECLEN, goodrecl;
Xunsigned long filesize = FILESIZE;
Xunsigned long numrecs = NUMRECS;
X
X#ifdef TIME
X long time();
X long starttime1, starttime2;
X long writetime;
X long totaltime;
X
X#endif
X
X#ifdef MSDOS
X buffer = (char *) malloc(MAXBUFFERSIZE);
X#endif
X
X printf("\n\tIOZONE: Performance Test of Sequential File I/O -- %s\n",
X THISVERSION);
X printf("\t\tBy Bill Norcott\n\n");
X
X strcpy(filename,default_filename);
X switch (argc) {
X case 1: /* no args, take all defaults */
X printf(USAGE);
X break;
X case 2: /* <megabytes|filename> */
X i = atoi(argv[1]); if (i) {
X megabytes = i;
X } else {
X strcpy(filename,argv[1]);
X }
X break;
X case 3: /* <megabytes> <reclen|filename> */
X filesize = atoi(argv[1]);
X i = atoi(argv[2]); if(i) {
X reclen = (unsigned) i;
X } else {
X strcpy(filename,argv[2]);
X }
X break;
X case 4: /* <megabytes> <reclen> <filename> */
X filesize = atoi(argv[1]);
X reclen = atoi(argv[2]);
X strcpy(filename,argv[3]);
X break;
X default:
X printf(USAGE);
X exit(1);
X
X }
X printf("\tSend comments to:\tBill.Norcott at nuo.mts.dec.com\n\n");
X
X filesize = megabytes*1024*1024;
X numrecs = filesize/reclen;
X if (reclen > MAXBUFFERSIZE) {
X printf("Error: Maximum record length is %d bytes\n", MAXBUFFERSIZE);
X }
X printf("\tIOZONE writes a %ld Megabyte sequential file consisting of\n",
X megabytes);
X printf("\t%ld records which are each %ld bytes in length.\n",
X numrecs, reclen);
X printf("\tIt then reads the file. It prints the bytes-per-second\n");
X printf("\trate at which the computer can read and write files.\n\n");
X printf("\nWriting the %ld Megabyte file, '%s'...", megabytes, filename);
X
X#ifdef TIME
X starttime1 = time(0);
X#endif
X if((fd = creat(filename, 0640))<0){
X printf("Cannot create temporary file\n");
X exit(1);
X }
X for(i=0; i<numrecs; i++){
X write(fd, buffer, (unsigned) reclen);
X }
X
X#ifdef TIME
X writetime = time(0) - starttime1;
X printf("%d seconds", writetime);
X#endif
X close(fd);
X#ifdef VMS
X if((fd = open(filename, O_RDONLY, 0640))<0){
X printf("Cannot open temporary file for read\n");
X exit(1);
X#elif defined(MSDOS)
X if((fd = open(filename, O_RDONLY, 0640))<0){
X printf("Cannot open temporary file for read\n");
X exit(1);
X#else
X if((fd = open(filename, O_RDONLY))<0){
X printf("Cannot open temporary file for read\n");
X exit(1);
X#endif
X }
X
X /*start timing*/
X#ifdef NOTIME
X printf("start timing\n");
X#endif
X
X printf("\nReading the file...");
X starttime2 = time(0);
X for(i=0; i<numrecs; i++) {
X if(read(fd, buffer, (unsigned) reclen) < 0)
X perror("Read error");
X }
X#ifdef NOTIME
X printf("stop timing\n");
X#endif
X#ifdef TIME
X totaltime = time(0) - starttime2;
X
X printf("%d seconds\n", totaltime);
X if(totaltime!=0)
X {
X printf("\nIOZONE performance measurements:\n");
X printf("\t%ld bytes/second for writing the file\n",
X (long) ((numrecs*reclen)/writetime) );
X printf("\t%ld bytes/second for reading the file\n",
X (long) ((numrecs*reclen)/totaltime) );
X if (totaltime < TOOFAST) {
X goodmegs = (TOOFAST/totaltime)*2*megabytes;
X printf("\nThis machine is fast (or is using a disk cache)!\n");
X printf("You will get a more accurate measure of its\n");
X printf("performance by re-running IOZONE using the command:\n");
X printf("\n\tiozone %d ", goodmegs);
X printf("\t(i.e., file size = %d megabytes)\n", goodmegs);
X }
X } else {
X goodrecl = reclen/2;
X printf("\nI/O error during read. Try again with the command:\n");
X printf("\n\tiozone %d %d ",megabytes, (int) goodrecl);
X printf("\t(i.e. record size = %d bytes)\n", (int) goodrecl);
X }
X#endif
X close(fd);
X#ifndef VMS
X unlink(filename); /* delete the file */
X /*stop timer*/
X#endif
X#ifdef MSDOS
X free(buffer); /* deallocate the memory */
X#endif
X#ifdef VMS
Xreturn SS$_NORMAL;
X#else
Xreturn 0;
X#endif
X}
X
X
END_OF_FILE
if test 7723 -ne `wc -c <'iozone.c'`; then
echo shar: \"'iozone.c'\" unpacked with wrong size!
fi
# end of 'iozone.c'
fi
echo shar: End of archive.
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list