diff --git a/architecture/README.md b/architecture/README.md
index 2b8cd20..b912d14 100644
--- a/architecture/README.md
+++ b/architecture/README.md
@@ -99,4 +99,22 @@ My Laptop:
- 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/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 @@
+
+
+
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..c3c2e66
--- /dev/null
+++ b/architecture/memory.py
@@ -0,0 +1,100 @@
+# 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.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}')
+ 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))
+ 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..f2a2c59
--- /dev/null
+++ b/architecture/memory_bandwidth.svg
@@ -0,0 +1,2552 @@
+
+
+
diff --git a/architecture/memory_clock.svg b/architecture/memory_clock.svg
new file mode 100644
index 0000000..f379707
--- /dev/null
+++ b/architecture/memory_clock.svg
@@ -0,0 +1,1704 @@
+
+
+
diff --git a/architecture/memory_latency.svg b/architecture/memory_latency.svg
new file mode 100644
index 0000000..12c5030
--- /dev/null
+++ b/architecture/memory_latency.svg
@@ -0,0 +1,1900 @@
+
+
+
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 @@
+
+
+