summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2019-10-08 16:44:13 +0200
committerTom Smeding <tom.smeding@gmail.com>2019-10-08 16:44:13 +0200
commitb3108c0bc1873ff72a3bbe694df07c7f3e7f1502 (patch)
tree6e0a485aba1e5fbb6af1ae1b9478d29e543f04f1
Initial
-rw-r--r--.gitignore2
-rw-r--r--Makefile13
-rw-r--r--disk_perf.c68
3 files changed, 83 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..02a03ef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+disk_perf
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..eca6140
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,13 @@
+CC = gcc
+CFLAGS = -Wall -Wextra -O3 -std=c99 -D_GNU_SOURCE
+BIN = disk_perf
+
+.PHONY: all clean
+
+all: $(BIN)
+
+$(BIN): disk_perf.c
+ $(CC) $(CFLAGS) -o $@ $<
+
+clean:
+ rm -f $(BIN)
diff --git a/disk_perf.c b/disk_perf.c
new file mode 100644
index 0000000..81c4095
--- /dev/null
+++ b/disk_perf.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <assert.h>
+#include <sys/time.h>
+
+static uint64_t gettimestamp() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000ULL + tv.tv_usec;
+}
+
+static void writeall(int fd, const void *buf, size_t count) {
+ size_t cursor = 0;
+ while (cursor < count) {
+ ssize_t written = write(fd, buf + cursor, count - cursor);
+ if (written < 0) {
+ perror("write");
+ exit(1);
+ }
+ assert(written > 0);
+ cursor += written;
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <temp file to use>\n", argv[0]);
+ fprintf(stderr,
+ "This will write some data to a file as many times per second as\n"
+ "possible, calling fsync() after each write to make sure it is\n"
+ "persisted. This gives an upper bound on the number of ACID transactions\n"
+ "a single-threaded database can achieve on a disk.\n"
+ "The amount of data in one write is currently 18 bytes.\n"
+ );
+ return 1;
+ }
+
+ int fd = open(argv[1], O_WRONLY | O_CREAT, 0644);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ uint64_t start_stamp = gettimestamp();
+ size_t num_writes = 0;
+ for (size_t i = 0; ; i++) {
+ const char *str = "abcdefgh=01234567\n";
+ writeall(fd, str, strlen(str));
+ fsync(fd);
+ num_writes++;
+
+ if (i % 100 == 0) {
+ uint64_t now = gettimestamp();
+ double secs = (double)(now - start_stamp) / 1000000;
+ if (secs >= 4.0) {
+ printf("Speed: %zu writes in %lf seconds = %lf w/s\n",
+ num_writes, secs, num_writes / secs);
+
+ start_stamp = now;
+ num_writes = 0;
+ }
+ }
+ }
+}