Bob Miller wrote:
> Just for grins, I wrote a couple of little programs to measure a
> disk's sequential read rate and its seek rate. Try running these
> on your RAIDs - I bet they do a lot better on seeking than
> my disks.
Whoops! Forgot to attach them. Here they are.
--
Bob Miller K<bob>
kbobsoft software consulting
http://kbobsoft.com [EMAIL PROTECTED]
#include <fcntl.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#define BLKSIZE (1024 * 1024)
#define TESTSIZE (1024 * 1024 * 1024)
char buf[BLKSIZE];
int test(const char *path)
{
size_t bytes;
ssize_t nr;
struct timeval before, after;
double seconds, Gbytes, rate, rateMb;
int fd = open(path, O_RDONLY);
if (fd < 0) {
perror(path);
return 1;
}
memset(buf, '\0', sizeof buf);
(void) gettimeofday(&before, NULL);
for (bytes = 0; bytes < TESTSIZE; bytes += nr) {
nr = read(fd, buf, sizeof buf);
if (nr < 0) {
perror("read");
return 1;
}
if (nr == 0) {
fprintf(stderr, "%s: premature EOF at %d bytes\n", path, bytes);
break;
}
if (nr != sizeof buf) {
fprintf(stderr, "Warning: %s short read of %d bytes\n", path, nr);
}
}
(void) gettimeofday(&after, NULL);
seconds = (after.tv_sec - before.tv_sec +
(after.tv_usec - before.tv_usec) / 1000000.0);
Gbytes = bytes / (1024 * 1024 * 1024);
rate = bytes / seconds;
rateMb = rate / (1024 * 1024);
printf("%s: %g Gbytes in %g seconds: %g Mb/second\n",
path, Gbytes, seconds, rateMb);
return 0;
}
int main(int argc, char *argv[])
{
int i, err = 0;
for (i = 1; i < argc; i++) {
err += test(argv[i]);
}
return err;
}
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#define BLKSIZE (4 * 1024)
#define TESTSIZE (1024 * 1024 * 1024)
#define NBLKS (TESTSIZE / BLKSIZE)
#define NSEEKS (32 * 1024)
char buf[BLKSIZE];
off_t offsets[NSEEKS];
void set_up_offsets()
{
int i;
srandom(0x12345678); /* make a repeatable sequence */
for (i = 0; i < NSEEKS; i++)
offsets[i] = (random() % NBLKS) * BLKSIZE;
}
int test(const char *path)
{
size_t seeks;
ssize_t nr;
struct timeval before, after;
double seconds, rate, ms_per_seek;
int fd;
off_t offset;
fd = open(path, O_RDONLY);
if (fd < 0) {
perror(path);
return 1;
}
memset(buf, '\0', sizeof buf);
(void) gettimeofday(&before, NULL);
for (seeks = 0; seeks < NSEEKS; seeks++) {
offset = lseek(fd, offsets[seeks], L_SET);
if (offset == -1) {
perror("lseek");
return 1;
}
nr = read(fd, buf, sizeof buf);
if (nr < 0) {
perror("read");
return 1;
}
if (nr == 0) {
fprintf(stderr, "%s: premature EOF at offset %ld\n", path, offset);
break;
}
if (nr != sizeof buf) {
fprintf(stderr, "Warning: %s short read of %d bytes\n", path, nr);
}
}
(void) gettimeofday(&after, NULL);
seconds = (after.tv_sec - before.tv_sec +
(after.tv_usec - before.tv_usec) / 1000000.0);
rate = seeks / seconds;
ms_per_seek = 1000 / rate;
printf("%s: %d seeks in %g seconds: %g seeks/second, %g ms/seek\n",
path, seeks, seconds, rate, ms_per_seek);
return 0;
}
int main(int argc, char *argv[])
{
int i, err = 0;
set_up_offsets();
for (i = 1; i < argc; i++) {
err += test(argv[i]);
}
return err;
}