aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2024-01-31 23:29:17 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2024-01-31 23:51:56 +0100
commit89d7fefa50268eb3ea5aa487c398a9e963b4c50d (patch)
tree2443be2e558d9679bc3cd2620fa1db79c4c9a6ad
parent178e99296104836281c723c6746e3025610acfc3 (diff)
downloadnotes-89d7fefa50268eb3ea5aa487c398a9e963b4c50d.tar.gz
notes-89d7fefa50268eb3ea5aa487c398a9e963b4c50d.zip
gnuplot: initial notes
-rw-r--r--src/SUMMARY.md1
-rw-r--r--src/tools/README.md1
-rw-r--r--src/tools/gnuplot.md68
-rw-r--r--src/tools/gnuplot/mem_lat.c67
-rw-r--r--src/tools/gnuplot/mem_lat.plot13
-rw-r--r--src/tools/gnuplot/plot.sh11
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