diff options
author | johannst <johannst@users.noreply.github.com> | 2024-01-31 22:52:33 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2024-01-31 22:52:33 +0000 |
commit | bfc5ce4bc01e5eb28969eefcc01ecfefa2601fdf (patch) | |
tree | 9de58b72811e7e84892c3a3749ca1ed5ccb83e42 /tools/gnuplot | |
parent | e5b4aacc5d30dedc78fe955de6ab340374ca2920 (diff) | |
download | notes-bfc5ce4bc01e5eb28969eefcc01ecfefa2601fdf.tar.gz notes-bfc5ce4bc01e5eb28969eefcc01ecfefa2601fdf.zip |
deploy: f3e631f7539c71686d1e336756c9c0fcd0b587ad
Diffstat (limited to 'tools/gnuplot')
-rw-r--r-- | tools/gnuplot/mem_lat.c | 67 | ||||
-rw-r--r-- | tools/gnuplot/mem_lat.plot | 13 | ||||
-rw-r--r-- | tools/gnuplot/plot.sh | 11 |
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 |