summaryrefslogtreecommitdiffstats
path: root/test-file-zero-alloc-speed.c
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2009-03-02 13:07:29 +0530
committerAmit Shah <amit.shah@redhat.com>2009-03-02 13:07:29 +0530
commit23bd4be5b74f227ceb073f8da213708d5ded2af8 (patch)
tree9a940b4bf03f2e8374fc84dcadacd5544a19e54a /test-file-zero-alloc-speed.c
downloadalloc-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.c177
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;
+}