C iotest
Jump to navigation
Jump to search
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <time.h>
#define MB (1024 * 1024)
#define REP_INTERVAL 2
char *Block;
char *flname;
long int sz;
long long int lsz, lbytes, tbytes, pos;
int fd, bs, Rsecs;
time_t start, st2, endt;
int elaps, speed;
long int bytes, kbytes;
float perc;
long int MinSpeed, MaxSpeed;
long int Wspeed, Rspeed, Sspeed; /* Write, Read, Search */
char *cp;
long long int i;
long long int count;
int Ln;
/************************************************************************/
void StTest (void)
{
start = time(0L);
st2 = start;
lbytes = 0;
tbytes = 0;
Ln = 0;
MinSpeed = 0;
MaxSpeed = 0;
}
/************************************************************************/
void CalcSpeed (long long bytes, time_t st,time_t en)
{
elaps = en - st;
if (elaps <= 0)
speed = 0;
else
speed = (unsigned long int) ((bytes / 1024) / elaps);
if (speed > MaxSpeed || MaxSpeed == 0)
MaxSpeed = speed;
if (speed < MinSpeed || MinSpeed == 0)
MinSpeed = speed;
if ((++Ln % 15) == 0)
printf("\n");
}
/************************************************************************/
int main (int argc,char **argv)
{
int flags;
if (argc < 4)
{
fprintf(stderr,"Ruurd Beerstra's simple I/O performance Measurement Tool.\n");
fprintf(stderr,"Usage: %s filename MBs BlockSize SeekTime\n",argv[0]);
fprintf(stderr,"Creates the named file 'filename' and writes BlockSize KB size blocks\n");
fprintf(stderr,"until the number of MB's is reached.\n");
fprintf(stderr,"Then it reads the file sequentially, followed by SeekTime\n");
fprintf(stderr,"seconds of random access. It reports all the achieved speeds. So:\n\n");
fprintf(stderr,"%s garbage 5000 32 60\n\n",argv[0]);
fprintf(stderr,"Creates a file 5000 MB in size by writing 32KB blocks, reports the speed,\n");
fprintf(stderr,"reads the file sequentially, reports the speed, then reads random\n");
fprintf(stderr,"32 KB blocks from the file for 60 seconds and reports the speed.\n");
fprintf(stderr,"The file is removed aty the end of the proces.\n");
fprintf(stderr,"When an environment variable O_DIRECT exists, the file is opened in DIRECT mode.\n");
fprintf(stderr,"When an environment variable O_CIO exists, the file is opened in Concurent I/O mode.\n");
fprintf(stderr,"When an environment variable NULL_BLOCK exists, the file contains only bytes with\n");
fprintf(stderr,"the value zero, otherwise a randomly filled block is used.\n");
exit(1);
}
flname = argv[1];
sscanf(argv[2],"%d",&sz); /* Size of the file (MB) */
sscanf(argv[3],"%d",&bs); /* Block size (KB) */
sscanf(argv[4],"%d",&Rsecs); /* Minutes to read random */
lsz = (long long int) sz * (long long) MB;
bs = bs * 1024;
Block = calloc(bs,1);
if (!Block)
{
printf("Out of memory\n");
exit(1);
}
srand(time(0L));
count = ((lsz / ((long long) bs))) + 1;
printf("Creating file %s of %ld MB (%lld blocks of %d bytes, or %lld bytes)...\n",flname,sz,count,bs,lsz);
if (getenv("NULL_BLOCK") == NULL)
{
printf("Using a block filled with RANDOM data\n");
cp = Block;
for (i = 0; i < bs; i++) /* Initialize with garbage */
*cp++ = (unsigned char) (drand48() * 256);
}
else
printf("Using a block filled with NULL bytes\n");
printf("Removing file %s...",flname); fflush(stdout);
unlink(flname);
printf("Done\n");
flags = O_CREAT | O_RDWR;
if (getenv("O_DIRECT"))
flags |= O_DIRECT;
if (getenv("O_CIO"))
flags |= O_CIO;
fd = open64(flname,flags,0666);
if (fd < 0)
{
perror("open");
exit(1);
}
StTest();
for (i = 0; i < count; i++)
{
if (write(fd,Block,bs) != bs)
{
perror("write");
exit(1);
}
lbytes += bs;
tbytes += bs;
endt = time(0L);
if (endt >= st2 + REP_INTERVAL)
{
perc = (float) ((tbytes * 100) / lsz);
CalcSpeed(lbytes,st2,endt);
printf("Sequential write speed: %d KB/sec, %3.2f%% done \r",speed,perc);
fflush(stdout);
lbytes = 0;
st2 = endt;
}
}
CalcSpeed(tbytes,start,time(0L));
printf("\nSummary: wrote %ldMB in %d secs: %ld KB/sec, Min=%d, Max=%d\n",sz,elaps,speed,MinSpeed,MaxSpeed);
printf("Syncing file (flush cache)..."); fflush(stdout);
fsync(fd);
CalcSpeed(tbytes,start,time(0L));
printf("done! Adjusted speed (with sync): %ld KB/sec, Min=%d, Max=%d\n",speed,MinSpeed,MaxSpeed);
Wspeed = speed;
printf("Reading sequentially...\n");
llseek(fd,0,0);
StTest();
while (read(fd,Block,bs) == bs)
{
lbytes += bs;
tbytes += bs;
endt = time(0L);
if (endt >= st2 + REP_INTERVAL)
{
perc = (float) ((tbytes * 100) / lsz);
CalcSpeed(lbytes,st2,endt);
printf("Sequential read speed: %d KB/sec, %3.2f%% done \r",speed,perc);
fflush(stdout);
lbytes = 0;
st2 = endt;
}
}
CalcSpeed(tbytes,start,time(0L));
printf("\nSummary: Read %ldMB in %d secs: %ld KB/sec, Min=%d, Max=%d\n",sz,elaps,speed,MinSpeed,MaxSpeed);
Rspeed = speed;
printf("Reading random positions of %d KB\n",bs / 1024);
StTest();
Rsecs = time(0L) + Rsecs;
while (time(0L) < Rsecs)
{
pos = (lsz * drand48());
pos = pos / 4096; /* Afronden op 4KB page */
pos = pos * 4096;
llseek(fd,pos,0); /* Large seek */
if (read(fd,Block,bs) != bs) /* groot block lezen. */
perror("Read error");
lbytes += bs;
tbytes += bs;
count++;
endt = time(0L);
if (endt >= st2 + REP_INTERVAL)
{
CalcSpeed(lbytes,st2,endt);
printf("Random read speed: %d KB/sec, %lld Reads of %ld KB \r",speed,count,bs / 1024);
fflush(stdout);
lbytes = 0;
count = 0;
st2 = endt;
}
}
endt = time(0L);
CalcSpeed(tbytes,start,endt);
printf("\nSummary: Read %ldMB in %d secs: %ld KB/sec, Min=%d, Max=%d\n",tbytes / MB,elaps,speed,MinSpeed,MaxSpeed);
Sspeed = speed;
printf("Einde test: Write: %ld KB/sec, Read: %ld KB/sec, Seek: %ld KB/sec\n",Wspeed,Rspeed,Sspeed);
printf("Removing file %s\n",flname);
unlink(flname);
exit(0);
}
/************************************************************************/