diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-01-31 23:29:17 +0100 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-01-31 23:51:56 +0100 |
commit | 89d7fefa50268eb3ea5aa487c398a9e963b4c50d (patch) | |
tree | 2443be2e558d9679bc3cd2620fa1db79c4c9a6ad | |
parent | 178e99296104836281c723c6746e3025610acfc3 (diff) | |
download | notes-89d7fefa50268eb3ea5aa487c398a9e963b4c50d.tar.gz notes-89d7fefa50268eb3ea5aa487c398a9e963b4c50d.zip |
gnuplot: initial notes
-rw-r--r-- | src/SUMMARY.md | 1 | ||||
-rw-r--r-- | src/tools/README.md | 1 | ||||
-rw-r--r-- | src/tools/gnuplot.md | 68 | ||||
-rw-r--r-- | src/tools/gnuplot/mem_lat.c | 67 | ||||
-rw-r--r-- | src/tools/gnuplot/mem_lat.plot | 13 | ||||
-rw-r--r-- | src/tools/gnuplot/plot.sh | 11 |
6 files changed, 161 insertions, 0 deletions
diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6c53882..fa4917c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -21,6 +21,7 @@ - [column](./tools/column.md) - [sort](./tools/sort.md) - [sed](./tools/sed.md) + - [gnuplot](./tools/gnuplot.md) - [Resource analysis & monitor](./monitor/README.md) - [lsof](./monitor/lsof.md) diff --git a/src/tools/README.md b/src/tools/README.md index 7b9b184..89b6c39 100644 --- a/src/tools/README.md +++ b/src/tools/README.md @@ -18,3 +18,4 @@ - [column](./column.md) - [sort](./sort.md) - [sed](./sed.md) +- [gnuplot](./gnuplot.md) diff --git a/src/tools/gnuplot.md b/src/tools/gnuplot.md new file mode 100644 index 0000000..0a2f50f --- /dev/null +++ b/src/tools/gnuplot.md @@ -0,0 +1,68 @@ +# gnuplot (1) + +``` +# Launch interactive shell. +gnuplot + +# Launch interactive shell. +gnuplot [opt] + opt: + -p ................ persist plot window + -c <file> ......... run script file + -e "<cmd1>; .." ... run cmd(s) +``` + +## Frequently used configuration +```sh +# Plot title. +set title "the plot" + +# Labels. +set xlabel "abc" +set ylabel "def" + +# Output format, 'help set term' for all output formats. +set term svg +# Output file. +set output "out.svg" + +# Make axis logarithmic to given base. +set logscale x 2 + +# Change separator, default is whitespace. +set datafile separator "," +``` + +## Plot +```sh +# With specific style (eg lines, linespoint, boxes, steps, impulses, ..). +plot "<data_file>" with <plot_style> + +> cat data.txt +1 1 3 +2 2 2 +3 3 1 +4 2 2 + +# Plot specific column. +plot "data.txt" using 1:2, "data.txt" using 1:3 +# Equivalent using the special file "", which re-uses the previous input file. +plot "data.txt" using 1:2, "" using 1:3 + +# Plot piped data. +plot "< head -n2 data.txt" + +# Plot with alternate title. +plot "data.txt" title "moose" +``` + +## Example: multiple data sets in on plot +```sh +{{#include gnuplot/mem_lat.plot}} +``` + +On Linux x86_64, [`mem_lat.c`](gnuplot/mem_lat.c) provides an example which can +be run as follows. +```sh +{{#include gnuplot/plot.sh:3:9}} +``` diff --git a/src/tools/gnuplot/mem_lat.c b/src/tools/gnuplot/mem_lat.c new file mode 100644 index 0000000..b85a08f --- /dev/null +++ b/src/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/src/tools/gnuplot/mem_lat.plot b/src/tools/gnuplot/mem_lat.plot new file mode 100644 index 0000000..db058f9 --- /dev/null +++ b/src/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/src/tools/gnuplot/plot.sh b/src/tools/gnuplot/plot.sh new file mode 100644 index 0000000..e288c6c --- /dev/null +++ b/src/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 |