From 2ea0c0b60cf10150eefe6a8eaafd6fb0a45fa156 Mon Sep 17 00:00:00 2001 From: Tiziano Zito Date: Wed, 13 Aug 2025 13:58:07 +0200 Subject: [PATCH] add all materials --- README.md | 93 + architecture/GPUvsCPU-architecture.png | Bin 0 -> 93850 bytes architecture/NAND-gate.svg | 67 + architecture/README.md | 121 + architecture/comp_architecture_schematics.svg | 1 + architecture/cpu_clock_rate.csv | 201 ++ architecture/cpu_clock_rate.py | 83 + architecture/cpu_clock_rate.svg | 2047 +++++++++++++ architecture/memory.csv | 148 + architecture/memory.py | 101 + architecture/memory_bandwidth.svg | 2563 +++++++++++++++++ architecture/memory_clock.svg | 1734 +++++++++++ architecture/memory_latency.svg | 1944 +++++++++++++ architecture/storage.csv | 49 + architecture/storage.py | 54 + architecture/storage.svg | 1526 ++++++++++ architecture/topology.png | Bin 0 -> 31325 bytes benchmark_low_level/README.md | 57 + benchmark_low_level/bandwidth-t14.svg | 1719 +++++++++++ benchmark_low_level/latency-t14.svg | 1801 ++++++++++++ benchmark_low_level/parse_results.py | 39 + benchmark_low_level/plot.py | 115 + benchmark_low_level/results_t14 | 485 ++++ benchmark_low_level/t14-bwr.csv | 22 + benchmark_low_level/t14-bww.csv | 22 + benchmark_low_level/t14-lrnd.csv | 41 + benchmark_low_level/t14-lseq.csv | 41 + benchmark_python/README.md | 29 + benchmark_python/bench.py | 68 + benchmark_python/bench_plot.py | 106 + benchmark_python/loading-slowdown-ns128.svg | 2360 +++++++++++++++ benchmark_python/loading-timings-ns128.svg | 2348 +++++++++++++++ benchmark_python/results_ns128 | 21 + exercise-my-solution.ipynb | 241 ++ numpy/README.md | 31 + numpy/ndarray-memory-layout-1d.svg | 1 + .../ndarray-memory-layout-2d-rectangular.svg | 1 + numpy/ndarray-memory-layout-2d-square.svg | 1 + numpy/python-list-memory-layout.svg | 1 + parallel/README.md | 24 + setup/generate_materials.py | 37 + setup/materials.pdf | Bin 0 -> 215911 bytes setup/template.svg | 105 + 43 files changed, 20448 insertions(+) create mode 100644 README.md create mode 100644 architecture/GPUvsCPU-architecture.png create mode 100644 architecture/NAND-gate.svg create mode 100644 architecture/README.md create mode 100644 architecture/comp_architecture_schematics.svg create mode 100644 architecture/cpu_clock_rate.csv create mode 100644 architecture/cpu_clock_rate.py create mode 100644 architecture/cpu_clock_rate.svg create mode 100644 architecture/memory.csv create mode 100644 architecture/memory.py create mode 100644 architecture/memory_bandwidth.svg create mode 100644 architecture/memory_clock.svg create mode 100644 architecture/memory_latency.svg create mode 100644 architecture/storage.csv create mode 100644 architecture/storage.py create mode 100644 architecture/storage.svg create mode 100644 architecture/topology.png create mode 100644 benchmark_low_level/README.md create mode 100644 benchmark_low_level/bandwidth-t14.svg create mode 100644 benchmark_low_level/latency-t14.svg create mode 100644 benchmark_low_level/parse_results.py create mode 100644 benchmark_low_level/plot.py create mode 100644 benchmark_low_level/results_t14 create mode 100644 benchmark_low_level/t14-bwr.csv create mode 100644 benchmark_low_level/t14-bww.csv create mode 100644 benchmark_low_level/t14-lrnd.csv create mode 100644 benchmark_low_level/t14-lseq.csv create mode 100644 benchmark_python/README.md create mode 100755 benchmark_python/bench.py create mode 100755 benchmark_python/bench_plot.py create mode 100644 benchmark_python/loading-slowdown-ns128.svg create mode 100644 benchmark_python/loading-timings-ns128.svg create mode 100644 benchmark_python/results_ns128 create mode 100644 exercise-my-solution.ipynb create mode 100644 numpy/README.md create mode 100644 numpy/ndarray-memory-layout-1d.svg create mode 100644 numpy/ndarray-memory-layout-2d-rectangular.svg create mode 100644 numpy/ndarray-memory-layout-2d-square.svg create mode 100644 numpy/python-list-memory-layout.svg create mode 100644 parallel/README.md create mode 100644 setup/generate_materials.py create mode 100644 setup/materials.pdf create mode 100644 setup/template.svg diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc9bced --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# What every scientist should know about computer architecture + +## Introduction + - [Puzzle](puzzle.ipynb) + - Question: how come that swapping dimensions in a for-loop makes out for a huge slowdown? + - Let students play around with the notebook and try to find the "bug" + - A more thorough [benchmark](benchmark_python/) + + +## A digression in CPU architecture and the memory hierarchy + + - Go to [A Primer in CPU architecture](architecture/) + - Measure size and timings for the memory hierarchy on my machine with a low level [C benchmark](benchmark_low_level/) + +## Analog programming + + - [Two exercises to activate the body and the mind](analog_programming.md) + + +## Back to the Python benchmark (second try) + + - can we explain what is happening? + - it must have to do with the good (or bad) use of cache properties + - but how are numpy arrays laid out in memory? + +## Anatomy of a numpy array + + - [memory layout of numpy arrays](numpy/) + +## Back to the Python benchmark (third try) + - can we explain what is happening now? Yes, more or less ;-) + - quick fix for the [puzzle](puzzle.ipynb): try and add `order='F'` in the "bad" snippet and see that it "fixes" the bug ➔ why? + - the default memeory layout is called "C-contiguous" or "row-major": + ```python + np.zeros((2,2)).flags.c_contiguous == True + np.zeros((2,2)).flags.f_contiguous == False + ``` + - note that for one-dimensional arrays it makes no difference: + ```python + np.zeros(2).flags.c_contiguous == True + np.zeros(2).flags.f_contiguous == True + ``` + - rule of thumb for multi-dimensional numpy arrays: + - the right-most index should be the inner-most loop in a series of nested loops over the dimensions of a multi-dimensional array + - the previous rule can be remembered as *the right-most index changes the faster* in a series of nested loops + - the logically contiguous data, for example the data points of a single time series, should be stored along the right-most dimension: + ```python + x = np.zeros((n_series, lenght_of_one_series)) # ➔ good! + y = np.zeros((length_of_one_series, n_series)) # ➔ bad! + ``` + - … unless of course you plan to mostly loop *across* time series :) + - watch out when migrating code from MATLAB® : it stores data in memory using the opposite convention, the column-major order! + - **DANGER**: watch out when working with [`pandas.DataFrame`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html): + + ➔ the data are stored in memory using different conventions depending on how the `DataFrame` was initialized! Be sure to + check the `DataFrame.values.flags` attribute! + +## A final exercise to put it all together + - fork this repo to your account and clone your fork on the laptop + - create a branch `ex` and switch to it + - work on the [exercise](exercise.ipynb) + - push your solution to your fork and create a Pull Request to this repo + + +## Notes on the benchmarks + + - while running the benchmarks attached to one core on my laptop, the core was running under a constant load of 100% (almost completely user-time) and at a fixed frequency of 3.8 GHz, where the theoretical max would be 5.2 GHz + + ➔ the CPU does not "starve" because it scales its speed down to match the memory throughput? Or I am misinterpreting this? This problem which at first sight should be perfectly memory-bound, becomes CPU-bound, or actually, exactly balanced? From the [Intel documentation](https://lenovopress.lenovo.com/lp1836-tuning-uefi-settings-4th-gen-intel-xeon-scalable-processor): + > **Energy Efficient Turbo** + > + > When `Energy Efficient Turbo` is enabled, the CPU’s optimal turbo + > frequency will be tuned dynamically based on CPU utilization. The actual + > turbo frequency the CPU is set to is proportionally adjusted based on the + > duration of the turbo request. Memory usage of the OS is also monitored. + > If the OS is using memory heavily and the CPU core performance is limited + > by the available memory resources, the turbo frequency will be reduced + > until more memory load dissipates, and more memory resources become + > available. The power/performance bias setting also influences energy + > efficient turbo. `Energy Efficient Turbo` is best used when attempting to + > maximize power consumption over performance. + +## Concluding remarks + - how is all of this relevant for the users of a computing cluster? + - Never trust benchmarks! See for example [Producing Wrong Data Without Doing Anything Obviously Wrong!](https://users.cs.northwestern.edu/~robby/courses/322-2013-spring/mytkowicz-wrong-data.pdf) + +## Additional material if there's time left +- [Excerpts of parallel Python](parallel) +- how does memory *allocation* to processes work at the OS level? + - virtual memory + - swap + - optimistic over-committing allocation policies + - the oom-killer watchdog diff --git a/architecture/GPUvsCPU-architecture.png b/architecture/GPUvsCPU-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..1370d89903e3e4a8a1697b24722b095bd59fe3c6 GIT binary patch literal 93850 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%0DUE|?|-fqp&ke>!GS3=h?v=fAo) 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 O6dtKQERi+&^Zx*ysqmlx literal 0 HcmV?d00001 diff --git a/architecture/NAND-gate.svg b/architecture/NAND-gate.svg new file mode 100644 index 0000000..64f3987 --- /dev/null +++ b/architecture/NAND-gate.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Vcc + GND + R1 + R2 + VT1 + VT2 + A + B + Q + + diff --git a/architecture/README.md b/architecture/README.md new file mode 100644 index 0000000..c9811a4 --- /dev/null +++ b/architecture/README.md @@ -0,0 +1,121 @@ +# A Primer on computer architecture + +## Binary representation of common data types +- **integers** + - int32 ➔ 32b (bits) = 4B (bytes) + - 1 bit for sign, 31 bit for magnitude + - min = -2^31 = -2,147,483,648 + - max = 2^31-1 = 2,147,483,647 + - [visualization](https://manderc.com/apps/umrechner/index_eng.php) + - In Python: + - `bin(14)` ➔ `'0b1110'` + - `np.iinfo(np.int32)` ➔ `iinfo(min=-2147483648, max=2147483647, dtype=int32)` + - Python integers, as opposed to numpy integer types, are represented with a flexible number of bits: `sys.int_info` ➔ `bits_per_digit=30, sizeof_digit=4, default_max_str_digits=4300, str_digits_check_threshold=640` + - they are called "long" or "superlong" integers, because they can have arbitrary size. Low level implementation explained: + - [Arpit Bhayani's blog](https://arpitbhayani.me/blogs/long-integers-python/) + - [Artem Golubin's blog](https://rushter.com/blog/python-integer-implementation/) + +- **real numbers**, a.k.a. floating point numbers (IEEE-754 standard): + - float64 ➔ 64b (bits) = 8B (bytes) + - 1 bit for sign, 51 bits for mantissa, 11 bits for exponent + - min, max ≈ ± 1.8 × 10^308 + - smallest ≈ 2.2 x 10^-308 + - example in Python: + - `np.finfo(np.float64)` ➔ `finfo(resolution=1e-15, min=-1.7976931348623157e+308, max=1.7976931348623157e+308, dtype=float64)` + - `sys.float_info` ➔ `max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1` + - next floating point number after `1.` in the direction of `2.`: `np.nextafter(1., 2.)` ➔ `1.0000000000000002` + - watch out for equality between floating point numbers: + - `1.1 + 2.2 == 3.3` ➔ `False` + - `(1.1+2.2).hex()` ➔ `0x1.a666666666667p+1` and `(3.3).hex()` ➔ `0x1.a666666666666p+1` + - visualization: + - [`float32`](https://www.h-schmidt.net/FloatConverter/IEEE754.html) + - [all types](https://float.exposed/) with [explanation](https://ciechanow.ski/exposing-floating-point/) + - Docs with more details: [What Every Programmer Should Know About Floating-Point Arithmetic or Why don’t my numbers add up?](https://floating-point-gui.de) + - Docs with the gory details, a.k.a. the floating point bible: [What every computer scientist should know about floating-point arithmetic](https://doi.org/10.1145/103162.103163) + +- **strings**: + - UTF8 encoded, flexible width from 1B (byte) to 4B (bytes): 1,112,064 Unicode characters (code points) + - ASCII: 7 bits (fits in one byte), 127 characters ➔ [ASCII table](https://upload.wikimedia.org/wikipedia/commons/2/26/ASCII_Table_%28suitable_for_printing%29.svg) + - [visualization](https://sonarsource.github.io/utf8-visualizer/) + - actually in Python strings (more precisely: unicode objects) are stored in different formats depending on which characters are stored for memory efficiency. Look at the gory details [here](https://docs.python.org/3.14/c-api/unicode.html) ➔ not for the faint-hearted! + +- **hexadecimal notation**: + - base16 ➔ '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f' + - a compact way of representating binary data: 8 bits = 1 byte = 2 hexadecimal digits + - Example: `254` (decimal) ➔ `1111 1110` (binary) ➔ `fe` (hex) + +## CPU architecture +![CPU schematics](comp_architecture_schematics.svg) + - Primer on CPU (x86_64) architecture and the memory hierarchy: + - CPU registers ≈ 160 (plus another ~500 model specific), latency: 0 cycles, capacity: 8 bytes + - x86-64 instruction set, with ≈ 2000 instructions with mnemonic (plus an unknown number of "undocumented" instructions ~ 10k) + - (single instruction, mutiple data [8 or 16 data units]) SIMD CPUs + - L-Caches: L1/L2/L3, with cache lines of 128B, latencies: 1-40 cycles, capacity: ~KB and ~MB + - Main memory: RAM pages 4KB or 64KB, latency: 50~100 cycles, capacity ~GBs + - Storage (local disks): disk transfer blocks 4KB to 64MB, latency: 0.1ms (300k cycles), capacity: ~TBs + - Remote Storage (network): typically limited by ethernet connection (1-10 GB/s), latency: 10~100 ms, capacity: ∞ + - Understand the trade-offs involved: + - **capacity** measured in T/G/M/K/B + - **latency** ≈ (time-when-data-available-on-output-pins – time-when-data-requested) ➔ measured in nanoseconds or in (CPU) cycles + - **bandwidth** ≈ clock frequency × data-transfer/tick × bus-width (in bytes) ➔ measured in T/G/M/K/B per second (this is what is usually advertised as the **speed**) + - data **volatility** vs. **persistence** + - cost + - physical limits (heat dissipation, density, size, lifetime) + - temporal and spacial locality of data + - The gory details about the memory hierarchy: [What Every Programmer Should Know About Memory](https://www.akkadia.org/drepper/cpumemory.pdf) by the notorious Ulrich Drepper + +# …and what about the GPU? +![GPU vs CPU architecture](GPUvsCPU-architecture.png) + - A GPU has many (in the order of hundreds) SIMT (single instruction, multiple thread) cores, so called SMs (Streaming Multiprocessors), each one with local L1 and shared L2 caches, and shared RAM (due to to the high parallelism, with huge bandwidth, in the order of ~1TB/s) + - The SMs are specialized on data types. In order of abundance, the following data types are supported: int8, int32, int64, float16, float32, float64 + - Performance depends on: + - memory bandwidth: usually higher than CPU's RAM + - "math" bandwidth: usually higher than CPU's, but much more limited in capability; for example branches (if/else) are expensive + - latency: usually much higher than CPU's ➔ the more parallel threads are run the less the price of high latency is paid (latency "hiding") + - spatial locality is extremely critical + - A portion of the GPU-RAM is accessible to the CPU ➔ the GPU performs the copies + - The PCI-Bus (Peripheral Component Interconnect bus) is the bottleneck: data needs to flow from main (CPU) memory to GPU memory and back! + - Problems on a cluster: the GPU does not really support simultanous multiple users payloads! + +# Computer Architecture (a concrete example) +My Laptop: +![Graphical representation](topology.png) + - Lenovo - T14 Gen 4 + - CPU i7-1365U: + - 2× "performance cores" (Intel Core) max 5.20 GHz (0.19 ns/cycle) with Hyper-Threading + - 8× "efficient cores" (Intel Atom) max 3.90 GHz (0.26 ns/cycle) + - L1 (data) cache P-Core 48 KB + - L1 (data) cache E-Core 32 KB + - L2 cache P-Core 1280 KB + - L2 cache E-Core 2048 KB (shared x4) + - L3 cache 12 MB (shared P+E-Cores) + - RAM DDR5-5200: 32GB (16GB soldered + 16GB bank): + - Data rate 5200 MT/s, Transfer time 0.192 ns/cycle + - Command rate (bus clock) 2600 MHz, Cycle time 0.385 ns + - Internal clock 650 MHz, 1.54 ns + - CAS Latency 34 cycles, Total latency = CAS latency x cycle = 13.09 ns, Throughput 40.6 GB/s + - DMI (Direct Media Interface): 8×16 GT/s (≈128 GB/s) + - PCI (Peripheral Component Interconnect) Express bridges: + - Graphics: 16 GT/s (≈ 8 GB/s) + - 2× Thunderbolt: 2.5 GT/s (≈ 1 GB/s) and 16 GT/s (≈ 8 GB/s) + - GPU Intel Iris, Internal clock 300 Mhz-1.30 GHz, memory 4 GB/2.1 GHz with a bandwidth of 68 GB/s + +## Historical evolution of speed of different components in a computer +(data source: Wikipedia) + +### CPU Clock Rate +![](cpu_clock_rate.svg) + +### Memory (RAM) Clock Cycle Time +![](memory_clock.svg) + +### Memory (RAM) Bandwidth +![](memory_bandwidth.svg) + +### Memory (RAM) Latency +![](memory_latency.svg) + +### Storage Read Speed +![](storage.svg) + + diff --git a/architecture/comp_architecture_schematics.svg b/architecture/comp_architecture_schematics.svg new file mode 100644 index 0000000..a6ba132 --- /dev/null +++ b/architecture/comp_architecture_schematics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/architecture/cpu_clock_rate.csv b/architecture/cpu_clock_rate.csv new file mode 100644 index 0000000..399939c --- /dev/null +++ b/architecture/cpu_clock_rate.csv @@ -0,0 +1,201 @@ +1969,1 MHz +1971,740 kHz +1972,200 kHz +1972,400 kHz +1972,500 kHz +1973,1 MHz +1973,2 MHz +1973,715 kHz +1974,1.33 MHz +1974,1.4 MHz +1974,1 MHz +1974,2 MHz +1974,400 kHz +1974,500 kHz +1974,715 kHz +1974,740 kHz +1975,1.2 MHz +1975,10 MHz +1975,1 MHz +1975,256 kHz +1975,2 MHz +1975,3.3 MHz +1975,4 MHz +1976,2.5 MHz +1976,3.3 MHz +1976,6.4 MHz +1976,8 MHz +1977,1.0 MHz +1977,2.0 MHz +1977,3.0 MHz +1978,1 MHz +1978,5 MHz +1979,5 MHz +1979,8 MHz +1981,10 MHz +1981,2.5 MHz +1982,18 MHz +1982,1 MHz +1982,6 MHz +1982,8 MHz +1983,2 MHz +1983,3 MHz +1984,16 MHz +1984,5 MHz +1985,12 MHz +1985,5 MHz +1985,8 MHz +1986,15 MHz +1986,16 MHz +1987,10 MHz +1987,12.5 MHz +1987,16 MHz +1987,20 MHz +1987,8 MHz +1988,10 MHz +1988,12 MHz +1988,25 MHz +1989,16-33 MHz +1989,25 MHz +1989,35 MHz +1990,20-30 MHz +1990,40 MHz +1991,100 MHz +1991,33 MHz +1991,62.5-90.91 MHz +1992,100 MHz +1992,100-200 MHz +1992,20 MHz +1992,40 MHz +1992,40-50 MHz +1993,120 MHz +1993,50-80 MHz +1993,55-71.5 MHz +1993,60-66 MHz +1994,100 MHz +1994,100-125 MHz +1994,100-180 MHz +1994,125 MHz +1994,200-300 MHz +1994,50 MHz +1994,60-120 MHz +1994,60-125 MHz +1995,101-118 MHz +1995,143-167 MHz +1995,150-200 MHz +1995,266-333 MHz +1996,141-161 MHz +1996,150 MHz +1996,150-250 MHz +1996,160-180 MHz +1996,180-250 MHz +1996,400-500 MHz +1996,75-100 MHz +1997,120-150 MHz +1997,125 MHz +1997,166-233 MHz +1997,200 MHz +1997,233-300 MHz +1997,233-366 MHz +1997,250-400 MHz +1997,370 MHz +1998,200 MHz +1998,250-300 MHz +1998,250-330 MHz +1998,262 MHz +1998,270-400 MHz +1998,300-440 MHz +1998,450-600 MHz +1998,500 MHz +1999,294-300 MHz +1999,350-500 MHz +1999,450 MHz +1999,450-600 MHz +1999,500-1000 MHz +1999,550-637 MHz +2000,1.33-1.73 GHz +2000,1.3-2 GHz +2000,450-810 MHz +2000,550 MHz-1.3 GHz +2000,600-750 MHz +2000,918 MHz +2001,1.1-1.4 GHz +2001,500-600 MHz +2001,733-800 MHz +2001,750-1200 MHz +2002,0.9-1 GHz +2002,1.1-1.35 GHz +2003,0.9-1.7 GHz +2003,1.4-2.4 GHz +2003,1.6-2.0 GHz +2004,1.65-1.9 GHz +2004,700 MHz +2005,1.05-1.35 GHz +2005,1.2-2.5 GHz +2005,1.6-3.0 GHz +2005,1-1.4 GHz +2005,2.8-3.2 GHz +2005,2-2.4 GHz +2005,3.2 GHz +2006,1.06-2.67 GHz +2006,1.1-2.33 GHz +2006,1.4-1.6 GHz +2006,3.2-4.6 GHz +2007,1.8-3.2 GHz +2007,1-1.4 GHz +2007,2.15-2.4 GHz +2007,3.5-4.7 GHz +2007,600-900 MHz +2007,850 MHz +2008,0.8-1.6 GHz +2008,1.8-2.6 GHz +2008,2.3-2.9 GHz +2008,2.4-2.88 GHz +2008,2.66-3.2 GHz +2008,2.8-4.0 GHz +2008,4.4 GHz +2008,600-866 MHz +2009,2.2-2.8 GHz +2009,2.5-3.2 GHz +2010,1.6 GHz +2010,1.73-2.66 GHz +2010,1.7-2.4 GHz +2010,1.86-3.33 GHz +2010,2.66-3.0 GHz +2010,2 GHz +2010,3.8-5.2 GHz +2010,3-4.14 GHz +2011,1.0-1.6 GHz +2011,1.6 GHz +2011,1.6-3.4 GHz +2011,1.73-2.67 GHz +2011,2.0 GHz +2011,2.8-3 GHz +2011,3.1-3.6 GHz +2012,1.73-2.53 GHz +2012,1.848 GHz +2012,3.1-5.3 GHz +2012,5.5 GHz +2013,1.9-4.4 GHz +2013,2.8-3 GHz +2013,3.6 GHz +2014,1.8-4 GHz +2014,2.5-5 GHz +2015,3.6 GHz +2015,5 GHz +2016,320 MHz +2017,1.5 GHz +2017,3.2-4.1 GHz +2017,4 GHz +2017,5.2 GHz +2017,5 GHz +2018,1.5 GHz +2018,2.2-3.2 GHz +2018,2.8-3.7 GHz +2019,2-4.7 GHz +2019,5.2 GHz +2020,3.2 GHz +2020,3.4-4.9 GHz +2021,3.2 GHz +2022,3.2 GHz +2022,5 GHz diff --git a/architecture/cpu_clock_rate.py b/architecture/cpu_clock_rate.py new file mode 100644 index 0000000..8c0504a --- /dev/null +++ b/architecture/cpu_clock_rate.py @@ -0,0 +1,83 @@ +# CPU clock rate data from Wikipedia +# https://en.wikipedia.org/wiki/Microprocessor_chronology +# Table data extracted with: https://wikitable2csv.ggor.de/ +import numpy as np +import matplotlib +from matplotlib import pyplot as plt +plt.style.use('ggplot') +matplotlib.rcParams['font.size'] = 12 +matplotlib.rcParams['font.family'] = ['Exo 2', 'sans-serif'] + +data = open('cpu_clock_rate.csv', 'rt') + +# first, remove units and rescale everything to MHz +rescaled = [] +for line in data: + date, raw = line.split(',') + try: + value, unit = raw.split() + except ValueError: + # there are lines with multiple units, for example + # 550 MHz-1.3 GHz + # take the left most one + raw = raw.split('-')[1] + value, unit = raw.split() + # if value is in the form X-Y, just use the biggest, i.e. Y + if '-' in value: + value = value.split('-')[1] + value = float(value) + # rescale value + if unit == 'kHz': + value = value/1000 + elif unit == 'GHz': + value = value*1000 + elif unit == 'MHz': + pass + else: + raise ValueError(f'Unit not understood! {unit}') + rescaled.append((date, value)) + +dtype = [('year', np.float64), ('clock', np.float64)] +rescaled = np.array(rescaled, dtype=dtype) +# sort first by year and then by value +rescaled.sort(order=['year', 'clock']) + +# add some jitter on values corresponding to the same year, so that the plot +# looks more understandable +old_year = rescaled[0][0] +count = 0 +for row in range(rescaled.shape[0]): + year = rescaled[row][0] + count += 1 + if year != old_year: + # add jitter to the values corresponding to the previous year + prev_count = count-1 + if prev_count > 1: + jitter = 1/prev_count + for i in range(1, count): + loc_year, loc_value = rescaled[row-count+i] + rescaled[row-count+i] = (loc_year+(jitter*(i-1)), loc_value) + # restart counting + count = 1 + old_year = year + +# plot the thing +plt.figure(figsize=(8.5,7.5)) +plt.semilogy(rescaled['year'], rescaled['clock'], 'o') +# my laptop here +plt.semilogy([2020], [4900], 'o') +plt.grid(None) +plt.grid(which='both', axis='both') +plt.ylim(0.1, 10000) +plt.xlim(1968, 2025) +years = np.arange(1970, 2025, 5) +plt.xticks(years, years) +plt.yticks([0.1, 1,10,100,1000, 10000], ['1 kHz\n1 ms', '1 MHz\n1 µs', '10 MHz\n100 ns', + '100 MHz\n10 ns', '1 GHz\n1 ns', '10 GHz\n0.1 ns']) +plt.tick_params(labelright=True, top=True, right=True) +plt.title('CPU clock rate') +plt.savefig('cpu_clock_rate.svg') + + + + diff --git a/architecture/cpu_clock_rate.svg b/architecture/cpu_clock_rate.svg new file mode 100644 index 0000000..f793c65 --- /dev/null +++ b/architecture/cpu_clock_rate.svg @@ -0,0 +1,2047 @@ + + + + + + + + 2024-03-09T19:48:36.950426 + image/svg+xml + + + Matplotlib v3.6.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/memory.csv b/architecture/memory.csv new file mode 100644 index 0000000..a380049 --- /dev/null +++ b/architecture/memory.csv @@ -0,0 +1,148 @@ +Generation,Type,Data rate (MT/s),Transfer time (ns),Command rate (MHz),Cycle time (ns),CAS latency,First word (ns),Fourth word (ns),Eighth word (ns) +SDRAM,PC100,100,10.000,100,10.000,2,20.00,50.00,90.00 +SDRAM,PC133,133,7.500,133,7.500,3,22.50,45.00,75.00 +DDR SDRAM,DDR-333,333,3.000,166,6.000,2.5,15.00,24.00,36.00 +DDR SDRAM,DDR-400,400,2.500,200,5.000,3,15.00,22.50,32.50 +DDR SDRAM,DDR-400,400,2.500,200,5.000,2.5,12.50,20.00,30.00 +DDR SDRAM,DDR-400,400,2.500,200,5.000,2,10.00,17.50,27.50 +DDR2 SDRAM,DDR2-400,400,2.500,200,5.000,4,20.00,27.50,37.50 +DDR2 SDRAM,DDR2-400,400,2.500,200,5.000,3,15.00,22.50,32.50 +DDR2 SDRAM,DDR2-533,533,1.875,266,3.750,4,15.00,20.63,28.13 +DDR2 SDRAM,DDR2-533,533,1.875,266,3.750,3,11.25,16.88,24.38 +DDR2 SDRAM,DDR2-667,667,1.500,333,3.000,5,15.00,19.50,25.50 +DDR2 SDRAM,DDR2-667,667,1.500,333,3.000,4,12.00,16.50,22.50 +DDR2 SDRAM,DDR2-800,800,1.250,400,2.500,6,15.00,18.75,23.75 +DDR2 SDRAM,DDR2-800,800,1.250,400,2.500,5,12.50,16.25,21.25 +DDR2 SDRAM,DDR2-800,800,1.250,400,2.500,4.5,11.25,15.00,20.00 +DDR2 SDRAM,DDR2-800,800,1.250,400,2.500,4,10.00,13.75,18.75 +DDR2 SDRAM,DDR2-1066,1066,0.938,533,1.875,7,13.13,15.94,19.69 +DDR2 SDRAM,DDR2-1066,1066,0.938,533,1.875,6,11.25,14.06,17.81 +DDR2 SDRAM,DDR2-1066,1066,0.938,533,1.875,5,9.38,12.19,15.94 +DDR2 SDRAM,DDR2-1066,1066,0.938,533,1.875,4.5,8.44,11.25,15.00 +DDR2 SDRAM,DDR2-1066,1066,0.938,533,1.875,4,7.50,10.31,14.06 +DDR3 SDRAM,DDR3-1066,1066,0.938,533,1.875,7,13.13,15.94,19.69 +DDR3 SDRAM,DDR3-1333,1333,0.750,666,1.500,9,13.50,15.75,18.75 +DDR3 SDRAM,DDR3-1333,1333,0.750,666,1.500,7,10.50,12.75,15.75 +DDR3 SDRAM,DDR3-1333,1333,0.750,666,1.500,6,9.00,11.25,14.25 +DDR3 SDRAM,DDR3-1375,1375,0.727,687,1.455,5,7.27,9.45,12.36 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,11,13.75,15.63,18.13 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,10,12.50,14.38,16.88 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,9,11.25,13.13,15.63 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,8,10.00,11.88,14.38 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,7,8.75,10.63,13.13 +DDR3 SDRAM,DDR3-1600,1600,0.625,800,1.250,6,7.50,9.38,11.88 +DDR3 SDRAM,DDR3-1866,1866,0.536,933,1.071,10,10.71,12.32,14.46 +DDR3 SDRAM,DDR3-1866,1866,0.536,933,1.071,9,9.64,11.25,13.39 +DDR3 SDRAM,DDR3-1866,1866,0.536,933,1.071,8,8.57,10.18,12.32 +DDR3 SDRAM,DDR3-2000,2000,0.500,1000,1.000,9,9.00,10.50,12.50 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,12,11.25,12.66,14.53 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,11,10.31,11.72,13.59 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,10,9.38,10.78,12.66 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,9,8.44,9.84,11.72 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,8,7.50,8.91,10.78 +DDR3 SDRAM,DDR3-2133,2133,0.469,1066,0.938,7,6.56,7.97,9.84 +DDR3 SDRAM,DDR3-2200,2200,0.455,1100,0.909,7,6.36,7.73,9.55 +DDR3 SDRAM,DDR3-2400,2400,0.417,1200,0.833,13,10.83,12.08,13.75 +DDR3 SDRAM,DDR3-2400,2400,0.417,1200,0.833,12,10.00,11.25,12.92 +DDR3 SDRAM,DDR3-2400,2400,0.417,1200,0.833,11,9.17,10.42,12.08 +DDR3 SDRAM,DDR3-2400,2400,0.417,1200,0.833,10,8.33,9.58,11.25 +DDR3 SDRAM,DDR3-2400,2400,0.417,1200,0.833,9,7.50,8.75,10.42 +DDR3 SDRAM,DDR3-2600,2600,0.385,1300,0.769,11,8.46,9.62,11.15 +DDR3 SDRAM,DDR3-2666,2666,0.375,1333,0.750,15,11.25,12.38,13.88 +DDR3 SDRAM,DDR3-2666,2666,0.375,1333,0.750,13,9.75,10.88,12.38 +DDR3 SDRAM,DDR3-2666,2666,0.375,1333,0.750,12,9.00,10.13,11.63 +DDR3 SDRAM,DDR3-2666,2666,0.375,1333,0.750,11,8.25,9.38,10.88 +DDR3 SDRAM,DDR3-2800,2800,0.357,1400,0.714,16,11.43,12.50,13.93 +DDR3 SDRAM,DDR3-2800,2800,0.357,1400,0.714,12,8.57,9.64,11.07 +DDR3 SDRAM,DDR3-2800,2800,0.357,1400,0.714,11,7.86,8.93,10.36 +DDR3 SDRAM,DDR3-2933,2933,0.341,1466,0.682,12,8.18,9.20,10.57 +DDR3 SDRAM,DDR3-3000,3000,0.333,1500,0.667,12,8.00,9.00,10.33 +DDR3 SDRAM,DDR3-3100,3100,0.323,1550,0.645,12,7.74,8.71,10.00 +DDR3 SDRAM,DDR3-3200,3200,0.313,1600,0.625,16,10.00,10.94,12.19 +DDR3 SDRAM,DDR3-3300,3300,0.303,1650,0.606,16,9.70,10.61,11.82 +DDR4 SDRAM,DDR4-1600,1600,0.625,800,1.250,12,15.00,16.88,19.38 +DDR4 SDRAM,DDR4-1600,1600,0.625,800,1.250,11,13.75,15.63,18.13 +DDR4 SDRAM,DDR4-1600,1600,0.625,800,1.250,10,12.50,14.38,16.88 +DDR4 SDRAM,DDR4-1866,1866,0.536,933,1.071,14,15.00,16.61,18.75 +DDR4 SDRAM,DDR4-1866,1866,0.536,933,1.071,13,13.93,15.54,17.68 +DDR4 SDRAM,DDR4-1866,1866,0.536,933,1.071,12,12.86,14.46,16.61 +DDR4 SDRAM,DDR4-2133,2133,0.469,1066,0.938,16,15.00,16.41,18.28 +DDR4 SDRAM,DDR4-2133,2133,0.469,1066,0.938,15,14.06,15.47,17.34 +DDR4 SDRAM,DDR4-2133,2133,0.469,1066,0.938,14,13.13,14.53,16.41 +DDR4 SDRAM,DDR4-2400,2400,0.417,1200,0.833,17,14.17,15.42,17.08 +DDR4 SDRAM,DDR4-2400,2400,0.417,1200,0.833,16,13.33,14.58,16.25 +DDR4 SDRAM,DDR4-2400,2400,0.417,1200,0.833,15,12.50,13.75,15.42 +DDR4 SDRAM,DDR4-2666,2666,0.375,1333,0.750,19,14.25,15.38,16.88 +DDR4 SDRAM,DDR4-2666,2666,0.375,1333,0.750,17,12.75,13.88,15.38 +DDR4 SDRAM,DDR4-2666,2666,0.375,1333,0.750,16,12.00,13.13,14.63 +DDR4 SDRAM,DDR4-2666,2666,0.375,1333,0.750,15,11.25,12.38,13.88 +DDR4 SDRAM,DDR4-2666,2666,0.375,1333,0.750,13,9.75,10.88,12.38 +DDR4 SDRAM,DDR4-2800,2800,0.357,1400,0.714,17,12.14,13.21,14.64 +DDR4 SDRAM,DDR4-2800,2800,0.357,1400,0.714,16,11.43,12.50,13.93 +DDR4 SDRAM,DDR4-2800,2800,0.357,1400,0.714,15,10.71,11.79,13.21 +DDR4 SDRAM,DDR4-2800,2800,0.357,1400,0.714,14,10.00,11.07,12.50 +DDR4 SDRAM,DDR4-3000,3000,0.333,1500,0.667,17,11.33,12.33,13.67 +DDR4 SDRAM,DDR4-3000,3000,0.333,1500,0.667,16,10.67,11.67,13.00 +DDR4 SDRAM,DDR4-3000,3000,0.333,1500,0.667,15,10.00,11.00,12.33 +DDR4 SDRAM,DDR4-3000,3000,0.333,1500,0.667,14,9.33,10.33,11.67 +DDR4 SDRAM,DDR4-3200,3200,0.313,1600,0.625,16,10.00,10.94,12.19 +DDR4 SDRAM,DDR4-3200,3200,0.313,1600,0.625,15,9.38,10.31,11.56 +DDR4 SDRAM,DDR4-3200,3200,0.313,1600,0.625,14,8.75,9.69,10.94 +DDR4 SDRAM,DDR4-3300,3300,0.303,1650,0.606,16,9.70,10.61,11.82 +DDR4 SDRAM,DDR4-3333,3333,0.300,1666,0.600,16,9.60,10.50,11.70 +DDR4 SDRAM,DDR4-3400,3400,0.294,1700,0.588,16,9.41,10.29,11.47 +DDR4 SDRAM,DDR4-3466,3466,0.288,1733,0.577,18,10.38,11.25,12.40 +DDR4 SDRAM,DDR4-3466,3466,0.288,1733,0.577,17,9.81,10.67,11.83 +DDR4 SDRAM,DDR4-3466,3466,0.288,1733,0.577,16,9.23,10.10,11.25 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,19,10.56,11.39,12.50 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,18,10.00,10.83,11.94 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,17,9.44,10.28,11.39 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,16,8.89,9.72,10.83 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,15,8.33,9.17,10.28 +DDR4 SDRAM,DDR4-3600,3600,0.278,1800,0.556,14,7.78,8.61,9.72 +DDR4 SDRAM,DDR4-3733,3733,0.268,1866,0.536,17,9.11,9.91,10.98 +DDR4 SDRAM,DDR4-3866,3866,0.259,1933,0.517,18,9.31,10.09,11.12 +DDR4 SDRAM,DDR4-4000,4000,0.250,2000,0.500,19,9.50,10.25,11.25 +DDR4 SDRAM,DDR4-4000,4000,0.250,2000,0.500,18,9.00,9.75,10.75 +DDR4 SDRAM,DDR4-4000,4000,0.250,2000,0.500,17,8.50,9.25,10.25 +DDR4 SDRAM,DDR4-4000,4000,0.250,2000,0.500,16,8.00,8.75,9.75 +DDR4 SDRAM,DDR4-4133,4133,0.242,2066,0.484,19,9.19,9.92,10.89 +DDR4 SDRAM,DDR4-4200,4200,0.238,2100,0.476,19,9.05,9.76,10.71 +DDR4 SDRAM,DDR4-4266,4266,0.234,2133,0.469,19,8.91,9.61,10.55 +DDR4 SDRAM,DDR4-4266,4266,0.234,2133,0.469,18,8.44,9.14,10.08 +DDR4 SDRAM,DDR4-4266,4266,0.234,2133,0.469,17,7.97,8.67,9.61 +DDR4 SDRAM,DDR4-4266,4266,0.234,2133,0.469,16,7.50,8.20,9.14 +DDR4 SDRAM,DDR4-4400,4400,0.227,2200,0.454,19,8.64,9.32,10.23 +DDR4 SDRAM,DDR4-4400,4400,0.227,2200,0.454,18,8.18,8.86,9.77 +DDR4 SDRAM,DDR4-4400,4400,0.227,2200,0.454,17,7.73,8.41,9.32 +DDR4 SDRAM,DDR4-4600,4600,0.217,2300,0.435,19,8.26,8.91,9.78 +DDR4 SDRAM,DDR4-4600,4600,0.217,2300,0.435,18,7.82,8.48,9.35 +DDR4 SDRAM,DDR4-4800,4800,0.208,2400,0.417,20,8.33,8.96,9.79 +DDR4 SDRAM,DDR4-4800,4800,0.208,2400,0.417,19,7.92,8.54,9.38 +DDR5 SDRAM,DDR5-4800,4800,0.208,2400,0.417,40,16.67,17.29,18.13 +DDR5 SDRAM,DDR5-4800,4800,0.208,2400,0.417,38,15.83,16.46,17.29 +DDR5 SDRAM,DDR5-4800,4800,0.208,2400,0.417,36,15.00,15.63,16.46 +DDR5 SDRAM,DDR5-4800,4800,0.208,2400,0.417,34,14.17,14.79,15.63 +DDR5 SDRAM,DDR5-5200,5200,0.192,2600,0.385,40,15.38,15.96,16.73 +DDR5 SDRAM,DDR5-5200,5200,0.192,2600,0.385,38,14.62,15.19,15.96 +DDR5 SDRAM,DDR5-5200,5200,0.192,2600,0.385,36,13.85,14.42,15.19 +DDR5 SDRAM,DDR5-5200,5200,0.192,2600,0.385,34,13.08,13.65,14.42 +DDR5 SDRAM,DDR5-5600,5600,0.179,2800,0.357,40,14.29,14.82,15.54 +DDR5 SDRAM,DDR5-5600,5600,0.179,2800,0.357,38,13.57,14.11,14.82 +DDR5 SDRAM,DDR5-5600,5600,0.179,2800,0.357,36,12.86,13.39,14.11 +DDR5 SDRAM,DDR5-5600,5600,0.179,2800,0.357,34,12.14,12.68,13.39 +DDR5 SDRAM,DDR5-5600,5600,0.179,2800,0.357,30,10.71,11.25,11.96 +DDR5 SDRAM,DDR5-6000,6000,0.167,3000,0.333,40,13.33,13.83,14.50 +DDR5 SDRAM,DDR5-6000,6000,0.167,3000,0.333,38,12.67,13.17,13.83 +DDR5 SDRAM,DDR5-6000,6000,0.167,3000,0.333,36,12.00,12.50,13.17 +DDR5 SDRAM,DDR5-6000,6000,0.167,3000,0.333,32,10.67,11.17,11.83 +DDR5 SDRAM,DDR5-6000,6000,0.167,3000,0.333,30,10.00,10.50,11.17 +DDR5 SDRAM,DDR5-6200,6200,0.161,3100,0.323,40,12.90,13.39,14.03 +DDR5 SDRAM,DDR5-6200,6200,0.161,3100,0.323,38,12.26,12.74,13.39 +DDR5 SDRAM,DDR5-6200,6200,0.161,3100,0.323,36,11.61,12.10,12.74 +DDR5 SDRAM,DDR5-6400,6400,0.156,3200,0.313,40,12.50,12.97,13.59 +DDR5 SDRAM,DDR5-6400,6400,0.156,3200,0.313,38,11.88,12.34,12.97 +DDR5 SDRAM,DDR5-6400,6400,0.156,3200,0.313,36,11.25,11.72,12.34 +DDR5 SDRAM,DDR5-6400,6400,0.156,3200,0.313,34,10.63,11.09,11.72 +DDR5 SDRAM,DDR5-6400,6400,0.156,3200,0.313,32,10.00,10.47,11.09 +DDR5 SDRAM,DDR5-6600,6600,0.152,3300,0.303,34,10.30,10.76,11.36 diff --git a/architecture/memory.py b/architecture/memory.py new file mode 100644 index 0000000..5dc36cc --- /dev/null +++ b/architecture/memory.py @@ -0,0 +1,101 @@ +# RAM clock rate and transfer rate data from Wikipedia +# https://en.wikipedia.org/wiki/DDR_SDRAM +# Table data extracted with: https://wikitable2csv.ggor.de/ +import numpy as np +import pandas +import matplotlib +from matplotlib import pyplot as plt +plt.style.use('ggplot') +matplotlib.rcParams['font.size'] = 12 +matplotlib.rcParams['font.family'] = ['Exo 2', 'sans-serif'] + + +data = pandas.read_csv('memory.csv') +#data = data.sort_values('Memory clock (MHz)') +_types = list(data['Type']) +_transfers = list(data['Data rate (MT/s)']) +_cycle_times = list(data['Cycle time (ns)']) +_latencies = list(data['Eighth word (ns)']) + +# remove redundant data +types = [] +transfers = [] +cycle_times = [] +latencies = [] +for idx, typ in enumerate(_types): + # just select the first occurence of this type + if typ in types: + continue + # filter DDR4 inferior to DDR4-3333 + prefix = 'DDR4-' + if typ.startswith(prefix) and int(typ.removeprefix(prefix)) < 3333: + continue + types.append(typ) + transfers.append(_transfers[idx]) + cycle_times.append(_cycle_times[idx]) + latencies.append(_latencies[idx]) + +# transform transfers from MT/s to GB/s +transfers = np.array(transfers, dtype='float64')*8/1024 +plt.figure(figsize=(8.5,7.5)) +plt.title('Memory Bandwidth [GB/s] (1995-2023)') +# my laptop first +me = types.index('DDR5-5200') +plt.plot(range(len(types)), transfers, 'o') +plt.plot(me, transfers[me], 'o') +plt.xticks(range(len(types))[::3], types[::3], rotation=30, ha='right') +yticks = range(0,56) +ylabels = [] +for t in yticks: + if not t%5: + ylabels.append(str(t)) + else: + ylabels.append('') +plt.yticks(yticks, ylabels) +plt.ylabel('GB/s') +plt.tick_params(axis='y', which='both', reset=True, labelright=True, right=True) +plt.savefig('memory_bandwidth.svg') + +plt.figure(figsize=(8.5,7.5)) +plt.title('Memory Cycle Time [ns] (1995-2023)') +# my laptop first +me = types.index('DDR5-5200') +plt.semilogy(range(len(types)), cycle_times, 'o') +plt.semilogy(me, cycle_times[me], 'o') +plt.xticks(range(len(types))[::3], types[::3], rotation=30, ha='right') +plt.ylim(0.1, 11) +line = np.arange(0,10).astype('float64') +yticks = list(line[1:]*0.1)+list(line[1:])+list(line[1:2]*10) +ylabels = [] +for value in yticks: + if value in (0.1, 0.5, 1., 1.5, 5., 10.): + ylabels.append(f'{value} ns') + else: + ylabels.append('') +plt.yticks(yticks, ylabels) +plt.tick_params(axis='y', which='both', reset=True, labelright=True, right=True) +plt.savefig('memory_clock.svg') + +# transform transfers from MT/s to GB/s +plt.figure(figsize=(8.5,7.5)) +plt.title('Memory Latency [ns] (1998-2023)') +# my laptop first +me = types.index('DDR5-5200') +mel = latencies[me] +y = latencies[2:] +x = types[2:] +plt.plot(range(len(x)), y, 'o') +plt.plot(me, mel, 'o') +plt.xticks(range(len(x))[::3], x[::3], rotation=30, ha='right') +plt.ylim(8,40) +yticks = range(8,41) +ylabels = [] +for t in yticks: + if not t%5: + ylabels.append(str(t)+' ns') + else: + ylabels.append('') +plt.yticks(yticks, ylabels) +plt.tick_params(axis='y', which='both', reset=True, labelright=True, right=True) +plt.savefig('memory_latency.svg') + diff --git a/architecture/memory_bandwidth.svg b/architecture/memory_bandwidth.svg new file mode 100644 index 0000000..9d579a6 --- /dev/null +++ b/architecture/memory_bandwidth.svg @@ -0,0 +1,2563 @@ + + + + + + + + 2024-08-16T18:39:22.726694 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/memory_clock.svg b/architecture/memory_clock.svg new file mode 100644 index 0000000..1330e40 --- /dev/null +++ b/architecture/memory_clock.svg @@ -0,0 +1,1734 @@ + + + + + + + + 2024-08-16T18:39:22.912183 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/memory_latency.svg b/architecture/memory_latency.svg new file mode 100644 index 0000000..ff91f61 --- /dev/null +++ b/architecture/memory_latency.svg @@ -0,0 +1,1944 @@ + + + + + + + + 2024-08-16T18:39:23.040253 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/storage.csv b/architecture/storage.csv new file mode 100644 index 0000000..14e86f0 --- /dev/null +++ b/architecture/storage.csv @@ -0,0 +1,49 @@ +Teletype Model 33 paper tape,10 B/s,1963 +Single Density 8-inch FM Floppy Disk Controller (160 KB),31 KB/s,1973 +C2N Commodore Datasette 1530 cassette tape interface,15 B/s,1977 +Apple II cassette tape interface,200 B/s,1977 +TRS-80 Model 1 Level 1 BASIC cassette tape interface,32 B/s,1977 +Single Density 5.25-inch FM Floppy Disk Controller (180 KB),15.5 KB/s,1978 +MFM hard disk,0.625 MB/s,1980 +Amstrad CPC tape,250 B/s,1984 +High Density MFM Floppy Disk Controller (1.2 MB/1.44 MB),31 KB/s,1984 +ATA PIO Mode 0,3.3 MB/s,1986 +SCSI (Narrow SCSI) (5 MHz),5 MB/s,1986 +CD Controller (1×),0.146 MB/s,1988 +Serial Storage Architecture SSA,80 MB/s,1990 +ATA PIO Mode 1,5.2 MB/s,1994 +ATA PIO Mode 2,8.3 MB/s,1994 +ATA PIO Mode 3,11.1 MB/s,1996 +ATA PIO Mode 4,16.7 MB/s,1996 +Fibre Channel 1GFC (1.0625 GHz),103.23 MB/s,1997 +Ultra DMA ATA 33,33 MB/s,1998 +Ultra DMA ATA 66,66.7 MB/s,2000 +Fibre Channel 2GFC (2.125 GHz),206.5 MB/s,2001 +Ultra DMA ATA 100,100 MB/s,2002 +SATA revision 1.0,150 MB/s,2003 +iSCSI over 10GbE,1.239 GB/s,2004 +iSCSI over Fast Ethernet,11.9 MB/s,2004 +iSCSI over gigabit Ethernet- jumbo frames,123.9 MB/s,2004 +Serial Attached SCSI (SAS) SAS-1,300 MB/s,2004 +SATA Revision 2.0,300 MB/s,2004 +Fibre Channel 4GFC (4.25 GHz),413 MB/s,2004 +Ultra DMA ATA 133,133 MB/s,2005 +Fibre Channel 8GFC (8.50 GHz),826 MB/s,2005 +iSCSI over InfiniBand 4×,4 GB/s,2007 +SATA Revision 3.0,600 MB/s,2008 +FCoE over 10GbE,1.206 GB/s,2009 +AoE over 10GbE,1.242 GB/s,2009 +AoE over Fast Ethernet,11.9 MB/s,2009 +AoE over gigabit Ethernet- jumbo frames,124.2 MB/s,2009 +Serial Attached SCSI (SAS) SAS-2,600 MB/s,2009 +FCoE over 100G Ethernet,12.064 GB/s,2010 +iSCSI over 100G Ethernet,12.392 GB/s,2010 +Fibre Channel 16GFC (14.025 GHz),1.652 GB/s,2011 +Serial Attached SCSI (SAS) SAS-3,1.2 GB/s,2013 +SATA Express,2 GB/s,2013 +NVMe over M.2 or U.2 (using PCI Express 3.0 ×4 link),3.938 GB/s,2013 +Fibre Channel 32GFC (28.05 GHz),3.303 GB/s,2016 +Serial Attached SCSI (SAS) SAS-4,2.4 GB/s,2017 +NVMe over M.2 or U.2 (using PCI Express 4.0 ×4 link),7.876 GB/s,2017 +UFS (version 3.0),2.9 GB/s,2018 +NVMe over M.2- U.2- U.3 or EDSFF (using PCI Express 5.0 ×4 link),15.754 GB/s,2019 diff --git a/architecture/storage.py b/architecture/storage.py new file mode 100644 index 0000000..ddfacdb --- /dev/null +++ b/architecture/storage.py @@ -0,0 +1,54 @@ +# Storage interfaces rates from +# https://en.wikipedia.org/wiki/List_of_interface_bit_rates#Storage +# Table data extracted with: https://wikitable2csv.ggor.de/ +import numpy as np +import matplotlib +from matplotlib import pyplot as plt +plt.style.use('ggplot') +matplotlib.rcParams['font.size'] = 12 +matplotlib.rcParams['font.family'] = ['Exo 2', 'sans-serif'] + +data = open('storage.csv', 'rt') +# remove units and rescale everything to MB/s +b_to_mb = 1/(1024*1024) +kb_to_mb = 1/1024 +gb_to_mb = 1024 +rescaled = [] +for line in data: + typ, rate, year = line.split(',') + value, unit = rate.split() + value = float(value) + if unit == 'B/s': + value = value*b_to_mb + elif unit == 'KB/s': + value = value*kb_to_mb + elif unit == 'MB/s': + pass + elif unit == 'GB/s': + value = value*gb_to_mb + else: + raise ValueError(f'Unit not understood! {unit}') + rescaled.append((int(year), value)) + +dtype = [('year', np.float64), ('speed', np.float64)] +rescaled = np.array(rescaled, dtype=dtype) +# sort first by year and then by value +rescaled.sort(order=['year', 'speed']) + +# plot the thing +plt.figure(figsize=(8.5,7.5)) +plt.semilogy(rescaled['year'], rescaled['speed'], 'o') +# my laptop here +plt.semilogy([2023], [6585], 'o') +plt.grid(None) +plt.grid(which='both', axis='y') +plt.grid(which='both', axis='x') +plt.ylim(b_to_mb, 100*gb_to_mb) +plt.xlim(1960, 2025) +years = range(1960,2026,5) +plt.xticks(years, years, rotation=45, ha='center') +plt.yticks([b_to_mb, kb_to_mb, 1, 10, 100, gb_to_mb, 10*gb_to_mb, 100*gb_to_mb], + ['1 B/s', '1 KB/s', '1 MB/s', '10 MB/s', '100 MB/s', '1 GB/s', '10 GB/s', '100 GB/s']) +plt.tick_params(labeltop=False, labelright=True, top=True, right=True) +plt.title('Storage (read) speed') +plt.savefig('storage.svg') diff --git a/architecture/storage.svg b/architecture/storage.svg new file mode 100644 index 0000000..19be256 --- /dev/null +++ b/architecture/storage.svg @@ -0,0 +1,1526 @@ + + + + + + + + 2024-03-09T19:54:25.352366 + image/svg+xml + + + Matplotlib v3.6.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/topology.png b/architecture/topology.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac05a9670e3b7c189c314cfa0f8c15361ff8c1b GIT binary patch literal 31325 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 /proc/sys/kernel/randomize_va_space + ``` + - Set scaling governor to performance for CPU0: + ```bash + echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor + ``` + - Reserve CPU 0 fro our benchmark, i.e. kick out (almost) all other processes + ```bash + cset shield --cpu 0 --kthread=on + ``` + - If you are on INTEL and CPU0 is part of a SMT-pair (hyperthreading), disable the peer + ```bash + echo 0 > /sys/devices/system/cpu/cpu1/online + ``` + - Disable turbo mode on INTEL: + ```bash + echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo + ``` + - Run the configuration script for lmbench. Select only the `HARDWARE` set of benchmarks and set the maximum amount of memory to something like 1024MB + ```bash + cd /usr/lib/lmbench/scripts + # the following command will create the configuration file /usr/lib/lmbench/bin/x86_64-linux-gnu/CONFIG. + cset shield --exec -- ./config-run + # run the benchmark + cset shield --exec -- /usr/bin/lmbench-run + # results are in /var/lib/lmbench/results/x86_64-linux-gnu/ + ``` + + diff --git a/benchmark_low_level/bandwidth-t14.svg b/benchmark_low_level/bandwidth-t14.svg new file mode 100644 index 0000000..cc99a94 --- /dev/null +++ b/benchmark_low_level/bandwidth-t14.svg @@ -0,0 +1,1719 @@ + + + + + + + + 2024-08-16T18:58:33.224677 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmark_low_level/latency-t14.svg b/benchmark_low_level/latency-t14.svg new file mode 100644 index 0000000..469c577 --- /dev/null +++ b/benchmark_low_level/latency-t14.svg @@ -0,0 +1,1801 @@ + + + + + + + + 2024-08-16T18:58:33.332734 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmark_low_level/parse_results.py b/benchmark_low_level/parse_results.py new file mode 100644 index 0000000..0096a98 --- /dev/null +++ b/benchmark_low_level/parse_results.py @@ -0,0 +1,39 @@ +import os +import sys + +# prefix is something like results_ +results = sys.argv[1] +name = results.removeprefix('results_') +types = {} +results = open(results, 'rt') + + +for idx, line in enumerate(results): + if line.startswith('Memory read bandwidth'): + types['bwr'] = idx + elif line.startswith('Memory write bandwidth'): + types['bww'] = idx + elif line.startswith('Memory load latency'): + types['lseq'] = idx + elif line.startswith('Random load latency'): + types['lrnd'] = idx + else: + pass + +for typ, idx in types.items(): + csv = open(f'{name}-{typ}.csv', 'wt') + results.seek(0) + for count, line in enumerate(results): + if count <= idx: + continue + if line.startswith('"'): + continue + try: + val1, val2 = line.split(" ") + except ValueError: + # we are at the end of the section + csv.close() + break + csv.write(f'{val1},{val2}') + + diff --git a/benchmark_low_level/plot.py b/benchmark_low_level/plot.py new file mode 100644 index 0000000..621f00d --- /dev/null +++ b/benchmark_low_level/plot.py @@ -0,0 +1,115 @@ +import os +import sys +import numpy as np +import matplotlib +import itertools +from matplotlib import pyplot as plt +plt.style.use('ggplot') +matplotlib.rcParams['font.size'] = 12 + +name = 't14' + +caches = (48*1024, 1280*1024, 12*1024*1024) + +def get_labels(x): + xlabels = [] + for value in x: + b = int(2**value) + if b < 1024: + xlabels.append(f'{b}B') + elif b < 1048576: + xlabels.append(f'{b//1024}K') + elif b < 1073741824: + xlabels.append(f'{b//1024//1024}M') + else: + xlabels.append(f'{b//1024//1024//1024}G') + return xlabels + + +# manually set ticks, to disable, set ticks = None + +line = np.linspace(1, 10, 9, endpoint=False) +yticks = list(line)+list(line*10)+list(line[:2]*100) + +ylabels = {1 : '1 ns', 5 : '5 ns', 10 : '10 ns', 50 : '50 ns', 100: '100 ns'} +ticks = {'l': (yticks, [ylabels[i] if i in ylabels else '' for i in yticks]), + 'bw': (range(5,46,5), [f'{i} GB/s' for i in range(5,46,5)]), + } + +# manually set limits, to disable set to ylim = None + +ylim = {'l' : (1, 200), + 'bw' : (5,45), + } + +for type_ in ('bw', 'l'): + if type_ == 'bw': + suffix = ('r', 'w') + ylabel = '' + title = f'Memory Bandwidth ({name}) [GB/s]' + legend1, legend2 = 'read', 'write' + pic = f'bandwidth-{name}.svg' + plt_func = plt.plot + else: + suffix = ('seq', 'rnd') + ylabel = '' + title = f'Memory Latency ({name}) [ns]' + legend1, legend2 = 'sequential access', 'random access' + pic = f'latency-{name}.svg' + plt_func = plt.semilogy + + + data1 = np.loadtxt(f'{name}-{type_}{suffix[0]}.csv', delimiter=',') + data2 = np.loadtxt(f'{name}-{type_}{suffix[1]}.csv', delimiter=',') + + # convert to bytes and then to the corresponding power of two + + if type_ == 'bw': + x1 = np.log2(data1[:,0]*1024*1024).round() + y1 = data1[:,1]/1024 + x2 = np.log2(data2[:,0]*1024*1024).round() + y2 = data2[:,1]/1024 + else: + x1 = np.log2(data1[::2,0]*1024*1024).round() + y1 = data1[::2,1] + x2 = np.log2(data2[::2,0]*1024*1024).round() + y2 = data2[::2,1] + ylabels = None + + + xlabel = 'block size' + xlabels = get_labels(x1) + + plt.figure(figsize=(8.5,7.5)) + if type_ == 'l': + # plot two empy plots so we advance the color cyle (bad trick) + _ = plt_func([],[]) + _ = plt_func([],[]) + p1, = plt_func(x1, y1, 'o') + plt.ylabel(ylabel) + plt.xlabel(xlabel) + p2, = plt_func(x2, y2, 'o') + if ylim and type_ in ylim: + plt.ylim(*ylim[type_]) + plt.xticks(x1, xlabels, rotation=60) + if ticks and type_ in ticks: + plt.yticks(*ticks[type_]) + plt.legend((p1, p2), (legend1, legend2)) + if ylim and type_ in ylim: + miny, maxy = ylim[type_] + else: + miny = min(y1.min(), y2.min()) + maxy = max(y1.max(), y2.max()) + # caches + for idx, cache in enumerate(caches): + level = idx + 1 + size = np.log2(cache) + plt.plot((size, size), (miny, maxy), + color = 'darkblue', alpha=0.4) + plt.text(size-1, 2*miny, f'L{level}\n⟵', + color='darkblue', verticalalignment='top') + + plt.title(title) + plt.savefig(pic) + + diff --git a/benchmark_low_level/results_t14 b/benchmark_low_level/results_t14 new file mode 100644 index 0000000..dcca71f --- /dev/null +++ b/benchmark_low_level/results_t14 @@ -0,0 +1,485 @@ +[lmbench3.0 results for Linux multivac 6.10.3-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.10.3-1 (2024-08-04) x86_64 GNU/Linux] +[LMBENCH_VER: 3.0-a9] +[BENCHMARK_HARDWARE: YES] +[BENCHMARK_OS: NO] +[ALL: 512 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1024m] +[DISKS: ] +[DISK_DESC: ] +[ENOUGH: 5000] +[FAST: ] +[FASTMEM: NO] +[FILE: /var/tmp/lmbench/XXX] +[FSDIR: /var/tmp/lmbench] +[HALF: 512 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m] +[INFO: INFO.multivac] +[LINE_SIZE: ] +[LOOP_O: 0.00000000] +[MB: 1024] +[MHZ: 1296 MHz, 0.7716 nanosec clock] +[MOTHERBOARD: ] +[NETWORKS: ] +[PROCESSORS: 11] +[REMOTE: ] +[SLOWFS: YES] +[OS: x86_64-linux-gnu] +[SYNC_MAX: 1] +[LMBENCH_SCHED: DEFAULT] +[TIMING_O: 0] +[LMBENCH VERSION: 3.0-20240810] +[USER: root] +[HOSTNAME: multivac] +[NODENAME: multivac] +[SYSNAME: Linux] +[PROCESSOR: unknown] +[MACHINE: x86_64] +[RELEASE: 6.10.3-amd64] +[VERSION: #1 SMP PREEMPT_DYNAMIC Debian 6.10.3-1 (2024-08-04)] +[Sat Aug 10 04:20:43 PM CEST 2024] +[ 16:20:43 up 1:18, 4 users, load average: 0.37, 0.94, 1.05] +[net: Kernel Interface table] +[net: Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg] +[net: eth0 1500 0 0 0 0 0 0 0 0 BMU] +[if: eth0: flags=4099 mtu 1500] +[if: ether fc:5c:ee:4d:b5:eb txqueuelen 1000 (Ethernet)] +[if: RX packets 0 bytes 0 (0.0 B)] +[if: RX errors 0 dropped 0 overruns 0 frame 0] +[if: TX packets 0 bytes 0 (0.0 B)] +[if: TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0] +[if: device interrupt 16 memory 0xbc300000-bc320000] +[if: ] +[net: eth1 1500 34948 0 2352 0 7773 0 0 0 BMRU] +[if: eth1: flags=4163 mtu 1500] +[if: inet 192.168.111.103 netmask 255.255.255.0 broadcast 192.168.111.255] +[if: inet6 fe80::44e3:4a35:5130:3045 prefixlen 64 scopeid 0x20] +[if: inet6 2003:ef:2f2e:c900:e437:85c7:3d97:f353 prefixlen 64 scopeid 0x0] +[if: ether b0:4f:13:ef:1a:3e txqueuelen 1000 (Ethernet)] +[if: RX packets 34948 bytes 33936985 (32.3 MiB)] +[if: RX errors 0 dropped 2352 overruns 0 frame 0] +[if: TX packets 7773 bytes 1213416 (1.1 MiB)] +[if: TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0] +[if: ] +[net: lo 65536 95 0 0 0 95 0 0 0 LRU] +[if: lo: flags=73 mtu 65536] +[if: inet 127.0.0.1 netmask 255.0.0.0] +[if: inet6 ::1 prefixlen 128 scopeid 0x10] +[if: loop txqueuelen 1000 (Local Loopback)] +[if: RX packets 95 bytes 5588 (5.4 KiB)] +[if: RX errors 0 dropped 0 overruns 0 frame 0] +[if: TX packets 95 bytes 5588 (5.4 KiB)] +[if: TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0] +[if: ] +[mount: sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)] +[mount: proc on /proc type proc (rw,relatime)] +[mount: udev on /dev type devtmpfs (rw,nosuid,relatime,size=16228560k,nr_inodes=4057140,mode=755,inode64)] +[mount: devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)] +[mount: tmpfs on /run type tmpfs (rw,nosuid,nodev,noexec,relatime,size=3251140k,mode=755,inode64)] +[mount: /dev/mapper/CRYPT-ROOT on / type ext4 (rw,relatime,errors=remount-ro)] +[mount: securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)] +[mount: tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,inode64)] +[mount: cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)] +[mount: pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)] +[mount: efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)] +[mount: bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)] +[mount: systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=39,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=67)] +[mount: hugetlbfs on /dev/hugepages type hugetlbfs (rw,nosuid,nodev,relatime,pagesize=2M)] +[mount: none on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)] +[mount: mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)] +[mount: tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k,inode64)] +[mount: tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)] +[mount: tmpfs on /run/credentials/systemd-journald.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: tmpfs on /run/credentials/systemd-udev-load-credentials.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: tmpfs on /run/credentials/systemd-tmpfiles-setup-dev-early.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)] +[mount: fusectl on /sys/fs/fuse/connections type fusectl (rw,nosuid,nodev,noexec,relatime)] +[mount: tmpfs on /run/credentials/systemd-sysctl.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: tmpfs on /run/credentials/systemd-tmpfiles-setup-dev.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime,size=16777216k,inode64)] +[mount: tmpfs on /run/credentials/systemd-tmpfiles-setup.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)] +[mount: sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)] +[mount: tmpfs on /run/user/1002 type tmpfs (rw,nosuid,nodev,relatime,size=3251136k,nr_inodes=812784,mode=700,uid=1002,gid=100,inode64)] +[mount: tmpfs on /run/credentials/getty@tty1.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap)] +[mount: tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=3251136k,nr_inodes=812784,mode=700,inode64)] +[mount: none on /cpusets type cgroup (rw,relatime,cpuset,noprefix,release_agent=/sbin/cpuset_release_agent)] +integer bit: 0.54 nanoseconds +integer add: 0.77 nanoseconds +integer div: 8.49 nanoseconds +integer mod: 12.58 nanoseconds +int64 bit: 0.52 nanoseconds +uint64 add: 0.77 nanoseconds +int64 div: 11.58 nanoseconds +int64 mod: 14.91 nanoseconds +float add: 1.54 nanoseconds +float mul: 3.09 nanoseconds +float div: 8.49 nanoseconds +double add: 1.54 nanoseconds +double mul: 3.09 nanoseconds +double div: 10.80 nanoseconds +float bogomflops: 1.16 nanoseconds +double bogomflops: 1.54 nanoseconds +integer bit parallelism: 2.77 +integer add parallelism: 2.73 +integer div parallelism: 1.83 +integer mod parallelism: 2.83 +int64 bit parallelism: 2.49 +int64 add parallelism: 2.60 +int64 div parallelism: 1.50 +int64 mod parallelism: 1.90 +float add parallelism: 4.00 +float mul parallelism: 8.00 +float div parallelism: 3.67 +double add parallelism: 4.00 +double mul parallelism: 8.00 +double div parallelism: 3.50 +unable to register (XACT_PROG, XACT_VERS, udp). +: RPC: Unable to receive + +"libc bcopy unaligned +0.000512 41652.95 +0.001024 47761.25 +0.002048 50233.88 +0.004096 55637.27 +0.008192 64524.03 +0.016384 67719.30 +0.032768 18212.36 +0.065536 18407.52 +0.131072 18473.55 +0.262144 18475.00 +0.524288 14642.79 +1.05 8957.30 +2.10 8208.03 +4.19 8208.03 +8.39 9645.77 +16.78 7631.79 +33.55 7129.38 +67.11 6951.41 +134.22 6900.65 +268.44 6848.89 +536.87 6861.76 + +"libc bcopy aligned +0.000512 44106.76 +0.001024 49354.68 +0.002048 51472.69 +0.004096 55925.21 +0.008192 63828.24 +0.016384 66379.51 +0.032768 18202.45 +0.065536 18336.03 +0.131072 18457.77 +0.262144 18327.76 +0.524288 15715.46 +1.05 8922.33 +2.10 8367.89 +4.19 8343.10 +8.39 9679.16 +16.78 7632.95 +33.55 7179.72 +67.11 6990.51 +134.22 6911.31 +268.44 6892.15 +536.87 6891.97 + +Memory bzero bandwidth +0.000512 73586.23 +0.001024 78019.46 +0.002048 80349.42 +0.004096 74573.30 +0.008192 78524.11 +0.016384 80567.79 +0.032768 81708.84 +0.065536 21219.16 +0.131072 21299.79 +0.262144 21333.96 +0.524288 21347.23 +1.05 19382.88 +2.10 12829.98 +4.19 12611.10 +8.39 12606.02 +16.78 10399.64 +33.55 9537.93 +67.11 9140.41 +134.22 9007.90 +268.44 8931.77 +536.87 8918.57 +1073.74 8908.13 + +"unrolled bcopy unaligned +0.000512 10357.22 +0.001024 10363.21 +0.002048 10356.95 +0.004096 10357.76 +0.008192 10343.49 +0.016384 10351.27 +0.032768 7899.27 +0.065536 7893.76 +0.131072 7873.84 +0.262144 7832.99 +0.524288 7281.78 +1.05 6503.77 +2.10 6418.22 +4.19 6461.47 +8.39 5194.99 +16.78 4722.65 +33.55 4639.72 +67.11 4606.91 +134.22 4593.51 +268.44 4596.34 +536.87 4587.27 + +"unrolled partial bcopy unaligned +0.000512 41402.69 +0.001024 41453.86 +0.002048 41452.30 +0.004096 41425.45 +0.008192 41418.12 +0.016384 41333.58 +0.032768 18957.19 +0.065536 18955.39 +0.131072 18962.49 +0.262144 18969.69 +0.524288 14659.04 +1.05 8844.77 +2.10 8192.00 +4.19 8206.57 +8.39 6326.25 +16.78 5801.25 +33.55 5644.14 +67.11 5609.70 +134.22 5600.81 +268.44 5589.38 +536.87 5591.24 + +Memory read bandwidth +0.000512 29201.61 +0.001024 29294.55 +0.002048 29363.12 +0.004096 29433.86 +0.008192 29442.59 +0.016384 29285.40 +0.032768 29336.30 +0.065536 27978.05 +0.131072 28392.59 +0.262144 28408.05 +0.524288 28424.68 +1.05 28385.92 +2.10 28385.92 +4.19 28395.43 +8.39 28334.85 +16.78 26342.45 +33.55 23489.28 +67.11 22195.75 +134.22 21644.53 +268.44 21620.12 +536.87 21505.80 +1073.74 21526.50 + +Memory partial read bandwidth +0.000512 58916.90 +0.001024 59661.44 +0.002048 61203.68 +0.004096 58783.21 +0.008192 61320.45 +0.016384 61266.70 +0.032768 60940.09 +0.065536 30488.23 +0.131072 30517.76 +0.262144 30516.13 +0.524288 29627.83 +1.05 24662.86 +2.10 17384.93 +4.19 17168.66 +8.39 16915.36 +16.78 13189.64 +33.55 11584.48 +67.11 11024.95 +134.22 10892.53 +268.44 10824.45 +536.87 10781.84 +1073.74 10759.80 + +Memory write bandwidth +0.000512 41405.52 +0.001024 41396.47 +0.002048 41429.93 +0.004096 41445.34 +0.008192 41401.00 +0.016384 41398.70 +0.032768 41426.50 +0.065536 21381.05 +0.131072 21388.82 +0.262144 21374.31 +0.524288 21370.17 +1.05 18114.68 +2.10 12417.83 +4.19 12264.05 +8.39 12250.61 +16.78 9679.16 +33.55 8978.98 +67.11 8703.00 +134.22 8589.38 +268.44 8520.41 +536.87 8543.59 +1073.74 8544.75 + +Memory partial write bandwidth +0.000512 41406.05 +0.001024 41431.27 +0.002048 41414.90 +0.004096 41425.45 +0.008192 41431.04 +0.016384 41453.60 +0.032768 41366.48 +0.065536 21392.21 +0.131072 21364.37 +0.262144 21381.05 +0.524288 21366.56 +1.05 18649.81 +2.10 12411.48 +4.19 12249.30 +8.39 12300.01 +16.78 9693.61 +33.55 9024.86 +67.11 8771.25 +134.22 8618.06 +268.44 8557.89 +536.87 8549.44 +1073.74 8543.32 + +Memory partial read/write bandwidth +0.000512 20712.63 +0.001024 20714.87 +0.002048 20703.88 +0.004096 20718.77 +0.008192 20719.28 +0.016384 20715.33 +0.032768 20722.87 +0.065536 20693.70 +0.131072 20690.58 +0.262144 20638.28 +0.524288 20665.37 +1.05 18846.95 +2.10 12887.53 +4.19 12613.33 +8.39 12576.62 +16.78 10295.93 +33.55 9551.50 +67.11 9191.74 +134.22 9087.19 +268.44 9035.49 +536.87 9018.95 +1073.74 9023.04 + +Usage: tlb [-c] [-L ] [-M len[K|M]] [-W ] [-N ] + +Memory load parallelism +Usage: par_mem [-L ] [-M len[K|M]] [-W ] [-N ] + +STREAM copy latency: 1.48 nanoseconds +STREAM copy bandwidth: 10781.39 MB/sec +STREAM scale latency: 1.50 nanoseconds +STREAM scale bandwidth: 10668.00 MB/sec +STREAM add latency: 2.11 nanoseconds +STREAM add bandwidth: 11374.24 MB/sec +STREAM triad latency: 2.13 nanoseconds +STREAM triad bandwidth: 11264.63 MB/sec +STREAM2 fill latency: 0.89 nanoseconds +STREAM2 fill bandwidth: 8955.12 MB/sec +STREAM2 copy latency: 1.48 nanoseconds +STREAM2 copy bandwidth: 10775.60 MB/sec +STREAM2 daxpy latency: 1.81 nanoseconds +STREAM2 daxpy bandwidth: 13256.52 MB/sec +STREAM2 sum latency: 1.60 nanoseconds +STREAM2 sum bandwidth: 5006.72 MB/sec + +Memory load latency +"stride=128 +0.00049 3.859 +0.00098 3.859 +0.00195 3.859 +0.00293 3.859 +0.00391 3.861 +0.00586 3.858 +0.00781 3.858 +0.01172 3.859 +0.01562 3.859 +0.02344 3.859 +0.03125 3.859 +0.04688 3.861 +0.06250 11.580 +0.09375 11.576 +0.12500 11.577 +0.18750 11.583 +0.25000 11.577 +0.37500 11.576 +0.50000 11.579 +0.75000 11.578 +1.00000 11.590 +1.50000 13.543 +2.00000 13.936 +3.00000 13.999 +4.00000 13.996 +6.00000 13.997 +8.00000 14.002 +12.00000 14.976 +16.00000 19.832 +24.00000 20.880 +32.00000 21.339 +48.00000 21.899 +64.00000 22.023 +96.00000 22.156 +128.00000 22.213 +192.00000 22.283 +256.00000 22.320 +384.00000 22.306 +512.00000 22.325 +768.00000 22.345 +1024.00000 22.361 + +Random load latency +"stride=16 +0.00049 3.859 +0.00098 3.858 +0.00195 3.858 +0.00293 3.858 +0.00391 3.858 +0.00586 3.858 +0.00781 3.859 +0.01172 3.858 +0.01562 3.858 +0.02344 3.859 +0.03125 3.859 +0.04688 3.864 +0.06250 11.575 +0.09375 14.276 +0.12500 15.462 +0.18750 16.079 +0.25000 16.646 +0.37500 16.373 +0.50000 16.352 +0.75000 18.529 +1.00000 18.245 +1.50000 42.351 +2.00000 55.350 +3.00000 61.011 +4.00000 62.143 +6.00000 63.587 +8.00000 65.259 +12.00000 84.563 +16.00000 107.165 +24.00000 131.898 +32.00000 141.864 +48.00000 150.654 +64.00000 156.245 +96.00000 162.950 +128.00000 167.497 +192.00000 170.394 +256.00000 171.779 +384.00000 172.858 +512.00000 172.877 +768.00000 173.626 +1024.00000 173.702 + + + +[Sat Aug 10 04:39:13 PM CEST 2024] diff --git a/benchmark_low_level/t14-bwr.csv b/benchmark_low_level/t14-bwr.csv new file mode 100644 index 0000000..8de9220 --- /dev/null +++ b/benchmark_low_level/t14-bwr.csv @@ -0,0 +1,22 @@ +0.000512,29201.61 +0.001024,29294.55 +0.002048,29363.12 +0.004096,29433.86 +0.008192,29442.59 +0.016384,29285.40 +0.032768,29336.30 +0.065536,27978.05 +0.131072,28392.59 +0.262144,28408.05 +0.524288,28424.68 +1.05,28385.92 +2.10,28385.92 +4.19,28395.43 +8.39,28334.85 +16.78,26342.45 +33.55,23489.28 +67.11,22195.75 +134.22,21644.53 +268.44,21620.12 +536.87,21505.80 +1073.74,21526.50 diff --git a/benchmark_low_level/t14-bww.csv b/benchmark_low_level/t14-bww.csv new file mode 100644 index 0000000..c8859ca --- /dev/null +++ b/benchmark_low_level/t14-bww.csv @@ -0,0 +1,22 @@ +0.000512,41405.52 +0.001024,41396.47 +0.002048,41429.93 +0.004096,41445.34 +0.008192,41401.00 +0.016384,41398.70 +0.032768,41426.50 +0.065536,21381.05 +0.131072,21388.82 +0.262144,21374.31 +0.524288,21370.17 +1.05,18114.68 +2.10,12417.83 +4.19,12264.05 +8.39,12250.61 +16.78,9679.16 +33.55,8978.98 +67.11,8703.00 +134.22,8589.38 +268.44,8520.41 +536.87,8543.59 +1073.74,8544.75 diff --git a/benchmark_low_level/t14-lrnd.csv b/benchmark_low_level/t14-lrnd.csv new file mode 100644 index 0000000..dd3d5b5 --- /dev/null +++ b/benchmark_low_level/t14-lrnd.csv @@ -0,0 +1,41 @@ +0.00049,3.859 +0.00098,3.858 +0.00195,3.858 +0.00293,3.858 +0.00391,3.858 +0.00586,3.858 +0.00781,3.859 +0.01172,3.858 +0.01562,3.858 +0.02344,3.859 +0.03125,3.859 +0.04688,3.864 +0.06250,11.575 +0.09375,14.276 +0.12500,15.462 +0.18750,16.079 +0.25000,16.646 +0.37500,16.373 +0.50000,16.352 +0.75000,18.529 +1.00000,18.245 +1.50000,42.351 +2.00000,55.350 +3.00000,61.011 +4.00000,62.143 +6.00000,63.587 +8.00000,65.259 +12.00000,84.563 +16.00000,107.165 +24.00000,131.898 +32.00000,141.864 +48.00000,150.654 +64.00000,156.245 +96.00000,162.950 +128.00000,167.497 +192.00000,170.394 +256.00000,171.779 +384.00000,172.858 +512.00000,172.877 +768.00000,173.626 +1024.00000,173.702 diff --git a/benchmark_low_level/t14-lseq.csv b/benchmark_low_level/t14-lseq.csv new file mode 100644 index 0000000..1d0919e --- /dev/null +++ b/benchmark_low_level/t14-lseq.csv @@ -0,0 +1,41 @@ +0.00049,3.859 +0.00098,3.859 +0.00195,3.859 +0.00293,3.859 +0.00391,3.861 +0.00586,3.858 +0.00781,3.858 +0.01172,3.859 +0.01562,3.859 +0.02344,3.859 +0.03125,3.859 +0.04688,3.861 +0.06250,11.580 +0.09375,11.576 +0.12500,11.577 +0.18750,11.583 +0.25000,11.577 +0.37500,11.576 +0.50000,11.579 +0.75000,11.578 +1.00000,11.590 +1.50000,13.543 +2.00000,13.936 +3.00000,13.999 +4.00000,13.996 +6.00000,13.997 +8.00000,14.002 +12.00000,14.976 +16.00000,19.832 +24.00000,20.880 +32.00000,21.339 +48.00000,21.899 +64.00000,22.023 +96.00000,22.156 +128.00000,22.213 +192.00000,22.283 +256.00000,22.320 +384.00000,22.306 +512.00000,22.325 +768.00000,22.345 +1024.00000,22.361 diff --git a/benchmark_python/README.md b/benchmark_python/README.md new file mode 100644 index 0000000..51aa31e --- /dev/null +++ b/benchmark_python/README.md @@ -0,0 +1,29 @@ +## Benchmark +![](loading-timings-ns128.svg) +![](loading-slowdown-ns128.svg) + +## Benchmarks details + + - Create in memory a list of `N=128` one dimensional numpy arrays of length `L` starting from `L=2` up to `L=2^22=4_194_304` in steps of powers of two. + - Given that each item of the array is of type `float64`, i.e. 8 bytes, the size of the arrays goes from `16B` to `32M` + - The total memory required is at least `128 × 32M × 2 = 8G` + - Load the whole list in one big numpy array of size `N`x`L` (*good*) and `L`x`N` (*bad*). The corresponding loops are: + ```python + # good loop (store each time series on a different row) + for row, time_series in enumerate(collection): + ts[row, :] = time_series + ``` + + ```python + # bad loop (store each time series on a different column) + for column, time_series in enumerate(collection): + ts[:, column] = time_series + ``` + - Time the *bad* and the *good* loop + - Plot the timings for the *good* and the *bad* loop as a function of `L` + - Plot `slowdown = time_bad/time_good` as a function of `L` + +## Scripts + + - [Benchmark script](bench.py) and [measurements](results_ns128) + - [Plotting script](bench_plot.py) diff --git a/benchmark_python/bench.py b/benchmark_python/bench.py new file mode 100755 index 0000000..232cad4 --- /dev/null +++ b/benchmark_python/bench.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +# Commands and ideas from: https://llvm.org/docs/Benchmarking.html +# we assume that CPU 0 and 1 are together in an intel SMT-pair (hyperthreading) +# - Disable address space randomization: +# echo 0 > /proc/sys/kernel/randomize_va_space +# - Set scaling governor to performance for CPU 0 +# echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor +# - Reserve CPU 0 fro our benchmark +# cset shield --cpu 0 --kthread=on +# - Disable the SMT-peer of CPU 0, i.e. CPU 1 +# echo 0 > /sys/devices/system/cpu/cpu1/online +# - Disable turbo mode (works only on Intel): +# echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo +# - Run with +# cset shield --exec -- ./bench.py +# + +# To use the full power of the CPU, skip all the other steps and +# just run with +# taskset --cpu-list 0 ./bench.py +import os +import sys +import timeit + +import numpy as np + +NSERIES = (128, ) +POWS = 2**np.arange(2, 23, dtype=int) + +# Size of one dimensional numpy arrays of dtype 'float64': +# A fix overhead of 96 bytes plus a variable size: +# (n_items x 8 bytes) + +def load_data_row(x, time_series): + """Store one time series per raw""" + for row, ts in enumerate(time_series): + x[row,:] = ts + return x + +def load_data_column(x, time_series): + """Store one time series per column""" + for column, ts in enumerate(time_series): + x[:, column] = ts + return x + +if __name__ == '__main__': + for nseries in NSERIES: + print(30*'=', '\n', nseries) + float_items = POWS + byte_sizes = (float_items*8) #+ 96 + bads = [] + goods = [] + results = open(f'results_ns{nseries}', 'wt') + for i, len_one_series in enumerate(float_items): + time_series = np.zeros((nseries, len_one_series), dtype='float64') + x = np.empty((nseries, len_one_series), dtype='float64') + print('Timing good...') + good = min(timeit.repeat(lambda: load_data_row(x, time_series), number=5))/5 + x = np.empty((len_one_series, nseries), dtype='float64') + print('Timing bad...') + bad = min(timeit.repeat(lambda: load_data_column(x, time_series), number=5))/5 + print(f'{len_one_series}/{POWS[-1]} {good} {bad}') + bads.append(bad) + goods.append(good) + results.write(f'{byte_sizes[i]} {good} {bad}\n') + results.flush() + results.close() + diff --git a/benchmark_python/bench_plot.py b/benchmark_python/bench_plot.py new file mode 100755 index 0000000..15e184d --- /dev/null +++ b/benchmark_python/bench_plot.py @@ -0,0 +1,106 @@ +#!/usr/bin/python3 +import os +import sys + +import numpy as np +import matplotlib +from matplotlib import pyplot as plt +plt.style.use('ggplot') +matplotlib.rcParams['font.size'] = 12 +matplotlib.rcParams['font.family'] = ['Exo 2', 'sans-serif'] + +from bench import NSERIES + +def get_xlabels(x): + xlabels = [] + for value in x: + b = int(2**value) + if b < 1024: + xlabels.append(f'{b}B') + elif b < 1048576: + xlabels.append(f'{b//1024}K') + elif b < 1073741824: + xlabels.append(f'{b//1024//1024}M') + else: + xlabels.append(f'{b//1024//1024//1024}G') + return xlabels + +def get_ylabels(y): + ylabels = [] + for power in y: + power = int(np.log10(power)) + if power < -6: + value = 10**(power+9) + ylabels.append(f'{value}ns') + elif power < -3: + value = 10**(power+6) + ylabels.append(f'{value}μs') + elif power < 0: + value = 10**(power+3) + ylabels.append(f'{value}ms') + else: + value = 10**power + ylabels.append(f'{value}s') + return ylabels + +prefix = 'results_ns' +maxy = 1e1 +miny = 1e-6 +for results in (f for f in os.listdir('.') if f.startswith(prefix)): + num_series = results.removeprefix(prefix) + + sizes, bads, goods = [], [], [] + with open(results, 'r') as fh: + for line in fh: + size, good, bad = line.split() + bads.append(float(bad)) + goods.append(float(good)) + sizes.append(int(size)) + goods = np.array(goods) + bads = np.array(bads) + x = np.log2(sizes) + y1 = goods + y2 = bads + # generate two plots: good+bad timings and slowdown plot + plt.figure(figsize=(8.5, 7.5)) + p1, = plt.semilogy(x, y1, 'o') + p2, = plt.semilogy(x, y2, 'o') + plt.xlabel('size of one time series') + plt.ylabel('loading time') + plt.grid(None) + plt.grid(which='both', axis='both') + plt.xticks(x, get_xlabels(x), rotation=60) + plt.ylim(miny, maxy) + yticks = np.logspace(int(np.log10(miny)), + int(np.log10(maxy)), + num=int(np.log10(maxy/miny))+1) + plt.yticks(yticks, get_ylabels(yticks)) + plt.tick_params(axis='y', labelright=True, right=True) + lgd = plt.legend((p1, p2), ('good', 'bad'), frameon=True) + lgd.get_frame().set_edgecolor('black') + plt.title(f'Timings\n{num_series} time series') + plt.savefig(f'loading-timings-ns{num_series}.svg') + + # slowdown plot + plt.figure(figsize=(8.5, 7.5)) + p1, = plt.plot(x, bads/goods, 'og', label=r'$\frac{\mathrm{time\_bad}}{\mathrm{time\_good}}$') + plt.xlabel('size of one time series') + plt.ylabel('slowdown') + plt.grid(None) + plt.grid(which='both', axis='both') + plt.xticks(x, get_xlabels(x), rotation=60) + plt.tick_params(axis='y', which='both', reset=True, labelright=True, right=True) + lmaxy = (bads/goods).max() + yticks = range(0, int(np.ceil(lmaxy))+1) + yticks_labels = [] + for i in yticks: + if not i%5: + yticks_labels.append(str(i)) + else: + yticks_labels.append('') + plt.yticks(yticks, yticks_labels) + #plt.legend((p1,), ('time_bad/time_good',)) + lgd = plt.legend(frameon=True, fontsize=16) + lgd.get_frame().set_edgecolor('black') + plt.title(f'Slowdown\n{num_series} time series') + plt.savefig(f'loading-slowdown-ns{num_series}.svg') diff --git a/benchmark_python/loading-slowdown-ns128.svg b/benchmark_python/loading-slowdown-ns128.svg new file mode 100644 index 0000000..5f24215 --- /dev/null +++ b/benchmark_python/loading-slowdown-ns128.svg @@ -0,0 +1,2360 @@ + + + + + + + + 2024-08-05T16:24:04.379937 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmark_python/loading-timings-ns128.svg b/benchmark_python/loading-timings-ns128.svg new file mode 100644 index 0000000..68d0234 --- /dev/null +++ b/benchmark_python/loading-timings-ns128.svg @@ -0,0 +1,2348 @@ + + + + + + + + 2024-08-05T16:24:04.166622 + image/svg+xml + + + Matplotlib v3.8.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmark_python/results_ns128 b/benchmark_python/results_ns128 new file mode 100644 index 0000000..234cca4 --- /dev/null +++ b/benchmark_python/results_ns128 @@ -0,0 +1,21 @@ +32 3.624640012276359e-05 3.637080008047633e-05 +64 3.6378599907038735e-05 3.75960000383202e-05 +128 3.5999999818159266e-05 3.659379981399979e-05 +256 3.647979974630289e-05 3.8503600080730394e-05 +512 3.6466600067797114e-05 4.5260399929247797e-05 +1024 3.694279985211324e-05 6.389359987224452e-05 +2048 3.771199990296736e-05 0.00010158859986404422 +4096 3.9600799937034026e-05 0.00017927039989444892 +8192 4.872880017501302e-05 0.00035019980023207606 +16384 0.0001166390000435058 0.0009462125999561977 +32768 0.00020714380007120782 0.0018965299997944385 +65536 0.00041309340012958274 0.003799166400131071 +131072 0.0009548601999995298 0.013321203599844011 +262144 0.002020656999957282 0.03497214360031649 +524288 0.004090915599954314 0.07588242120000359 +1048576 0.008223017600175807 0.15468134920010926 +2097152 0.01658681320004689 0.3135109368002304 +4194304 0.03318921820027754 0.629940018599882 +8388608 0.031091862199900788 1.2587968365998676 +16777216 0.0620614524003031 2.517574722000063 +33554432 0.125347068800329 5.040295794399936 diff --git a/exercise-my-solution.ipynb b/exercise-my-solution.ipynb new file mode 100644 index 0000000..6d5861f --- /dev/null +++ b/exercise-my-solution.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T09:40:28.904Z", + "iopub.status.busy": "2024-03-04T09:40:28.896Z", + "iopub.status.idle": "2024-03-04T09:40:28.978Z", + "shell.execute_reply": "2024-03-04T09:40:28.967Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:02:39.062Z", + "iopub.status.busy": "2024-03-04T10:02:39.057Z", + "iopub.status.idle": "2024-03-04T10:02:39.068Z", + "shell.execute_reply": "2024-03-04T10:02:39.071Z" + } + }, + "outputs": [], + "source": [ + "n_series = 32\n", + "len_one_series = 5*2**20\n", + "time_series = np.random.rand(n_series, len_one_series)\n", + "gap = 16*2**10" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:02:41.027Z", + "iopub.status.busy": "2024-03-04T10:02:41.020Z", + "iopub.status.idle": "2024-03-04T10:02:41.036Z", + "shell.execute_reply": "2024-03-04T10:02:41.040Z" + }, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size of one time series: 40 M\n", + "Size of collection: 1280 M\n", + "Gap size: 128 K\n", + "Gapped series size: 2 K\n" + ] + } + ], + "source": [ + "print(f'Size of one time series: {int(time_series[0].nbytes/2**20)} M')\n", + "print(f'Size of collection: {int(time_series.nbytes/2**20)} M')\n", + "print(f'Gap size: {int(gap*8/2**10)} K')\n", + "print(f'Gapped series size: {int(time_series[0, ::gap].nbytes/2**10)} K')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following function implements an approximation of a power series of every `gap` value in our time series.\n", + "\n", + "If we define one time series of length `N` to be:\n", + "\n", + "$[x_0, x_1, x_2, ..., x_N]$,\n", + "\n", + "then the \"gapped\" series with `gap=g` is:\n", + "\n", + "$[x_0, x_g, x_{2g}, ..., x_{N/g}]$,\n", + "\n", + "where $N/g$ is the number of gaps.\n", + "\n", + "The approximation of the power series up to power `30` for our \"gapped\" series is defined as:\n", + "\n", + "$$\\mathbf{P} = \\sum_{p=0}^{30} \\sum_i x_i^{p} = \\sum_i x_i^0 + \\sum_i x_i^1 + \\sum_i x_i^2 + ... + \\sum_i x_i^{30} $$\n", + "\n", + "where $i \\in [0, g, 2g, ..., N/g]$" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:06:08.461Z", + "iopub.status.busy": "2024-03-04T10:06:08.459Z", + "iopub.status.idle": "2024-03-04T10:06:08.466Z", + "shell.execute_reply": "2024-03-04T10:06:08.468Z" + } + }, + "outputs": [], + "source": [ + "# compute an approximation of a power series for a collection of gapped timeseries\n", + "def power(time_series, P, gap):\n", + " for row in range(time_series.shape[0]):\n", + " for pwr in range(30):\n", + " P[row] += (time_series[row, ::gap]**pwr).sum()\n", + " return P\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Challenge\n", + "- Can you improve on the above implementation of the `power` function?\n", + "- Change the following `power_improved` function and see what you can do\n", + "- **Remember**: you can't change any other cell in this notebook!" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:06:08.461Z", + "iopub.status.busy": "2024-03-04T10:06:08.459Z", + "iopub.status.idle": "2024-03-04T10:06:08.466Z", + "shell.execute_reply": "2024-03-04T10:06:08.468Z" + } + }, + "outputs": [], + "source": [ + "def power_improved(time_series, P, gap):\n", + " y = time_series[:,::gap].copy()\n", + " for row in range(time_series.shape[0]):\n", + " for pwr in range(30):\n", + " P[row] += (y[row, :]**pwr).sum()\n", + " return P" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# verify that they yield the same results\n", + "P = np.zeros(n_series, dtype='float64')\n", + "out1 = power(time_series, P, gap)\n", + "P = np.zeros(n_series, dtype='float64')\n", + "out2 = power_improved(time_series, P, gap)\n", + "np.testing.assert_allclose(out1, out2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:06:14.959Z", + "iopub.status.busy": "2024-03-04T10:06:14.956Z", + "iopub.status.idle": "2024-03-04T10:06:17.437Z", + "shell.execute_reply": "2024-03-04T10:06:17.443Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "38.9 ms ± 492 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" + ] + } + ], + "source": [ + "P = np.zeros(n_series, dtype='float64')\n", + "%timeit power(time_series, P, gap)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "execution": { + "iopub.execute_input": "2024-03-04T10:06:20.056Z", + "iopub.status.busy": "2024-03-04T10:06:20.053Z", + "iopub.status.idle": "2024-03-04T10:06:21.695Z", + "shell.execute_reply": "2024-03-04T10:06:21.700Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6.79 ms ± 35.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "P = np.zeros(n_series, dtype='float64')\n", + "%timeit power_improved(time_series, P, gap)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.5" + }, + "nteract": { + "version": "0.28.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/numpy/README.md b/numpy/README.md new file mode 100644 index 0000000..a73b534 --- /dev/null +++ b/numpy/README.md @@ -0,0 +1,31 @@ +# Anatomy of a numpy array +## one dimension, float64 +![1d array](ndarray-memory-layout-1d.svg) + +## two dimensions, square, float64 +![2d array - square](ndarray-memory-layout-2d-square.svg) + +## two dimensions, rectangular, int32 +![2d array - rectangular](ndarray-memory-layout-2d-rectangular.svg) + +## what about Python lists? +![memory layout of a Python list](python-list-memory-layout.svg) + +## interesting attributes of numpy arrays + - `x.data`, `x.data.hex()`, `x.data.format`, `x.tobytes()` + - `x.flags`: + - `OWNDATA` + - `C_CONTIGUOUS` + - `F_CONTIGUOUS` + - more [flags](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.flags.html) + +## If your arrays are bigger than RAM + - [`numpy.memmap`](https://numpy.org/doc/stable/reference/generated/numpy.memmap.html): an array-like + object that maps memory to an array stored on disk, used for accessing small segments of large + files on disk, without reading the entire file into memory. Use with caution! + + - [`HDF5`](https://support.hdfgroup.org/documentation/hdf5/latest/_intro_h_d_f5.html): hierarchical + data format, with aribitrary metadata and multilanguage support + with [`h5py`](https://docs.h5py.org/en/stable/) with an array-lie interface + - other projects, for example [`xarray`](https://docs.xarray.dev/en/stable/) + and [`zarr`](https://zarr.readthedocs.io/en/stable/) diff --git a/numpy/ndarray-memory-layout-1d.svg b/numpy/ndarray-memory-layout-1d.svg new file mode 100644 index 0000000..26e8c2a --- /dev/null +++ b/numpy/ndarray-memory-layout-1d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/numpy/ndarray-memory-layout-2d-rectangular.svg b/numpy/ndarray-memory-layout-2d-rectangular.svg new file mode 100644 index 0000000..cff7818 --- /dev/null +++ b/numpy/ndarray-memory-layout-2d-rectangular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/numpy/ndarray-memory-layout-2d-square.svg b/numpy/ndarray-memory-layout-2d-square.svg new file mode 100644 index 0000000..69e08b9 --- /dev/null +++ b/numpy/ndarray-memory-layout-2d-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/numpy/python-list-memory-layout.svg b/numpy/python-list-memory-layout.svg new file mode 100644 index 0000000..358c330 --- /dev/null +++ b/numpy/python-list-memory-layout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/parallel/README.md b/parallel/README.md new file mode 100644 index 0000000..73d4d1d --- /dev/null +++ b/parallel/README.md @@ -0,0 +1,24 @@ +# The dangers and joys of automatic parallelization (like in numpy linear algebra routines) and the use of clusters/schedulers (but also on your laptop) +- Go through the [notebook](../parallel.ipynb) to play around with numpy auto-parallelization, CPU affinity and OpenMP thread pool control + +- Now we want to submit our code to a cluster, or even just running it in parallel on our own laptop: + - run [`overcommit.py`](overcommit.py) while monitoring with htop + - try the [`submit.sh`](submit.sh) script + - see problems with overcomitting + - explain the PSI (Pressure Stalled Information) fields in `htop`. Useful readings: + - https://docs.kernel.org/accounting/psi.html + - https://facebookmicrosites.github.io/psi/docs/overview +- Discuss implications for local and cluster workflows + +# Hands on +- Let's try to make it more quantitative: + - Write a benchmark in the style of [benchmark_python](../benchmark_python/bench.py) + - We want to assess the performance of matrix multiplication as a function of: + - the size of the matrix `N` + - the number of openMP threads `T`, controlled with `threadpoolctl` or by environment variable `OMP_NUM_THREADS` + - the number of processes `P`, controlled by the [`submit.sh`](submit.sh) script or something similar +- The results will of course depend on the particular architecture of the machine on which you are running +- Submit your benchmark, together with some plotting routines, as a PR to this repo! + + + diff --git a/setup/generate_materials.py b/setup/generate_materials.py new file mode 100644 index 0000000..1c8a3b1 --- /dev/null +++ b/setup/generate_materials.py @@ -0,0 +1,37 @@ +MSVG = 'template.svg' +TEMPL = '0xNN' +NREG = 4 +N = 30 + + +import sys +import subprocess + +if N > 255: + print('cannot do it!') + sys.exit() + +addresses = [hex(i).replace("0x", "0x0") for i in range(N//2+1)] + \ + [hex(i) for i in range(N//2+1,N)] + \ + [f'REG{i}' for i in range(NREG)] + +msvg = open(MSVG).read() +delete = [] +to_join = [] +for a in addresses: + print(f'Processing {a}...') + new_svg = a+MSVG + new_svg_pdf = new_svg.replace('.svg', '.pdf') + with open(new_svg, 'wt') as svg: + svg.write(msvg.replace(TEMPL,a)) + delete.extend([new_svg, new_svg_pdf]) + subprocess.run(['inkscape', '--export-filename='+new_svg_pdf, new_svg], capture_output=True) + to_join.append(new_svg_pdf) + +subprocess.run(['pdftk'] + to_join + ['output', 'materials.pdf'], capture_output=True) +subprocess.check_call(['rm'] + delete) + + + + + diff --git a/setup/materials.pdf b/setup/materials.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fdc550077424001351c0f8260d342e1e90dcd2b4 GIT binary patch literal 215911 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[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 q+S(pe4AuZ_#mc76hI + + + + + + + + + + + + + + + 0xNN + 0xNN + +