Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 304777 Details for
Bug 445560
GFS2: fstest using fsync() after each write much slower than open O_SYNC or using fdatasync()
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
fstest - test program to simulate sync writes for messaging loads
fstest.c (text/x-csrc), 7.12 KB, created by
Rob Kenna
on 2008-05-07 16:08:38 UTC
(
hide
)
Description:
fstest - test program to simulate sync writes for messaging loads
Filename:
MIME Type:
Creator:
Rob Kenna
Created:
2008-05-07 16:08:38 UTC
Size:
7.12 KB
patch
obsolete
>/* > * Single file multiple sequential osync write performance benchmark. > */ > >#include <ctype.h> >#include <fcntl.h> >#include <limits.h> >#include <pthread.h> >#include <signal.h> >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >#include <time.h> >#include <unistd.h> >#include <sys/time.h> > >struct data { > pthread_t id; > off_t offset; > long elapsed; > long min_latency; > long max_latency; > long long tot_latency; >}; > >static char name[256]; >static char *buf; >static const char *progname; >static int bsize = 4096; >static int size = 4*1024*1024; >static int blocks; >static int append = 0; >static int dsync = 0; >static int async = 0; >static int random_offset = 0; >static int sync_blocks = -1; >static int do_lock = 0; >static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; > >static void >usage(void) >{ > printf("Usage: %s [-A] [-a] [-d] [-b block size] [-r] " > "[-S # blocks ] [-s file size] [-t # threads]\n" > " Block and file sizes can be suffixed with k, m\n" > " -A run in async mode, fsync at the end (default is osync)\n" > " -S fsync after this many blocks in async mode\n" > " -a append to file instead of overwriting it\n" > " -d data only sync\n" > " -r use random offsets in file\n" > " -l lock file access before write\n", > progname); > exit(0); >} > >static void >cleanup(int sig) >{ > if (name[0]) > unlink(name); > exit(1); >} > >static void * >writer(void *arg) >{ > int fd, flags, i; > time_t start; > struct data *data = arg; > > flags = O_WRONLY | ((dsync || async) ? 0 : O_SYNC); > if ((fd = open(name, flags)) < 0) { > perror("open"); > exit(1); > } > if (!append && !random_offset && > lseek(fd, data->offset, SEEK_SET) != data->offset) { > perror("lseek"); > exit(1); > } > start = time(NULL); > for (i = 0; i < blocks; i++) { > long latency; > struct timeval tv1, tv2; > > if (do_lock && pthread_mutex_lock(&mutex)) { > perror("pthread_mutex_lock"); > exit(1); > } > if (append && lseek(fd, 0, SEEK_END) < 0) { > perror("lseek"); > exit(1); > } > if (gettimeofday(&tv1, NULL) < 0) { > perror("gettimeofday"); > exit(1); > } > if (random_offset) { > off_t offset = ((data->offset + drand48() * blocks * bsize) / bsize) * bsize; > > if (lseek(fd, offset, SEEK_SET) != offset) { > perror("lseek"); > exit(1); > } > } > if (write(fd, buf, bsize) != bsize) { > perror("write"); > exit(1); > } > if (dsync && fdatasync(fd) < 0) { > perror("fdatasync"); > exit(1); > } > if (sync_blocks > 0 && i % sync_blocks == 0 && fsync(fd) < 0) { > perror("fsync"); > exit(1); > } > if (gettimeofday(&tv2, NULL) < 0) { > perror("gettimeofday"); > exit(1); > } > if (do_lock && pthread_mutex_unlock(&mutex)) { > perror("pthread_mutex_unlock"); > exit(1); > } > latency = ((tv2.tv_usec - tv1.tv_usec) > + (tv2.tv_sec - tv1.tv_sec) * 1000000); > data->tot_latency += latency; > if (latency < data->min_latency) > data->min_latency = latency; > if (latency > data->max_latency) > data->max_latency = latency; > } > if (async && > (sync_blocks <= 0 || blocks % sync_blocks) && fsync(fd) < 0) { > perror("fsync"); > exit(1); > } > if (close(fd) < 0) { > perror("close"); > exit(1); > } > data->elapsed = time(NULL) - start; > return (NULL); >} > >static char * >rate(int size, int elapsed) >{ > char *buf; > double r; > > if (elapsed <= 0) > return "N/A"; > buf = malloc(1024); > if (!buf) { > perror("malloc"); > exit(1); > } > r = (double)size / elapsed; > if (r >= 1024*1024) > sprintf(buf, "%.2f MB/s", r / (1024*1024)); > else if (r >= 1024) > sprintf(buf, "%.2f KB/s", r / 1024); > else > sprintf(buf, "%.2f B/s", r); > return (buf); >} > >int >main(int argc, char **argv) >{ > const char *tmpl = "test.XXXXXX"; > int bufsize, c, fd, i, *p; > int min = INT_MAX, max = -1, total = 0; > int num_threads = 1; > long min_latency = LONG_MAX; > long max_latency = 0; > long long tot_latency = 0; > struct data *data; > > progname = argv[0]; > while ((c = getopt(argc, argv, "aAb:dlS:rs:t:")) != EOF) { > switch (c) { > > case 'b': > case 's': > p = (c == 'b') ? &bsize : &size; > if (sscanf(optarg, "%d", p) != 1) > usage(); > c = optarg[strlen(optarg) - 1]; > if (!isdigit(c)) { > if (c == 'k') > *p *= 1024; > else if (c == 'm') > *p *= 1024*1024; > else > usage(); > } > break; > > case 't': > if (sscanf(optarg, "%d", &num_threads) != 1) > usage(); > break; > > case 'a': > append = 1; > do_lock = 1; > printf("Append mode enabled\n"); > break; > > case 'd': > dsync = 1; > printf("Data-only sync mode enabled\n"); > break; > > case 'A': > printf("Async mode enabled, fsync at end\n"); > async = 1; > dsync = 0; > break; > > case 'S': > if (sscanf(optarg, "%u", &sync_blocks) != 1) > usage(); > printf("Will fsync every %u blocks\n", sync_blocks); > break; > > case 'r': > printf("Random offset mode enabled\n"); > random_offset = 1; > break; > > case 'l': > printf("Using our own locks\n"); > do_lock = 1; > break; > > default: > usage(); > } > } > if (size <= 0) { > fprintf(stderr, "ERROR: invalid file size\n"); > exit(1); > } > blocks = size / bsize / num_threads; > if (blocks == 0) { > fprintf(stderr, "ERROR: # blocks is 0\n"); > exit(1); > } > data = malloc(sizeof(struct data) * num_threads); > if (!data) { > perror("malloc"); > exit(1); > } > bufsize = bsize; > if (bufsize < 4096) > bufsize = 4096; > buf = malloc(bufsize); > if (!buf) { > perror("malloc"); > exit(1); > } > signal(SIGINT, cleanup); > signal(SIGTERM, cleanup); > strcpy(name, tmpl); > if ((fd = mkstemp(name)) < 0) { > perror("mkstemp"); > exit(1); > } > memset(buf, 0, bufsize); > printf("Creating file..."); > fflush(stdout); > if (!append) { > for (i = 0; i < size; i += bufsize) { > if (write(fd, buf, bufsize) != bufsize) { > perror("write"); > exit(1); > } > } > if (fsync(fd) < 0) { > perror("fsync"); > exit(1); > } > } > if (close(fd) < 0) { > perror("close"); > exit(1); > } > printf("done\n"); > printf("%d thread(s) will write %d block(s) each " > "in %d byte chunks\n", > num_threads, blocks, bsize); > for (i = 0; i < num_threads; i++) { > struct data *p = data + i; > > p->offset = (off_t)blocks * bsize * i; > p->min_latency = LONG_MAX; > p->max_latency = 0; > p->tot_latency = 0; > if (pthread_create(&p->id, NULL, writer, p)) { > perror("pthread_create"); > exit(1); > } > } > for (i = 0; i < num_threads; i++) { > struct data *p = data + i; > > if (pthread_join(p->id, NULL)) { > perror("pthread_join"); > exit(1); > } > total += p->elapsed; > if (p->elapsed < min) > min = p->elapsed; > if (p->elapsed > max) > max = p->elapsed; > tot_latency += p->tot_latency; > if (p->min_latency < min_latency) > min_latency = p->min_latency; > if (p->max_latency > max_latency) > max_latency = p->max_latency; > } > printf("Throughput\n"); > printf(" Min %s\n", rate(blocks * bsize, max)); > printf(" Max %s\n", rate(blocks * bsize, min)); > printf(" Avg %s\n", rate(size, total)); > printf("Latency\n"); > printf(" Min %ld usec %ld msec\n", min_latency, min_latency / 1000); > printf(" Max %ld usec %ld msec\n", max_latency, max_latency / 1000); > printf(" Avg %ld usec %ld msec\n", > (long)(tot_latency / (blocks * num_threads)), > (long)(tot_latency / (blocks * num_threads) / 1000)); > unlink(name); > exit(0); >} > >/* > * Local Variables: > * compile-command: "gcc -O2 -Wall fstest.c -o fstest -lpthread" > * End: > */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 445560
:
304777
|
304795