From b1ce1927022d374198441afafeb27199fc8a052a Mon Sep 17 00:00:00 2001 From: eunhhu Date: Thu, 24 Sep 2026 17:14:54 +0100 Subject: Establish native micro runtime checkpoint --- .../2026-09-24-check-hybrid.log.gz | Bin 0 -> 6376 bytes .../2026-09-24-ext4-linux-aarch64.json | 463 +++++++++++ .../2026-09-24-sequence-ext4-linux-aarch64.json | 862 +++++++++++++++++++++ .../005-storage-edit-latency/copy-memory.json | 43 + .../005-storage-edit-latency/flat-memory.json | 43 + .../005-storage-edit-latency/measure.py | 99 +++ .../005-storage-edit-latency/paged-memory.json | 43 + .../005-storage-edit-latency/sequence.py | 85 ++ 8 files changed, 1638 insertions(+) create mode 100644 research/experiments/005-storage-edit-latency/2026-09-24-check-hybrid.log.gz create mode 100644 research/experiments/005-storage-edit-latency/2026-09-24-ext4-linux-aarch64.json create mode 100644 research/experiments/005-storage-edit-latency/2026-09-24-sequence-ext4-linux-aarch64.json create mode 100644 research/experiments/005-storage-edit-latency/copy-memory.json create mode 100644 research/experiments/005-storage-edit-latency/flat-memory.json create mode 100644 research/experiments/005-storage-edit-latency/measure.py create mode 100644 research/experiments/005-storage-edit-latency/paged-memory.json create mode 100644 research/experiments/005-storage-edit-latency/sequence.py (limited to 'research/experiments/005-storage-edit-latency') diff --git a/research/experiments/005-storage-edit-latency/2026-09-24-check-hybrid.log.gz b/research/experiments/005-storage-edit-latency/2026-09-24-check-hybrid.log.gz new file mode 100644 index 0000000..e4c0174 Binary files /dev/null and b/research/experiments/005-storage-edit-latency/2026-09-24-check-hybrid.log.gz differ diff --git a/research/experiments/005-storage-edit-latency/2026-09-24-ext4-linux-aarch64.json b/research/experiments/005-storage-edit-latency/2026-09-24-ext4-linux-aarch64.json new file mode 100644 index 0000000..f9decda --- /dev/null +++ b/research/experiments/005-storage-edit-latency/2026-09-24-ext4-linux-aarch64.json @@ -0,0 +1,463 @@ +{ + "profile": "native-cli-durable-one-mib-document-last-byte-edit", + "platform": "Linux-6.18.39+rpt-rpi-2712-aarch64-with-glibc2.41", + "filesystem": "ext4 /dev/mmcblk0p2[/home/eunhhu/work/pure]", + "trials_per_variant": 18, + "final_body_sha256": "06cb5e32505f66804f6e8c79e3230105ca4769444e1389ee36f6f11fd61f2d3a", + "scope": "Each sample starts a new CLI process; create and edit each include program parsing, store initialization, file and directory synchronization. Show verifies the final revision but is outside the timed operations. The host page cache, filesystem and device remain uncontrolled.", + "variants": { + "flat": { + "binary_sha256": "23ebc0ce1df9c49216511bee658fd5b9e373509e296bd2c2f8e76e6d3081cded", + "median_create_ms": 83.556, + "median_edit_ms": 78.805, + "samples": [ + { + "trial": 0, + "create_ms": 93.308, + "edit_ms": 86.265, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 1, + "create_ms": 66.85, + "edit_ms": 81.315, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 2, + "create_ms": 83.243, + "edit_ms": 26.218, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 3, + "create_ms": 25.734, + "edit_ms": 81.636, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 4, + "create_ms": 80.359, + "edit_ms": 22.923, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 5, + "create_ms": 84.855, + "edit_ms": 77.624, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 6, + "create_ms": 83.516, + "edit_ms": 24.882, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 7, + "create_ms": 100.653, + "edit_ms": 65.551, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 8, + "create_ms": 87.547, + "edit_ms": 88.306, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 9, + "create_ms": 100.781, + "edit_ms": 89.489, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 10, + "create_ms": 29.332, + "edit_ms": 79.987, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 11, + "create_ms": 80.05, + "edit_ms": 26.629, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 12, + "create_ms": 79.751, + "edit_ms": 24.165, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 13, + "create_ms": 85.309, + "edit_ms": 23.163, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 14, + "create_ms": 83.597, + "edit_ms": 82.171, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 15, + "create_ms": 97.909, + "edit_ms": 85.934, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 16, + "create_ms": 25.638, + "edit_ms": 82.514, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 17, + "create_ms": 86.699, + "edit_ms": 23.813, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + } + ] + }, + "copy": { + "binary_sha256": "52c2b828b0cba3564a37e3874f60bec793d1dd7031aff77ba850cee7683977f9", + "median_create_ms": 81.672, + "median_edit_ms": 77.908, + "samples": [ + { + "trial": 0, + "create_ms": 29.767, + "edit_ms": 78.001, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 1, + "create_ms": 89.789, + "edit_ms": 91.286, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 2, + "create_ms": 83.106, + "edit_ms": 77.868, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 3, + "create_ms": 84.346, + "edit_ms": 47.881, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 4, + "create_ms": 29.06, + "edit_ms": 78.142, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 5, + "create_ms": 29.801, + "edit_ms": 52.17, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 6, + "create_ms": 81.026, + "edit_ms": 77.948, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 7, + "create_ms": 30.027, + "edit_ms": 87.974, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 8, + "create_ms": 45.522, + "edit_ms": 87.955, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 9, + "create_ms": 80.228, + "edit_ms": 22.863, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 10, + "create_ms": 82.319, + "edit_ms": 77.564, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 11, + "create_ms": 94.951, + "edit_ms": 46.186, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 12, + "create_ms": 84.607, + "edit_ms": 80.2, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 13, + "create_ms": 29.82, + "edit_ms": 86.258, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 14, + "create_ms": 94.36, + "edit_ms": 31.893, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 15, + "create_ms": 97.289, + "edit_ms": 44.737, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 16, + "create_ms": 60.805, + "edit_ms": 80.635, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + }, + { + "trial": 17, + "create_ms": 85.887, + "edit_ms": 77.182, + "store_files": 2, + "store_file_bytes": 1048600, + "store_allocated_bytes": 1052672 + } + ] + }, + "paged": { + "binary_sha256": "e1c12a2f5e736bb86737ceff7849fe95b1a9d13136e8c5eb3f3398cb3971c6f5", + "median_create_ms": 88.948, + "median_edit_ms": 14.473, + "samples": [ + { + "trial": 0, + "create_ms": 117.897, + "edit_ms": 565.484, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 1, + "create_ms": 47.619, + "edit_ms": 13.102, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 2, + "create_ms": 89.46, + "edit_ms": 14.779, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 3, + "create_ms": 30.501, + "edit_ms": 15.016, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 4, + "create_ms": 89.223, + "edit_ms": 13.383, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 5, + "create_ms": 88.518, + "edit_ms": 12.718, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 6, + "create_ms": 88.992, + "edit_ms": 13.681, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 7, + "create_ms": 116.568, + "edit_ms": 23.607, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 8, + "create_ms": 100.547, + "edit_ms": 24.497, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 9, + "create_ms": 54.374, + "edit_ms": 13.896, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 10, + "create_ms": 84.894, + "edit_ms": 13.607, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 11, + "create_ms": 92.673, + "edit_ms": 14.166, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 12, + "create_ms": 34.961, + "edit_ms": 78.767, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 13, + "create_ms": 88.903, + "edit_ms": 13.656, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 14, + "create_ms": 57.426, + "edit_ms": 13.968, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 15, + "create_ms": 38.675, + "edit_ms": 14.937, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 16, + "create_ms": 90.664, + "edit_ms": 15.344, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + }, + { + "trial": 17, + "create_ms": 90.055, + "edit_ms": 14.926, + "store_files": 3, + "store_file_bytes": 1065520, + "store_allocated_bytes": 1069056 + } + ] + } + } +} diff --git a/research/experiments/005-storage-edit-latency/2026-09-24-sequence-ext4-linux-aarch64.json b/research/experiments/005-storage-edit-latency/2026-09-24-sequence-ext4-linux-aarch64.json new file mode 100644 index 0000000..5efbf8b --- /dev/null +++ b/research/experiments/005-storage-edit-latency/2026-09-24-sequence-ext4-linux-aarch64.json @@ -0,0 +1,862 @@ +{ + "profile": "repeated-durable-one-mib-document-last-byte-edit", + "platform": "Linux-6.18.39+rpt-rpi-2712-aarch64-with-glibc2.41", + "filesystem": "ext4 /dev/mmcblk0p2[/home/eunhhu/work/pure]", + "edits_per_variant": 70, + "final_body_sha256": "3cfc240f48e8e1b8553f3e2670adf7b81cafe34f089d4372fa4c28787dc02151", + "scope": "Same actual source-loaded CLI and editor.pure, two persistent stores, alternating operation order. Timings include each edit process, parser, store init and fsync; creation and final show are not timed. Device state is uncontrolled.", + "variants": { + "flat": { + "binary_sha256": "23ebc0ce1df9c49216511bee658fd5b9e373509e296bd2c2f8e76e6d3081cded", + "median_edit_ms": 83.176, + "samples": [ + { + "edit": 1, + "elapsed_ms": 24.328, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 2, + "elapsed_ms": 79.862, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 3, + "elapsed_ms": 177.059, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 4, + "elapsed_ms": 89.804, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 5, + "elapsed_ms": 92.579, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 6, + "elapsed_ms": 83.733, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 7, + "elapsed_ms": 29.379, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 8, + "elapsed_ms": 78.191, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 9, + "elapsed_ms": 57.551, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 10, + "elapsed_ms": 83.875, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 11, + "elapsed_ms": 78.209, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 12, + "elapsed_ms": 85.296, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 13, + "elapsed_ms": 25.204, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 14, + "elapsed_ms": 28.663, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 15, + "elapsed_ms": 82.153, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 16, + "elapsed_ms": 84.924, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 17, + "elapsed_ms": 82.359, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 18, + "elapsed_ms": 39.211, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 19, + "elapsed_ms": 28.648, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 20, + "elapsed_ms": 82.115, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 21, + "elapsed_ms": 83.895, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 22, + "elapsed_ms": 83.007, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 23, + "elapsed_ms": 84.496, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 24, + "elapsed_ms": 28.525, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 25, + "elapsed_ms": 86.499, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 26, + "elapsed_ms": 25.536, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 27, + "elapsed_ms": 93.217, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 28, + "elapsed_ms": 36.673, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 29, + "elapsed_ms": 84.748, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 30, + "elapsed_ms": 79.529, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 31, + "elapsed_ms": 84.024, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 32, + "elapsed_ms": 82.681, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 33, + "elapsed_ms": 28.903, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 34, + "elapsed_ms": 29.254, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 35, + "elapsed_ms": 86.486, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 36, + "elapsed_ms": 96.679, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 37, + "elapsed_ms": 41.477, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 38, + "elapsed_ms": 82.386, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 39, + "elapsed_ms": 25.063, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 40, + "elapsed_ms": 27.84, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 41, + "elapsed_ms": 86.119, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 42, + "elapsed_ms": 89.284, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 43, + "elapsed_ms": 84.316, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 44, + "elapsed_ms": 86.972, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 45, + "elapsed_ms": 88.795, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 46, + "elapsed_ms": 47.265, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 47, + "elapsed_ms": 32.736, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 48, + "elapsed_ms": 93.95, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 49, + "elapsed_ms": 29.861, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 50, + "elapsed_ms": 25.674, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 51, + "elapsed_ms": 87.319, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 52, + "elapsed_ms": 83.632, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 53, + "elapsed_ms": 83.964, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 54, + "elapsed_ms": 83.345, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 55, + "elapsed_ms": 175.728, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 56, + "elapsed_ms": 92.189, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 57, + "elapsed_ms": 98.676, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 58, + "elapsed_ms": 84.905, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 59, + "elapsed_ms": 81.966, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 60, + "elapsed_ms": 87.203, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 61, + "elapsed_ms": 25.923, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 62, + "elapsed_ms": 29.165, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 63, + "elapsed_ms": 82.076, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 64, + "elapsed_ms": 128.506, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 65, + "elapsed_ms": 91.837, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 66, + "elapsed_ms": 25.832, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 67, + "elapsed_ms": 86.189, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 68, + "elapsed_ms": 83.351, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 69, + "elapsed_ms": 85.479, + "files": 2, + "allocated_bytes": 1052672 + }, + { + "edit": 70, + "elapsed_ms": 77.587, + "files": 2, + "allocated_bytes": 1052672 + } + ] + }, + "paged": { + "binary_sha256": "e1c12a2f5e736bb86737ceff7849fe95b1a9d13136e8c5eb3f3398cb3971c6f5", + "median_edit_ms": 18.858, + "samples": [ + { + "edit": 1, + "elapsed_ms": 16.412, + "files": 3, + "allocated_bytes": 1069056 + }, + { + "edit": 2, + "elapsed_ms": 17.281, + "files": 3, + "allocated_bytes": 1085440 + }, + { + "edit": 3, + "elapsed_ms": 32.037, + "files": 3, + "allocated_bytes": 1101824 + }, + { + "edit": 4, + "elapsed_ms": 29.739, + "files": 3, + "allocated_bytes": 1118208 + }, + { + "edit": 5, + "elapsed_ms": 28.746, + "files": 3, + "allocated_bytes": 1134592 + }, + { + "edit": 6, + "elapsed_ms": 31.822, + "files": 3, + "allocated_bytes": 1150976 + }, + { + "edit": 7, + "elapsed_ms": 16.937, + "files": 3, + "allocated_bytes": 1167360 + }, + { + "edit": 8, + "elapsed_ms": 16.845, + "files": 3, + "allocated_bytes": 1183744 + }, + { + "edit": 9, + "elapsed_ms": 17.18, + "files": 3, + "allocated_bytes": 1200128 + }, + { + "edit": 10, + "elapsed_ms": 18.422, + "files": 3, + "allocated_bytes": 1216512 + }, + { + "edit": 11, + "elapsed_ms": 18.672, + "files": 3, + "allocated_bytes": 1232896 + }, + { + "edit": 12, + "elapsed_ms": 16.399, + "files": 3, + "allocated_bytes": 1249280 + }, + { + "edit": 13, + "elapsed_ms": 18.911, + "files": 3, + "allocated_bytes": 1265664 + }, + { + "edit": 14, + "elapsed_ms": 71.604, + "files": 3, + "allocated_bytes": 1282048 + }, + { + "edit": 15, + "elapsed_ms": 18.821, + "files": 3, + "allocated_bytes": 1298432 + }, + { + "edit": 16, + "elapsed_ms": 16.746, + "files": 3, + "allocated_bytes": 1314816 + }, + { + "edit": 17, + "elapsed_ms": 17.354, + "files": 3, + "allocated_bytes": 1331200 + }, + { + "edit": 18, + "elapsed_ms": 15.468, + "files": 3, + "allocated_bytes": 1347584 + }, + { + "edit": 19, + "elapsed_ms": 15.872, + "files": 3, + "allocated_bytes": 1363968 + }, + { + "edit": 20, + "elapsed_ms": 18.347, + "files": 3, + "allocated_bytes": 1380352 + }, + { + "edit": 21, + "elapsed_ms": 17.311, + "files": 3, + "allocated_bytes": 1396736 + }, + { + "edit": 22, + "elapsed_ms": 18.997, + "files": 3, + "allocated_bytes": 1413120 + }, + { + "edit": 23, + "elapsed_ms": 17.267, + "files": 3, + "allocated_bytes": 1429504 + }, + { + "edit": 24, + "elapsed_ms": 18.52, + "files": 3, + "allocated_bytes": 1445888 + }, + { + "edit": 25, + "elapsed_ms": 34.127, + "files": 3, + "allocated_bytes": 1462272 + }, + { + "edit": 26, + "elapsed_ms": 86.489, + "files": 3, + "allocated_bytes": 1478656 + }, + { + "edit": 27, + "elapsed_ms": 29.105, + "files": 3, + "allocated_bytes": 1495040 + }, + { + "edit": 28, + "elapsed_ms": 37.131, + "files": 3, + "allocated_bytes": 1511424 + }, + { + "edit": 29, + "elapsed_ms": 15.478, + "files": 3, + "allocated_bytes": 1527808 + }, + { + "edit": 30, + "elapsed_ms": 19.623, + "files": 3, + "allocated_bytes": 1544192 + }, + { + "edit": 31, + "elapsed_ms": 90.312, + "files": 3, + "allocated_bytes": 1560576 + }, + { + "edit": 32, + "elapsed_ms": 17.365, + "files": 3, + "allocated_bytes": 1576960 + }, + { + "edit": 33, + "elapsed_ms": 17.109, + "files": 3, + "allocated_bytes": 1593344 + }, + { + "edit": 34, + "elapsed_ms": 126.006, + "files": 3, + "allocated_bytes": 1609728 + }, + { + "edit": 35, + "elapsed_ms": 17.457, + "files": 3, + "allocated_bytes": 1626112 + }, + { + "edit": 36, + "elapsed_ms": 15.908, + "files": 3, + "allocated_bytes": 1642496 + }, + { + "edit": 37, + "elapsed_ms": 18.896, + "files": 3, + "allocated_bytes": 1658880 + }, + { + "edit": 38, + "elapsed_ms": 16.535, + "files": 3, + "allocated_bytes": 1675264 + }, + { + "edit": 39, + "elapsed_ms": 17.568, + "files": 3, + "allocated_bytes": 1691648 + }, + { + "edit": 40, + "elapsed_ms": 71.184, + "files": 3, + "allocated_bytes": 1708032 + }, + { + "edit": 41, + "elapsed_ms": 16.619, + "files": 3, + "allocated_bytes": 1724416 + }, + { + "edit": 42, + "elapsed_ms": 29.265, + "files": 3, + "allocated_bytes": 1740800 + }, + { + "edit": 43, + "elapsed_ms": 21.163, + "files": 3, + "allocated_bytes": 1757184 + }, + { + "edit": 44, + "elapsed_ms": 27.305, + "files": 3, + "allocated_bytes": 1773568 + }, + { + "edit": 45, + "elapsed_ms": 29.526, + "files": 3, + "allocated_bytes": 1789952 + }, + { + "edit": 46, + "elapsed_ms": 27.936, + "files": 3, + "allocated_bytes": 1806336 + }, + { + "edit": 47, + "elapsed_ms": 87.552, + "files": 3, + "allocated_bytes": 1822720 + }, + { + "edit": 48, + "elapsed_ms": 30.512, + "files": 3, + "allocated_bytes": 1839104 + }, + { + "edit": 49, + "elapsed_ms": 17.81, + "files": 3, + "allocated_bytes": 1855488 + }, + { + "edit": 50, + "elapsed_ms": 70.4, + "files": 3, + "allocated_bytes": 1871872 + }, + { + "edit": 51, + "elapsed_ms": 17.115, + "files": 3, + "allocated_bytes": 1888256 + }, + { + "edit": 52, + "elapsed_ms": 18.79, + "files": 3, + "allocated_bytes": 1904640 + }, + { + "edit": 53, + "elapsed_ms": 21.637, + "files": 3, + "allocated_bytes": 1921024 + }, + { + "edit": 54, + "elapsed_ms": 16.47, + "files": 3, + "allocated_bytes": 1937408 + }, + { + "edit": 55, + "elapsed_ms": 53.194, + "files": 3, + "allocated_bytes": 1953792 + }, + { + "edit": 56, + "elapsed_ms": 219.485, + "files": 3, + "allocated_bytes": 1970176 + }, + { + "edit": 57, + "elapsed_ms": 24.517, + "files": 3, + "allocated_bytes": 1986560 + }, + { + "edit": 58, + "elapsed_ms": 16.725, + "files": 3, + "allocated_bytes": 2002944 + }, + { + "edit": 59, + "elapsed_ms": 19.628, + "files": 3, + "allocated_bytes": 2019328 + }, + { + "edit": 60, + "elapsed_ms": 17.158, + "files": 3, + "allocated_bytes": 2035712 + }, + { + "edit": 61, + "elapsed_ms": 72.424, + "files": 3, + "allocated_bytes": 2052096 + }, + { + "edit": 62, + "elapsed_ms": 16.894, + "files": 3, + "allocated_bytes": 2068480 + }, + { + "edit": 63, + "elapsed_ms": 18.918, + "files": 3, + "allocated_bytes": 2084864 + }, + { + "edit": 64, + "elapsed_ms": 16.879, + "files": 3, + "allocated_bytes": 2101248 + }, + { + "edit": 65, + "elapsed_ms": 35.067, + "files": 3, + "allocated_bytes": 1052672 + }, + { + "edit": 66, + "elapsed_ms": 83.189, + "files": 3, + "allocated_bytes": 1069056 + }, + { + "edit": 67, + "elapsed_ms": 16.607, + "files": 3, + "allocated_bytes": 1085440 + }, + { + "edit": 68, + "elapsed_ms": 19.566, + "files": 3, + "allocated_bytes": 1101824 + }, + { + "edit": 69, + "elapsed_ms": 17.47, + "files": 3, + "allocated_bytes": 1118208 + }, + { + "edit": 70, + "elapsed_ms": 20.338, + "files": 3, + "allocated_bytes": 1134592 + } + ] + } + } +} diff --git a/research/experiments/005-storage-edit-latency/copy-memory.json b/research/experiments/005-storage-edit-latency/copy-memory.json new file mode 100644 index 0000000..969250c --- /dev/null +++ b/research/experiments/005-storage-edit-latency/copy-memory.json @@ -0,0 +1,43 @@ +{ + "passed": true, + "failures": [], + "profile": "portable-measurement-no-budget", + "variant": "source-program", + "scope": "Child-process peak RSS for native CLI document creation, read and one-byte revision edit; includes libc and the selected program form, excludes filesystem cache, kernel buffers, TLS, GUI and other apps. No cross-platform memory ceiling is asserted.", + "samples": { + "small_edit_rss_kib": 1056, + "one_mib_edit_rss_kib": 2080, + "one_mib_show_rss_kib": 1104, + "one_mib_splice_rss_kib": 1056 + }, + "raw_samples": { + "small_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1056, + "raw_max_rss": 1056, + "raw_unit": "KiB" + }, + "one_mib_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 2080, + "raw_max_rss": 2080, + "raw_unit": "KiB" + }, + "one_mib_show_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1104, + "raw_max_rss": 1104, + "raw_unit": "KiB" + }, + "one_mib_splice_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1056, + "raw_max_rss": 1056, + "raw_unit": "KiB" + } + }, + "budget_sha256": null, + "binary_sha256": "52c2b828b0cba3564a37e3874f60bec793d1dd7031aff77ba850cee7683977f9", + "binary_bytes": 178824, + "platform": "Linux-6.18.39+rpt-rpi-2712-aarch64-with-glibc2.41" +} diff --git a/research/experiments/005-storage-edit-latency/flat-memory.json b/research/experiments/005-storage-edit-latency/flat-memory.json new file mode 100644 index 0000000..3f45eb1 --- /dev/null +++ b/research/experiments/005-storage-edit-latency/flat-memory.json @@ -0,0 +1,43 @@ +{ + "passed": true, + "failures": [], + "profile": "portable-measurement-no-budget", + "variant": "source-program", + "scope": "Child-process peak RSS for native CLI document creation, read and one-byte revision edit; includes libc and the selected program form, excludes filesystem cache, kernel buffers, TLS, GUI and other apps. No cross-platform memory ceiling is asserted.", + "samples": { + "small_edit_rss_kib": 1056, + "one_mib_edit_rss_kib": 2080, + "one_mib_show_rss_kib": 1056, + "one_mib_splice_rss_kib": 1104 + }, + "raw_samples": { + "small_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1056, + "raw_max_rss": 1056, + "raw_unit": "KiB" + }, + "one_mib_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 2080, + "raw_max_rss": 2080, + "raw_unit": "KiB" + }, + "one_mib_show_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1056, + "raw_max_rss": 1056, + "raw_unit": "KiB" + }, + "one_mib_splice_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1104, + "raw_max_rss": 1104, + "raw_unit": "KiB" + } + }, + "budget_sha256": null, + "binary_sha256": "23ebc0ce1df9c49216511bee658fd5b9e373509e296bd2c2f8e76e6d3081cded", + "binary_bytes": 178336, + "platform": "Linux-6.18.39+rpt-rpi-2712-aarch64-with-glibc2.41" +} diff --git a/research/experiments/005-storage-edit-latency/measure.py b/research/experiments/005-storage-edit-latency/measure.py new file mode 100644 index 0000000..b390c92 --- /dev/null +++ b/research/experiments/005-storage-edit-latency/measure.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +"""Time the same durable one-MiB document creation and one-byte revision edit.""" +import argparse +import hashlib +import json +from pathlib import Path +import platform +import statistics +import subprocess +import tempfile +import time + +HERE = Path(__file__).resolve().parents[3] +PROGRAM = HERE / 'prototypes/connections/examples/editor.pure' +INITIAL = b'A' * 1_048_576 +EXPECTED = INITIAL[:-1] + b'Z' + + +def invoke(command): + started = time.monotonic_ns() + result = subprocess.run([str(arg) for arg in command], capture_output=True, timeout=30) + elapsed_ms = (time.monotonic_ns() - started) / 1_000_000 + if result.returncode: + raise AssertionError((command, result.returncode, result.stderr[-1000:])) + return result, elapsed_ms + + +def one(binary, root, initial, replacement): + base = [binary, '--program', PROGRAM, '--store', root] + created, create_ms = invoke([*base, 'edit', 'document', 0, 0, 0, initial]) + assert json.loads(created.stdout)['revision'] == '1' + edited, edit_ms = invoke([*base, 'edit', 'document', 1, 1_048_575, 1, replacement]) + assert json.loads(edited.stdout)['revision'] == '2' + shown, _ = invoke([*base, 'show', 'document']) + assert shown.stdout == EXPECTED + assert json.loads(shown.stderr)['revision'] == '2' + files = [path for path in root.iterdir() if path.is_file()] + return {'create_ms': round(create_ms, 3), 'edit_ms': round(edit_ms, 3), + 'store_files': len(files), + 'store_file_bytes': sum(path.stat().st_size for path in files), + 'store_allocated_bytes': sum(path.stat().st_blocks * 512 for path in files)} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--flat', type=Path, required=True) + parser.add_argument('--copy', type=Path, required=True) + parser.add_argument('--paged', type=Path, required=True) + parser.add_argument('--scratch-parent', type=Path, required=True) + parser.add_argument('--trials', type=int, default=18) + parser.add_argument('--output', type=Path, required=True) + args = parser.parse_args() + if args.trials < 3 or args.trials % 3 or args.output.exists(): + parser.error('trials must be a positive multiple of three and output must be new') + variants = {'flat': args.flat.resolve(), 'copy': args.copy.resolve(), + 'paged': args.paged.resolve()} + for binary in variants.values(): + if not binary.is_file(): + parser.error(f'missing binary: {binary}') + args.scratch_parent.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory(prefix='pure-storage-timing-', + dir=args.scratch_parent.resolve()) as name: + root = Path(name) + (root / 'initial').write_bytes(INITIAL) + (root / 'replacement').write_bytes(b'Z') + filesystem = subprocess.run(['findmnt', '-T', str(root), '-no', 'FSTYPE,SOURCE'], + capture_output=True, text=True, check=True).stdout.strip() + samples = {name: [] for name in variants} + names = list(variants) + for trial in range(args.trials): + for name in names[trial % 3:] + names[:trial % 3]: + sample = one(variants[name], root / f'{name}-{trial}', + root / 'initial', root / 'replacement') + samples[name].append({'trial': trial, **sample}) + result = {'profile': 'native-cli-durable-one-mib-document-last-byte-edit', + 'platform': platform.platform(), 'filesystem': filesystem, + 'trials_per_variant': args.trials, + 'final_body_sha256': hashlib.sha256(EXPECTED).hexdigest(), + 'scope': ('Each sample starts a new CLI process; create and edit each ' + 'include program parsing, store initialization, file and ' + 'directory synchronization. Show verifies the final revision ' + 'but is outside the timed operations. The host page cache, ' + 'filesystem and device remain uncontrolled.'), + 'variants': {name: {'binary_sha256': hashlib.sha256(binary.read_bytes()).hexdigest(), + 'median_create_ms': round(statistics.median( + row['create_ms'] for row in samples[name]), 3), + 'median_edit_ms': round(statistics.median( + row['edit_ms'] for row in samples[name]), 3), + 'samples': samples[name]} + for name, binary in variants.items()}} + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(result, indent=2) + '\n') + print(json.dumps({name: {key: value for key, value in entry.items() + if key.startswith('median_')} + for name, entry in result['variants'].items()}, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/research/experiments/005-storage-edit-latency/paged-memory.json b/research/experiments/005-storage-edit-latency/paged-memory.json new file mode 100644 index 0000000..a9bef53 --- /dev/null +++ b/research/experiments/005-storage-edit-latency/paged-memory.json @@ -0,0 +1,43 @@ +{ + "passed": true, + "failures": [], + "profile": "portable-measurement-no-budget", + "variant": "source-program", + "scope": "Child-process peak RSS for native CLI document creation, read and one-byte revision edit; includes libc and the selected program form, excludes filesystem cache, kernel buffers, TLS, GUI and other apps. No cross-platform memory ceiling is asserted.", + "samples": { + "small_edit_rss_kib": 1088, + "one_mib_edit_rss_kib": 2112, + "one_mib_show_rss_kib": 1088, + "one_mib_splice_rss_kib": 1056 + }, + "raw_samples": { + "small_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1088, + "raw_max_rss": 1088, + "raw_unit": "KiB" + }, + "one_mib_edit_rss_kib": { + "exit_code": 0, + "max_rss_kib": 2112, + "raw_max_rss": 2112, + "raw_unit": "KiB" + }, + "one_mib_show_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1088, + "raw_max_rss": 1088, + "raw_unit": "KiB" + }, + "one_mib_splice_rss_kib": { + "exit_code": 0, + "max_rss_kib": 1056, + "raw_max_rss": 1056, + "raw_unit": "KiB" + } + }, + "budget_sha256": null, + "binary_sha256": "e1c12a2f5e736bb86737ceff7849fe95b1a9d13136e8c5eb3f3398cb3971c6f5", + "binary_bytes": 200704, + "platform": "Linux-6.18.39+rpt-rpi-2712-aarch64-with-glibc2.41" +} diff --git a/research/experiments/005-storage-edit-latency/sequence.py b/research/experiments/005-storage-edit-latency/sequence.py new file mode 100644 index 0000000..57ff835 --- /dev/null +++ b/research/experiments/005-storage-edit-latency/sequence.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""Measure repeated durable edits and page-segment rebuilds on one real document.""" +import argparse +import hashlib +import json +from pathlib import Path +import platform +import statistics +import subprocess +import tempfile + +from measure import INITIAL, PROGRAM, invoke + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--flat', type=Path, required=True) + parser.add_argument('--paged', type=Path, required=True) + parser.add_argument('--scratch-parent', type=Path, required=True) + parser.add_argument('--edits', type=int, default=70) + parser.add_argument('--output', type=Path, required=True) + args = parser.parse_args() + if args.edits < 66 or args.output.exists(): + parser.error('at least 66 edits are needed to observe the current rebuild boundary; output must be new') + binaries = {'flat': args.flat.resolve(), 'paged': args.paged.resolve()} + args.scratch_parent.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory(prefix='pure-storage-sequence-', + dir=args.scratch_parent.resolve()) as name: + root = Path(name) + filesystem = subprocess.run(['findmnt', '-T', str(root), '-no', 'FSTYPE,SOURCE'], + capture_output=True, text=True, check=True).stdout.strip() + (root / 'initial').write_bytes(INITIAL) + patches = {'Y': root / 'Y', 'Z': root / 'Z'} + for label, file in patches.items(): + file.write_bytes(label.encode()) + bases = {variant: [binary, '--program', PROGRAM, '--store', root / variant] + for variant, binary in binaries.items()} + for base in bases.values(): + result, _ = invoke([*base, 'edit', 'document', 0, 0, 0, root / 'initial']) + assert json.loads(result.stdout)['revision'] == '1' + samples = {variant: [] for variant in binaries} + for edit in range(1, args.edits + 1): + patch = 'Z' if edit % 2 else 'Y' + order = ('flat', 'paged') if edit % 2 else ('paged', 'flat') + for variant in order: + base = bases[variant] + result, elapsed = invoke([*base, 'edit', 'document', edit, + len(INITIAL) - 1, 1, patches[patch]]) + assert json.loads(result.stdout)['revision'] == str(edit + 1) + files = [file for file in (root / variant).iterdir() if file.is_file()] + samples[variant].append({'edit': edit, 'elapsed_ms': round(elapsed, 3), + 'files': len(files), + 'allocated_bytes': sum(file.stat().st_blocks * 512 + for file in files)}) + expected = INITIAL[:-1] + patches[patch].read_bytes() + for base in bases.values(): + shown, _ = invoke([*base, 'show', 'document']) + assert shown.stdout == expected + assert json.loads(shown.stderr)['revision'] == str(args.edits + 1) + result = {'profile': 'repeated-durable-one-mib-document-last-byte-edit', + 'platform': platform.platform(), 'filesystem': filesystem, + 'edits_per_variant': args.edits, + 'final_body_sha256': hashlib.sha256(expected).hexdigest(), + 'scope': ('Same actual source-loaded CLI and editor.pure, two persistent ' + 'stores, alternating operation order. Timings include each ' + 'edit process, parser, store init and fsync; creation and ' + 'final show are not timed. Device state is uncontrolled.'), + 'variants': {variant: { + 'binary_sha256': hashlib.sha256(binary.read_bytes()).hexdigest(), + 'median_edit_ms': round(statistics.median(row['elapsed_ms'] + for row in samples[variant]), 3), + 'samples': samples[variant]} + for variant, binary in binaries.items()}} + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(result, indent=2) + '\n') + print(json.dumps({variant: {'median_edit_ms': row['median_edit_ms'], + 'max_edit_ms': max(sample['elapsed_ms'] + for sample in row['samples']), + 'max_allocated_bytes': max(sample['allocated_bytes'] + for sample in row['samples'])} + for variant, row in result['variants'].items()}, indent=2)) + + +if __name__ == '__main__': + main() -- cgit v1.2.3