diff options
author | Amit Shah <amit.shah@redhat.com> | 2009-03-02 13:07:29 +0530 |
---|---|---|
committer | Amit Shah <amit.shah@redhat.com> | 2009-03-02 13:07:29 +0530 |
commit | 23bd4be5b74f227ceb073f8da213708d5ded2af8 (patch) | |
tree | 9a940b4bf03f2e8374fc84dcadacd5544a19e54a /test-file-zero-alloc-speed.c | |
download | alloc-perf-23bd4be5b74f227ceb073f8da213708d5ded2af8.tar.gz alloc-perf-23bd4be5b74f227ceb073f8da213708d5ded2af8.tar.xz alloc-perf-23bd4be5b74f227ceb073f8da213708d5ded2af8.zip |
First version of file allocation perf measuring program
This program measures performance of creating a file and zeroing it using
a few different methods:
1. using the posix_fallocate() syscall
2. using mmap() and then memset()
3. writing chunks to the file (currently 4k and 8k-sized chunks)
directly calling the Linux fallocate() syscall doesn't yet work; a bug has
been filed earlier for this in the Red Hat Bugzilla, #485487
A few results from running this program on my laptop and on my desktop are put
in the results.txt file.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Diffstat (limited to 'test-file-zero-alloc-speed.c')
-rw-r--r-- | test-file-zero-alloc-speed.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/test-file-zero-alloc-speed.c b/test-file-zero-alloc-speed.c new file mode 100644 index 0000000..8e8fe5c --- /dev/null +++ b/test-file-zero-alloc-speed.c @@ -0,0 +1,177 @@ +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <asm/unistd.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/mman.h> + +#define GB (1024 * 1024 * 1024) + +int do_posix_fallocate(char *name, off_t len) +{ + int r, fd; + struct timeval tv1, tv2; + + unlink(name); + fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + perror("open"); + return -1; + } + + printf("posix-fallocate run time:\n"); + gettimeofday(&tv1, NULL); + r = posix_fallocate(fd, 0, len); + close(fd); + gettimeofday(&tv2, NULL); + if (r < 0) + return r; + printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); + printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); + printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); + + return 0; +} + +#if 1 +int do_fallocate(char *name, off_t len) +{ + int r, fd; + struct timeval tv1, tv2; + + unlink(name); + fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + perror("open"); + return -1; + } + + printf("fallocate run time:\n"); + gettimeofday(&tv1, NULL); + r = syscall(__NR_fallocate, fd, 0, len); + close(fd); + gettimeofday(&tv2, NULL); + if (r < 0) { + perror("fallocate"); + return r; + } + printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); + printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); + printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); + + return 0; +} +#endif + +int do_mmap(char *name, off_t len) +{ + int fd; + struct timeval tv1, tv2; + char *addr; + + unlink(name); + fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + perror("open"); + return -1; + } + /* memset has to have the mmap'ed file backed by something on + * disk -- bus error otherwise */ + lseek(fd, len - 1, SEEK_SET); + write(fd, "0", 1); + + addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("mmap"); + return -2; + } + + printf("mmap run time:\n"); + gettimeofday(&tv1, NULL); + memset(addr, 0, len); + munmap(addr, len); + close(fd); + gettimeofday(&tv2, NULL); + + printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); + printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); + printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); + + return 0; +} + +int do_write_chunks(char *name, off_t len, size_t chunk_size) +{ + int fd; + struct timeval tv1, tv2; + + unsigned long long remain = len; + char *zeros; + + zeros = calloc(1, len); + + unlink(name); + fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) { + perror("open"); + return -1; + } + + printf("%llu-sized chunk run time:\n", chunk_size); + gettimeofday(&tv1, NULL); + while (remain) { + int bytes = chunk_size; + if (bytes > remain) + bytes = remain; + if ((bytes = write(fd, zeros, bytes)) < 0) { + perror("write"); + return -2; + } + remain -= bytes; + } + close(fd); + gettimeofday(&tv2, NULL); + + printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); + printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); + printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); + free(zeros); + + return 0; +} + +int main(int argc, char **argv) +{ + char *basename; + char *filename; + + if (argc < 2) { + printf("usage: %s base-dir\n", argv[0]); + return -1; + } + + basename = argv[1]; + + sprintf(filename, "%s/file-pf", basename); + do_posix_fallocate(filename, 1 * GB); + +#if 0 + sprintf(filename, "%s/file-pf", basename); + do_fallocate(filename, 1 * GB); +#endif + + sprintf(filename, "%s/file-mmap", basename); + do_mmap(filename, 1 * GB); + + sprintf(filename, "%s/file-chunk4", basename); + do_write_chunks(filename, 1 * GB, 4 * 1024); + + sprintf(filename, "%s/file-chunk8", basename); + do_write_chunks(filename, 1 * GB, 8 * 1024); + + return 0; +} |