aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/gnuplot
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gnuplot')
-rw-r--r--tools/gnuplot/mem_lat.c67
-rw-r--r--tools/gnuplot/mem_lat.plot13
-rw-r--r--tools/gnuplot/plot.sh11
3 files changed, 91 insertions, 0 deletions
diff --git a/tools/gnuplot/mem_lat.c b/tools/gnuplot/mem_lat.c
new file mode 100644
index 0000000..b85a08f
--- /dev/null
+++ b/tools/gnuplot/mem_lat.c
@@ -0,0 +1,67 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum : size_t {
+ KB = 1024,
+ MB = 1024 * KB,
+
+ DFL_MAXSZ = 64 * MB,
+ DFL_STRIDE = 256,
+ NUM_ACCESS = 1ull << 24,
+};
+
+static inline uint64_t rdtsc() {
+ uint32_t eax, edx;
+ asm volatile("rdtsc" : "=a"(eax), "=d"(edx));
+ return ((uint64_t)edx << 32) | eax;
+}
+
+uint64_t run_one_walk(size_t size, size_t stride) {
+ // Check size is power of two.
+ assert((size & (size -1)) == 0);
+ assert((size / stride) <= NUM_ACCESS);
+
+ unsigned char *mem = (unsigned char *)malloc(size);
+ memset(mem, 0x55, size);
+
+ const uint64_t start = rdtsc();
+ for (size_t it = 0; it < NUM_ACCESS; it++) {
+ ((volatile unsigned char *)mem)[(it * stride) & (size - 1)]++;
+ }
+ const uint64_t stop = rdtsc();
+
+ free(mem);
+ return stop - start;
+}
+
+int main(int argc, char *argv[]) {
+ size_t max_sz = DFL_MAXSZ;
+ size_t stride = DFL_STRIDE;
+
+ if (argc > 1) {
+ max_sz = strtoll(argv[1], 0, 10);
+ max_sz *= MB;
+ }
+ if (argc > 2) {
+ stride = strtoll(argv[2], 0, 10);
+ }
+
+ fprintf(stderr, "max_sz=%zuK stride=%zu access=%zu\n",
+ max_sz / KB, stride, NUM_ACCESS);
+
+ size_t size = 2048;
+ while (size <= max_sz) {
+ uint64_t cycles = 0;
+ for (size_t loop = 0; loop < 10; ++loop) {
+ cycles += run_one_walk(size, stride);
+ }
+ printf("%6zuK %f\n", size / KB, (double)cycles / NUM_ACCESS / 10.0);
+
+ size *= 2;
+ }
+
+ return 0;
+}
diff --git a/tools/gnuplot/mem_lat.plot b/tools/gnuplot/mem_lat.plot
new file mode 100644
index 0000000..db058f9
--- /dev/null
+++ b/tools/gnuplot/mem_lat.plot
@@ -0,0 +1,13 @@
+# file: mem_lat.plot
+
+set title "memory latency (different strides)"
+set xlabel "array in KB"
+set ylabel "cycles / access"
+
+set logscale x 2
+
+plot "stride_32.txt" title "32" with linespoints, \
+ "stride_64.txt" title "64" with linespoints, \
+ "stride_128.txt" title "128" with linespoints, \
+ "stride_256.txt" title "256" with linespoints, \
+ "stride_512.txt" title "512" with linespoints
diff --git a/tools/gnuplot/plot.sh b/tools/gnuplot/plot.sh
new file mode 100644
index 0000000..e288c6c
--- /dev/null
+++ b/tools/gnuplot/plot.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+gcc -o mem_lat mem_lat.c -g -O3 -Wall -Werror
+
+for stride in 32 64 128 256 512; do \
+ taskset -c 1 ./mem_lat 128 $stride | tee stride_$stride.txt ; \
+done
+
+gnuplot -p -c mem_lat.plot
+
+rm -f stride_*.txt mem_lat