Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <inttypes.h>
- #include <sys/time.h>
- #include <sys/uio.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include <dirent.h>
- #include <string.h>
- #include <pthread.h>
- #include <errno.h>
- #include <numa.h>
- #define RWF_UNCACHED 0x80
- static int random_io = 0;
- static unsigned long long mtime_since(const struct timeval *s,
- const struct timeval *e)
- {
- long long sec, usec;
- sec = e->tv_sec - s->tv_sec;
- usec = (e->tv_usec - s->tv_usec);
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
- sec *= 1000;
- usec /= 1000;
- return sec + usec;
- }
- static unsigned long long mtime_since_now(struct timeval *tv)
- {
- struct timeval end;
- gettimeofday(&end, NULL);
- return mtime_since(tv, &end);
- }
- struct thread_data {
- pthread_t thread;
- pthread_barrier_t barrier;
- int fd;
- volatile int done;
- int rwf_flags;
- int bs;
- int reading;
- void *buf;
- unsigned long max_blocks;
- unsigned long bytes;
- };
- static off_t next_off(struct thread_data *d, off_t last_off, int bytes)
- {
- if (random_io) {
- long off = lrand48();
- long block = off % d->max_blocks;
- return block * d->bs;
- }
- return last_off + bytes;
- }
- static void *thread_fn(void *__data)
- {
- struct thread_data *d = __data;
- struct iovec iov = { .iov_len = d->bs };
- const char *msg = d->reading ? "preadv2" : "pwritev2";
- off_t offset = 0;
- struct stat sb;
- if (fstat(d->fd, &sb) < 0) {
- perror("fstat");
- goto done;
- }
- if (random_io)
- d->max_blocks = sb.st_size / d->bs;
- if (posix_memalign(&d->buf, 4096, d->bs))
- goto done;
- iov.iov_base = d->buf;
- pthread_barrier_wait(&d->barrier);
- for (;;) {
- int ret;
- if (d->reading)
- ret = preadv2(d->fd, &iov, 1, offset, d->rwf_flags);
- else
- ret = pwritev2(d->fd, &iov, 1, offset, d->rwf_flags);
- if (ret < 0) {
- perror(msg);
- break;
- } else if (!ret) {
- break;
- }
- d->bytes += ret;
- offset = next_off(d, offset, ret);
- }
- done:
- d->done = 1;
- return NULL;
- }
- int main(int argc, char *argv[])
- {
- struct timeval tv, start;
- unsigned int bs;
- unsigned long last_bytes = 0, bytes = 0;
- struct thread_data *td;
- int rwf_flags = 0;
- int reading = 1;
- int nr, i;
- if (argc < 5) {
- printf("%s: bs uncached reading <files>\n", argv[0]);
- return 1;
- }
- bs = atoi(argv[1]);
- if (!!atoi(argv[2]))
- rwf_flags |= RWF_UNCACHED;
- reading = !!atoi(argv[3]);
- nr = argc - 4;
- if (!nr) {
- fprintf(stderr, "Need files\n");
- return 1;
- }
- if (!reading)
- random_io = 0;
- td = calloc(nr, sizeof(struct thread_data));
- for (i = 0; i < nr; i++) {
- int flags;
- if (reading)
- flags = O_RDONLY;
- else
- flags = O_WRONLY;
- again:
- td[i].fd = open(argv[4 + i], flags, 0644);
- if (td[i].fd < 0) {
- if (!reading && errno == ENOENT) {
- flags |= O_CREAT;
- goto again;
- }
- perror("open");
- return 1;
- }
- posix_fadvise(td[i].fd, 0, (off_t) -1, POSIX_FADV_RANDOM);
- posix_fadvise(td[i].fd, 0, (off_t) -1, POSIX_FADV_DONTNEED);
- td[i].rwf_flags = rwf_flags;
- td[i].bs = bs;
- td[i].reading = reading;
- }
- printf("Starting %d threads\n", nr);
- for (i = 0; i < nr; i++) {
- pthread_barrier_init(&td[i].barrier, NULL, 2);
- pthread_create(&td[i].thread, NULL, thread_fn, &td[i]);
- pthread_barrier_wait(&td[i].barrier);
- }
- printf("%sing bs %u, uncached %d\n", reading ? "read" : "writ", bs, (rwf_flags & RWF_UNCACHED) != 0);
- gettimeofday(&tv, NULL);
- start = tv;
- do {
- unsigned long mb, msec;
- int done = 0;
- usleep(100000);
- msec = mtime_since_now(&tv);
- bytes = 0;
- for (i = 0; i < nr; i++) {
- bytes += td[i].bytes;
- done += td[i].done;
- }
- if (msec < 1000 && (done != nr))
- continue;
- mb = (bytes - last_bytes) >> 10;
- last_bytes = bytes;
- gettimeofday(&tv, NULL);
- printf("%3llds: %luMB/sec, MB=%lu\n", mtime_since_now(&start) / 1000, mb / msec, (bytes / msec) >> 10);
- if (done == nr)
- break;
- } while (1);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement