From 6b3b1c64328fb6b4932dfb67fd05486182657673 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Wed, 30 Sep 2026 03:42:36 +0100 Subject: Say what the windows and checkpoints cost (013 steps 2 and 3, 104) 013's second step is in (d9e0b68): each transport holds a window of its output's sends. 104 measures it with the receivers down: once the window is full a node grows by the outbox alone, 219 and 218 B a send over the link and HTTP (399 and 534 B before). The third step is a measurement. A checkpoint holds one list's snapshot while it writes the image, so what it adds is what the app changed meanwhile: nothing visible on tmpfs or for a list that fits the card's fast writes; on the SD card, a 22.4 MB list written for about 8 s while 1,400 items a second were set left +3.0 and +4.4 MiB. The highest resident memory was twice the state bytes, inside 013's bound (the state and one snapshot) and its stop criterion (3x). 021's run.py takes --items, --stores (a directory on the device to measure) and --label, and reports the peak (VmHWM). --- .../2026-09-30-checkpoint-linux-aarch64.jsonl | 3 +++ .../2026-09-30-window-linux-aarch64.jsonl | 2 ++ research/experiments/021-memory/run.py | 25 +++++++++++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 research/experiments/021-memory/2026-09-30-checkpoint-linux-aarch64.jsonl create mode 100644 research/experiments/021-memory/2026-09-30-window-linux-aarch64.jsonl (limited to 'research/experiments/021-memory') diff --git a/research/experiments/021-memory/2026-09-30-checkpoint-linux-aarch64.jsonl b/research/experiments/021-memory/2026-09-30-checkpoint-linux-aarch64.jsonl new file mode 100644 index 0000000..1fbe32f --- /dev/null +++ b/research/experiments/021-memory/2026-09-30-checkpoint-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"label": "tmpfs", "case": "unheld", "seconds": 30, "posted": 205531, "refused": 0, "rss_began_kib": 11312, "rss_end_kib": 11728, "rss_peak_kib": 11728, "items": 50000, "rss_per_post_bytes": 2.1, "store_bytes": 22647708, "samples": [[0.0, 11312, 0], [2.0, 11696, 13881], [4.01, 11696, 27968], [6.01, 11696, 41364], [8.01, 11696, 54455], [10.02, 11728, 67781], [12.02, 11728, 81825], [14.03, 11728, 95982], [16.03, 11728, 110099], [18.03, 11728, 123891], [20.04, 11728, 137984], [22.04, 11728, 151784], [24.04, 11728, 164949], [26.05, 11728, 178675], [28.05, 11728, 192438], [30.05, 11728, 205527], [30.05, 11728, 205527]], "stats": {"active": 0, "retained_payload_bytes": 0, "accepted": 8, "requests": 255531, "bursts": 152162, "burst_events": 255531, "ticks": 0, "expired": 0, "threads": 2, "owner": true, "snapshots": 152163, "views_from_snapshots": 0, "delivered": 0, "delivery_attempts": 0, "answers": 0, "commit_groups": 0, "grouped_commits": 0, "checkpoints": 4, "link_packets": 0, "link_records": 0, "link_resent": 0, "link_lost": 0, "link_acknowledged": 0, "link_stored": 0, "link_refused": 0, "listener_packets": 0, "listener_received": 0, "listener_deliveries": 0, "listener_woken": 0, "listener_remembered": 0, "listener_swept": 0, "listener_active": 0, "listener_keyed": 0, "listener_secrets": 0, "listener_epochs": 0, "listener_refused": 0, "state_bytes": 5600000, "memory_refused": 0, "windows_full": 0}} +{"label": "sd-card", "case": "unheld", "seconds": 30, "posted": 36522, "refused": 0, "rss_began_kib": 11568, "rss_end_kib": 11920, "rss_peak_kib": 11920, "items": 50000, "rss_per_post_bytes": 9.9, "store_bytes": 22647708, "samples": [[0.0, 11568, 0], [2.0, 11872, 2094], [4.0, 11920, 4139], [6.01, 11920, 6475], [8.01, 11920, 8779], [10.01, 11920, 11122], [12.01, 11920, 13701], [14.01, 11920, 16234], [16.01, 11920, 18733], [18.01, 11920, 21216], [20.01, 11920, 23727], [22.02, 11920, 26210], [24.02, 11920, 28596], [26.02, 11920, 30956], [28.02, 11920, 33798], [30.02, 11920, 36518], [30.02, 11920, 36518]], "stats": {"active": 0, "retained_payload_bytes": 0, "accepted": 8, "requests": 86522, "bursts": 24027, "burst_events": 86522, "ticks": 0, "expired": 0, "threads": 2, "owner": true, "snapshots": 24028, "views_from_snapshots": 0, "delivered": 0, "delivery_attempts": 0, "answers": 0, "commit_groups": 0, "grouped_commits": 0, "checkpoints": 1, "link_packets": 0, "link_records": 0, "link_resent": 0, "link_lost": 0, "link_acknowledged": 0, "link_stored": 0, "link_refused": 0, "listener_packets": 0, "listener_received": 0, "listener_deliveries": 0, "listener_woken": 0, "listener_remembered": 0, "listener_swept": 0, "listener_active": 0, "listener_keyed": 0, "listener_secrets": 0, "listener_epochs": 0, "listener_refused": 0, "state_bytes": 5600000, "memory_refused": 0, "windows_full": 0}} +{"label": "sd-card", "case": "unheld", "seconds": 240, "posted": 331881, "refused": 0, "rss_began_kib": 35920, "rss_end_kib": 43488, "rss_peak_kib": 43488, "items": 200000, "rss_per_post_bytes": 23.4, "store_bytes": 56224924, "samples": [[0.0, 35920, 0], [2.0, 36016, 2823], [4.01, 36016, 5611], [6.01, 36416, 7810], [8.01, 38048, 9291], [10.01, 39136, 11267], [12.01, 39136, 14243], [14.01, 39136, 16904], [16.01, 39136, 19857], [18.01, 39136, 22534], [20.01, 39136, 25452], [22.01, 39136, 28212], [24.01, 39136, 30754], [26.02, 39136, 33010], [28.02, 39136, 35403], [30.02, 39136, 37617], [32.02, 39136, 39666], [34.02, 39136, 42030], [36.02, 39136, 44303], [38.02, 39136, 46536], [40.02, 39136, 48546], [42.02, 39136, 50862], [44.03, 39136, 53150], [46.03, 39136, 55317], [48.03, 39136, 57851], [50.03, 39136, 60239], [52.03, 39136, 62468], [54.03, 39136, 64813], [56.03, 39136, 66894], [58.03, 39136, 69147], [60.03, 39136, 71306], [62.03, 39136, 73476], [64.04, 39136, 75829], [66.04, 39136, 78844], [68.04, 39136, 81637], [70.04, 39136, 84140], [72.04, 39136, 86830], [74.04, 39136, 89258], [76.04, 39136, 92081], [78.04, 39136, 95081], [80.04, 39136, 98077], [82.04, 39136, 100937], [84.05, 39136, 103911], [86.05, 39136, 106974], [88.05, 39136, 109948], [90.05, 39136, 113173], [92.05, 39136, 116688], [94.05, 39136, 120226], [96.05, 39136, 123090], [98.05, 39136, 125795], [100.05, 39136, 129171], [102.06, 39136, 132362], [104.06, 39136, 135085], [106.06, 39136, 138303], [108.06, 39136, 141374], [110.06, 39136, 144455], [112.06, 39136, 147323], [114.06, 39136, 150009], [116.06, 39136, 152857], [118.06, 39136, 155628], [120.07, 39136, 158297], [122.07, 39136, 160911], [124.07, 39136, 164122], [126.07, 39136, 167114], [128.07, 39136, 169741], [130.07, 39136, 172414], [132.07, 39136, 175596], [134.07, 39136, 179054], [136.07, 39136, 182091], [138.07, 39136, 185356], [140.08, 39136, 188694], [142.08, 39136, 191798], [144.08, 39136, 195078], [146.08, 39136, 198423], [148.08, 39136, 201395], [150.08, 39136, 204285], [152.08, 39136, 207284], [154.08, 39136, 210240], [156.08, 39136, 213144], [158.08, 39136, 215643], [160.09, 39136, 218353], [162.09, 39136, 220651], [164.09, 39536, 222664], [166.09, 41056, 225034], [168.09, 41872, 226643], [170.09, 42832, 228707], [172.09, 43632, 230744], [174.09, 43488, 233315], [176.09, 43488, 235998], [178.09, 43488, 238643], [180.1, 43488, 241252], [182.1, 43488, 244278], [184.1, 43488, 247052], [186.1, 43488, 250316], [188.1, 43488, 253671], [190.1, 43488, 256698], [192.1, 43488, 259851], [194.11, 43488, 263181], [196.11, 43488, 266340], [198.11, 43488, 269500], [200.11, 43488, 272626], [202.11, 43488, 275599], [204.11, 43488, 278757], [206.11, 43488, 282039], [208.11, 43488, 285131], [210.11, 43488, 288008], [212.12, 43488, 290872], [214.12, 43488, 294022], [216.12, 43488, 297195], [218.12, 43488, 300336], [220.12, 43488, 303276], [222.12, 43488, 306555], [224.12, 43488, 309734], [226.12, 43488, 312564], [228.12, 43488, 315365], [230.13, 43488, 317789], [232.13, 43488, 320287], [234.13, 43488, 323353], [236.13, 43488, 326444], [238.13, 43488, 329302], [240.13, 43488, 331877], [240.13, 43488, 331877]], "stats": {"active": 0, "retained_payload_bytes": 0, "accepted": 8, "requests": 531881, "bursts": 144699, "burst_events": 531881, "ticks": 0, "expired": 0, "threads": 2, "owner": true, "snapshots": 144700, "views_from_snapshots": 0, "delivered": 0, "delivery_attempts": 0, "answers": 0, "commit_groups": 0, "grouped_commits": 0, "checkpoints": 2, "link_packets": 0, "link_records": 0, "link_resent": 0, "link_lost": 0, "link_acknowledged": 0, "link_stored": 0, "link_refused": 0, "listener_packets": 0, "listener_received": 0, "listener_deliveries": 0, "listener_woken": 0, "listener_remembered": 0, "listener_swept": 0, "listener_active": 0, "listener_keyed": 0, "listener_secrets": 0, "listener_epochs": 0, "listener_refused": 0, "state_bytes": 22400000, "memory_refused": 0, "windows_full": 0}} diff --git a/research/experiments/021-memory/2026-09-30-window-linux-aarch64.jsonl b/research/experiments/021-memory/2026-09-30-window-linux-aarch64.jsonl new file mode 100644 index 0000000..7370490 --- /dev/null +++ b/research/experiments/021-memory/2026-09-30-window-linux-aarch64.jsonl @@ -0,0 +1,2 @@ +{"label": "window", "case": "link-down", "seconds": 30, "posted": 202933, "refused": 0, "rss_began_kib": 8688, "rss_end_kib": 58976, "rss_per_post_bytes": 253.8, "store_bytes": 34678695, "samples": [[0.0, 8688, 0], [2.0, 14384, 13522], [4.01, 19600, 27002], [6.01, 24224, 40567], [8.01, 26928, 52717], [10.01, 29760, 66334], [12.02, 32656, 80087], [14.02, 35632, 93864], [16.02, 38640, 107662], [18.03, 41520, 121411], [20.03, 44464, 135167], [22.03, 47360, 148920], [24.03, 50192, 162021], [26.04, 53120, 175808], [28.04, 56128, 189345], [30.04, 58976, 202929], [30.04, 58976, 202929]], "stats": {"active": 0, "retained_payload_bytes": 0, "accepted": 4, "requests": 202933, "bursts": 122711, "burst_events": 202933, "ticks": 0, "expired": 0, "threads": 2, "owner": true, "snapshots": 122712, "views_from_snapshots": 0, "delivered": 0, "delivery_attempts": 0, "answers": 0, "commit_groups": 122712, "grouped_commits": 122712, "checkpoints": 0, "link_packets": 67, "link_records": 350, "link_resent": 32, "link_lost": 0, "link_acknowledged": 0, "link_stored": 0, "link_refused": 0, "listener_packets": 0, "listener_received": 0, "listener_deliveries": 0, "listener_woken": 0, "listener_remembered": 0, "listener_swept": 0, "listener_active": 0, "listener_keyed": 0, "listener_secrets": 0, "listener_epochs": 0, "listener_refused": 0, "state_bytes": 27598888, "memory_refused": 0, "windows_full": 100054}} +{"label": "window", "case": "wire-down", "seconds": 30, "posted": 202831, "refused": 0, "rss_began_kib": 3104, "rss_end_kib": 55856, "rss_per_post_bytes": 266.3, "store_bytes": 34678695, "samples": [[0.0, 3104, 0], [2.0, 10528, 13345], [4.01, 17488, 26797], [6.01, 21232, 40539], [8.01, 24192, 53780], [10.01, 26896, 67387], [12.02, 29728, 80588], [14.02, 32672, 94295], [16.02, 35648, 108084], [18.03, 38464, 121233], [20.03, 41376, 135025], [22.03, 44320, 148807], [24.03, 47088, 161562], [26.04, 50096, 175369], [28.04, 52928, 189121], [30.04, 55920, 202827], [30.04, 55920, 202827]], "stats": {"active": 0, "retained_payload_bytes": 0, "accepted": 4, "requests": 202831, "bursts": 121645, "burst_events": 202831, "ticks": 0, "expired": 0, "threads": 2, "owner": true, "snapshots": 121646, "views_from_snapshots": 0, "delivered": 0, "delivery_attempts": 9, "answers": 0, "commit_groups": 121646, "grouped_commits": 121646, "checkpoints": 0, "link_packets": 0, "link_records": 0, "link_resent": 0, "link_lost": 0, "link_acknowledged": 0, "link_stored": 0, "link_refused": 0, "listener_packets": 0, "listener_received": 0, "listener_deliveries": 0, "listener_woken": 0, "listener_remembered": 0, "listener_swept": 0, "listener_active": 0, "listener_keyed": 0, "listener_secrets": 0, "listener_epochs": 0, "listener_refused": 0, "state_bytes": 27585016, "memory_refused": 0, "windows_full": 103922}} diff --git a/research/experiments/021-memory/run.py b/research/experiments/021-memory/run.py index 49bb5a9..546bfbc 100644 --- a/research/experiments/021-memory/run.py +++ b/research/experiments/021-memory/run.py @@ -15,7 +15,12 @@ size at the end. unheld the same, no surface python3 research/experiments/021-memory/run.py [--seconds 30] [--cases outbox,budget,held] [--out FILE] - [--label NAME] + [--label NAME] [--items 20000] [--stores DIRECTORY] + +--items sets how many items held and unheld begin with; --stores puts the +stores in a directory of the device to measure (a flash card: checkpoints +then take long, and a snapshot is held that long). Each row gives the peak +resident memory too (VmHWM). PURE_SERVE=PATH runs another build's pure-serve (--label names it in the rows). """ @@ -87,10 +92,10 @@ def start(args): return process, json.loads(line)['port'] -def rss_kib(pid): +def rss_kib(pid, field='VmRSS:'): with open(f'/proc/{pid}/status') as status: for line in status: - if line.startswith('VmRSS:'): + if line.startswith(field): return int(line.split()[1]) return 0 @@ -121,8 +126,8 @@ def post_all(port, bodies, stop, counts, index, refused): connection.close() -def run_case(case, work, seconds, clients=4): - store = work / f'store-{case}' +def run_case(case, work, seconds, clients=4, stores=None): + store = (stores or work) / f'store-{case}-{os.getpid()}' args = [SERVE, '--store', store, '--threads', '2'] note = 'n' * NOTE if case in ('outbox', 'budget', 'link-down', 'wire-down'): @@ -183,31 +188,35 @@ def run_case(case, work, seconds, clients=4): stop.set() for t in threads: t.join() - rss_end = rss_kib(process.pid) + rss_end, rss_peak = rss_kib(process.pid), rss_kib(process.pid, 'VmHWM:') finally: process.send_signal(signal.SIGTERM) _, error = process.communicate(timeout=60) stats = [json.loads(line) for line in error.decode().splitlines() if line.startswith('{"active"')] posted = sum(counts) return {'case': case, 'seconds': seconds, 'posted': posted, 'refused': sum(refused), 'rss_began_kib': rss_began, - 'rss_end_kib': rss_end, + 'rss_end_kib': rss_end, 'rss_peak_kib': rss_peak, 'items': SEEDED, 'rss_per_post_bytes': round((rss_end - rss_began) * 1024 / posted, 1) if posted else None, 'store_bytes': store_bytes(store), 'samples': samples[::4] + [samples[-1]], 'stats': stats[-1] if stats else None} def main(): + global SEEDED parser = argparse.ArgumentParser() parser.add_argument('--seconds', type=int, default=30) parser.add_argument('--cases', default='outbox,budget,link-down,wire-down,unheld,held') parser.add_argument('--out', type=Path, default=None) parser.add_argument('--label', default=None, help='the build, named in each row') + parser.add_argument('--items', type=int, default=SEEDED) + parser.add_argument('--stores', type=Path, default=None) args = parser.parse_args() + SEEDED = args.items with tempfile.TemporaryDirectory(prefix='pure-memory-') as directory: work = Path(directory) build(work) for case in args.cases.split(','): - row = run_case(case, work, args.seconds) + row = run_case(case, work, args.seconds, stores=args.stores) if args.label: row = {'label': args.label, **row} line = json.dumps(row) -- cgit v1.2.3