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;
}

Reply via email to