diff options
| author | eunhhu <[email protected]> | 2026-09-30 13:52:30 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-30 13:52:30 +0100 |
| commit | 68dca986ee7ff7d729a15565e2e07127d5b5d1a4 (patch) | |
| tree | 89e50c693af9594c26320c56e37ee7f0f9b95d6a /research/experiments/024-finding-items | |
| parent | dacc3cf3e1e7fe6554575cefdb4ac6d7a19a61c6 (diff) | |
| download | pure-68dca986ee7ff7d729a15565e2e07127d5b5d1a4.tar.gz pure-68dca986ee7ff7d729a15565e2e07127d5b5d1a4.zip | |
Say that prefetching items did not pay, and why (109)
Fetching a found item's cells, a leaf's keys and each level's keys ahead
made finding and reading items 20% faster on 100,000 items in a micro
benchmark, but TPC-C's clean pairs moved 1% at most and finding alone got
48% slower, so it is not in. The owner's finding samples were the descent,
not the fields: a write right after a read copies the leaf whole anyway,
and what costs is walking structures larger than the caches at random.
Diffstat (limited to 'research/experiments/024-finding-items')
17 files changed, 201 insertions, 0 deletions
diff --git a/research/experiments/024-finding-items/2026-09-30-micro-linux-aarch64.txt b/research/experiments/024-finding-items/2026-09-30-micro-linux-aarch64.txt new file mode 100644 index 0000000..df7d999 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-micro-linux-aarch64.txt @@ -0,0 +1,6 @@ +load average at the start: (3.32470703125, 3.7529296875, 3.55712890625) + 100000 before seek: 125.4 ns (x1.69) seek+3 reads: 339.3 ns (x1.36) seek+3 reads+3 changes: 433.7 ns (x1.33) same, a share each 30: 681.5 ns (x1.15) + 100000 after seek: 185.9 ns (x1.10) seek+3 reads: 270.8 ns (x1.08) seek+3 reads+3 changes: 360.1 ns (x1.07) same, a share each 30: 597.2 ns (x1.12) + 400000 before seek: 212.6 ns (x1.10) seek+3 reads: 384.7 ns (x1.02) seek+3 reads+3 changes: 505.4 ns (x1.12) same, a share each 30: 855.1 ns (x1.22) + 400000 after seek: 261.8 ns (x1.55) seek+3 reads: 348.8 ns (x1.63) seek+3 reads+3 changes: 470.6 ns (x1.18) same, a share each 30: 801.6 ns (x1.51) +load average at the end: (3.677734375, 3.7158203125, 3.5546875) diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-1-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-1-linux-aarch64.jsonl new file mode 100644 index 0000000..4e48295 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-1-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.92, "sqlite_load_s": 1.61, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 35582, "new_orders_per_minute": 951532, "undone_new_orders": 3034, "errors": 0, "new_order": {"done": 320214, "failed": 0, "p50_us": 1536, "p99_us": 6656}, "payment": {"done": 306093, "failed": 0, "p50_us": 1536, "p99_us": 6656}, "order_status": {"done": 28549, "failed": 0, "p50_us": 304, "p99_us": 3456}, "delivery": {"done": 28527, "failed": 0, "p50_us": 1536, "p99_us": 6656}, "stock_level": {"done": 28264, "failed": 0, "p50_us": 336, "p99_us": 3712}, "server_threads": "3", "cpu_us_per_transaction": 46.4, "core_shares": {"pure-owner": 0.77, "pure-checkpoint": 0.01}, "resident_mib": 385.0, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 385.0, "pure_state_mib": 193.6, "pure_store_mib": 198.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23174, "burst_events": 651885, "checkpoints": 32}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-2-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-2-linux-aarch64.jsonl new file mode 100644 index 0000000..0a3ba79 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-2-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.9, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 32144, "new_orders_per_minute": 858833, "undone_new_orders": 2719, "errors": 0, "new_order": {"done": 288997, "failed": 0, "p50_us": 1728, "p99_us": 6912}, "payment": {"done": 276707, "failed": 0, "p50_us": 1664, "p99_us": 6656}, "order_status": {"done": 25877, "failed": 0, "p50_us": 336, "p99_us": 3712}, "delivery": {"done": 25795, "failed": 0, "p50_us": 1728, "p99_us": 6656}, "stock_level": {"done": 25502, "failed": 0, "p50_us": 384, "p99_us": 3840}, "server_threads": "3", "cpu_us_per_transaction": 48.7, "core_shares": {"pure-owner": 0.74, "pure-checkpoint": 0.01}, "resident_mib": 353.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 353.6, "pure_state_mib": 176.9, "pure_store_mib": 182.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 21004, "burst_events": 588864, "checkpoints": 28}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-3-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-3-linux-aarch64.jsonl new file mode 100644 index 0000000..af6b785 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-3-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 44626, "new_orders_per_minute": 1193844, "undone_new_orders": 3830, "errors": 0, "new_order": {"done": 401787, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "payment": {"done": 383595, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "order_status": {"done": 35812, "failed": 0, "p50_us": 256, "p99_us": 1344}, "delivery": {"done": 35769, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "stock_level": {"done": 35586, "failed": 0, "p50_us": 288, "p99_us": 1408}, "server_threads": "3", "cpu_us_per_transaction": 42.6, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 467.3, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 467.3, "pure_state_mib": 237.2, "pure_store_mib": 246.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27798, "burst_events": 817405, "checkpoints": 40}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-4-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-4-linux-aarch64.jsonl new file mode 100644 index 0000000..1f4fb9d --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-4-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.57, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 44555, "new_orders_per_minute": 1191922, "undone_new_orders": 3830, "errors": 0, "new_order": {"done": 401140, "failed": 0, "p50_us": 1408, "p99_us": 3328}, "payment": {"done": 382996, "failed": 0, "p50_us": 1408, "p99_us": 3328}, "order_status": {"done": 35736, "failed": 0, "p50_us": 256, "p99_us": 1344}, "delivery": {"done": 35691, "failed": 0, "p50_us": 1408, "p99_us": 3328}, "stock_level": {"done": 35534, "failed": 0, "p50_us": 288, "p99_us": 1408}, "server_threads": "3", "cpu_us_per_transaction": 42.7, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 466.9, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 466.9, "pure_state_mib": 236.8, "pure_store_mib": 246.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27532, "burst_events": 816081, "checkpoints": 40}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-5-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-5-linux-aarch64.jsonl new file mode 100644 index 0000000..c089c78 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-5-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.62, "pure_load_s": 0.9, "sqlite_load_s": 1.68, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 32643, "new_orders_per_minute": 872505, "undone_new_orders": 2776, "errors": 0, "new_order": {"done": 293612, "failed": 0, "p50_us": 1728, "p99_us": 6656}, "payment": {"done": 280962, "failed": 0, "p50_us": 1664, "p99_us": 6656}, "order_status": {"done": 26241, "failed": 0, "p50_us": 336, "p99_us": 3712}, "delivery": {"done": 26139, "failed": 0, "p50_us": 1664, "p99_us": 6400}, "stock_level": {"done": 25905, "failed": 0, "p50_us": 368, "p99_us": 3712}, "server_threads": "3", "cpu_us_per_transaction": 48.7, "core_shares": {"pure-owner": 0.75, "pure-checkpoint": 0.01}, "resident_mib": 357.1, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 357.1, "pure_state_mib": 179.4, "pure_store_mib": 182.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 21420, "burst_events": 598014, "checkpoints": 28}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-after-6-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-after-6-linux-aarch64.jsonl new file mode 100644 index 0000000..eabbf86 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-after-6-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.77, "sqlite_load_s": 1.6, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43579, "new_orders_per_minute": 1166097, "undone_new_orders": 3735, "errors": 0, "new_order": {"done": 392436, "failed": 0, "p50_us": 1408, "p99_us": 3968}, "payment": {"done": 374594, "failed": 0, "p50_us": 1408, "p99_us": 3840}, "order_status": {"done": 34948, "failed": 0, "p50_us": 256, "p99_us": 1600}, "delivery": {"done": 34891, "failed": 0, "p50_us": 1408, "p99_us": 3840}, "stock_level": {"done": 34722, "failed": 0, "p50_us": 288, "p99_us": 1792}, "server_threads": "3", "cpu_us_per_transaction": 43.0, "core_shares": {"pure-owner": 0.88, "pure-checkpoint": 0.01}, "resident_mib": 457.4, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 457.4, "pure_state_mib": 232.2, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27631, "burst_events": 798265, "checkpoints": 39}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-1-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-1-linux-aarch64.jsonl new file mode 100644 index 0000000..4370220 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-1-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.55, "pure_load_s": 0.71, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43185, "new_orders_per_minute": 1155354, "undone_new_orders": 3699, "errors": 0, "new_order": {"done": 388817, "failed": 0, "p50_us": 1472, "p99_us": 3840}, "payment": {"done": 371224, "failed": 0, "p50_us": 1408, "p99_us": 3840}, "order_status": {"done": 34650, "failed": 0, "p50_us": 256, "p99_us": 1472}, "delivery": {"done": 34606, "failed": 0, "p50_us": 1408, "p99_us": 3712}, "stock_level": {"done": 34399, "failed": 0, "p50_us": 288, "p99_us": 1600}, "server_threads": "3", "cpu_us_per_transaction": 43.9, "core_shares": {"pure-owner": 0.88, "pure-checkpoint": 0.01}, "resident_mib": 453.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 453.8, "pure_state_mib": 230.3, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26754, "burst_events": 791032, "checkpoints": 38}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-2-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-2-linux-aarch64.jsonl new file mode 100644 index 0000000..4bb2a72 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-2-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 44248, "new_orders_per_minute": 1183944, "undone_new_orders": 3800, "errors": 0, "new_order": {"done": 398450, "failed": 0, "p50_us": 1408, "p99_us": 3840}, "payment": {"done": 380308, "failed": 0, "p50_us": 1408, "p99_us": 3840}, "order_status": {"done": 35467, "failed": 0, "p50_us": 256, "p99_us": 1472}, "delivery": {"done": 35460, "failed": 0, "p50_us": 1408, "p99_us": 3712}, "stock_level": {"done": 35283, "failed": 0, "p50_us": 288, "p99_us": 1536}, "server_threads": "3", "cpu_us_per_transaction": 42.9, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 463.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 463.8, "pure_state_mib": 235.4, "pure_store_mib": 246.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27621, "burst_events": 810503, "checkpoints": 40}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-3-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-3-linux-aarch64.jsonl new file mode 100644 index 0000000..4116a98 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-3-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.57, "sqlite_page_size": 4096, "pure_resident_mib": 38.9, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43719, "new_orders_per_minute": 1169901, "undone_new_orders": 3742, "errors": 0, "new_order": {"done": 393711, "failed": 0, "p50_us": 1472, "p99_us": 3712}, "payment": {"done": 375772, "failed": 0, "p50_us": 1408, "p99_us": 3712}, "order_status": {"done": 35030, "failed": 0, "p50_us": 256, "p99_us": 1728}, "delivery": {"done": 35025, "failed": 0, "p50_us": 1408, "p99_us": 3712}, "stock_level": {"done": 34852, "failed": 0, "p50_us": 288, "p99_us": 1792}, "server_threads": "3", "cpu_us_per_transaction": 43.1, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 459.1, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 459.1, "pure_state_mib": 232.9, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27236, "burst_events": 800851, "checkpoints": 39}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-4-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-4-linux-aarch64.jsonl new file mode 100644 index 0000000..15fa180 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-4-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.61, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43895, "new_orders_per_minute": 1174382, "undone_new_orders": 3764, "errors": 0, "new_order": {"done": 395225, "failed": 0, "p50_us": 1472, "p99_us": 3712}, "payment": {"done": 377341, "failed": 0, "p50_us": 1408, "p99_us": 3712}, "order_status": {"done": 35184, "failed": 0, "p50_us": 256, "p99_us": 1344}, "delivery": {"done": 35150, "failed": 0, "p50_us": 1408, "p99_us": 3584}, "stock_level": {"done": 34992, "failed": 0, "p50_us": 288, "p99_us": 1472}, "server_threads": "3", "cpu_us_per_transaction": 42.9, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 460.2, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 460.2, "pure_state_mib": 233.7, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27142, "burst_events": 804037, "checkpoints": 39}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-5-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-5-linux-aarch64.jsonl new file mode 100644 index 0000000..6c90e25 --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-5-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.7, "sqlite_load_s": 1.64, "sqlite_page_size": 4096, "pure_resident_mib": 38.9, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 37963, "new_orders_per_minute": 1015262, "undone_new_orders": 3254, "errors": 0, "new_order": {"done": 341679, "failed": 0, "p50_us": 1536, "p99_us": 4608}, "payment": {"done": 326457, "failed": 0, "p50_us": 1536, "p99_us": 4608}, "order_status": {"done": 30460, "failed": 0, "p50_us": 288, "p99_us": 2304}, "delivery": {"done": 30463, "failed": 0, "p50_us": 1536, "p99_us": 4864}, "stock_level": {"done": 30208, "failed": 0, "p50_us": 320, "p99_us": 2304}, "server_threads": "3", "cpu_us_per_transaction": 45.7, "core_shares": {"pure-owner": 0.82, "pure-checkpoint": 0.01}, "resident_mib": 407.7, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 407.7, "pure_state_mib": 205.0, "pure_store_mib": 214.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 24124, "burst_events": 695431, "checkpoints": 33}} diff --git a/research/experiments/024-finding-items/2026-09-30-tpcc-before-6-linux-aarch64.jsonl b/research/experiments/024-finding-items/2026-09-30-tpcc-before-6-linux-aarch64.jsonl new file mode 100644 index 0000000..0a1fa6c --- /dev/null +++ b/research/experiments/024-finding-items/2026-09-30-tpcc-before-6-linux-aarch64.jsonl @@ -0,0 +1,3 @@ +{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.76, "sqlite_load_s": 1.6, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8} +{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43848, "new_orders_per_minute": 1173206, "undone_new_orders": 3760, "errors": 0, "new_order": {"done": 394829, "failed": 0, "p50_us": 1472, "p99_us": 3584}, "payment": {"done": 376952, "failed": 0, "p50_us": 1408, "p99_us": 3584}, "order_status": {"done": 35157, "failed": 0, "p50_us": 248, "p99_us": 1344}, "delivery": {"done": 35082, "failed": 0, "p50_us": 1408, "p99_us": 3584}, "stock_level": {"done": 34950, "failed": 0, "p50_us": 272, "p99_us": 1472}, "server_threads": "3", "cpu_us_per_transaction": 42.7, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 459.5, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []} +{"step": "end", "pure_resident_mib": 459.5, "pure_state_mib": 233.5, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26881, "burst_events": 803187, "checkpoints": 39}} diff --git a/research/experiments/024-finding-items/bench-seek.c b/research/experiments/024-finding-items/bench-seek.c new file mode 100644 index 0000000..6be7245 --- /dev/null +++ b/research/experiments/024-finding-items/bench-seek.c @@ -0,0 +1,80 @@ +/* Finding items in a keyed list the way TPC-C's stock is found (docs/research/109): + * bench-seek ITEMS OPERATIONS + * A list of ITEMS items, five number fields, keyed by the first (keys 1..ITEMS); + * then OPERATIONS random keys, four ways: a seek alone; a seek and three + * fields read; and three fields read and each changed (journaled); the same + * with a share every 30 changes, as a snapshot a save takes. Prints ns each, + * and the machine's latency to memory (a random pointer chase over 64 MiB). */ +#include "module-list.h" +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +static uint64_t now_ns(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (uint64_t)t.tv_sec * 1000000000u + (uint64_t)t.tv_nsec; +} + +static uint64_t state = 0x9e3779b97f4a7c15u; +static uint64_t next(void) { + state ^= state << 13, state ^= state >> 7, state ^= state << 17; + return state; +} + +int main(int argc, char **argv) { + size_t items = argc > 1 ? strtoull(argv[1], NULL, 10) : 100000, operations = argc > 2 ? strtoull(argv[2], NULL, 10) : 2000000; + static const uint8_t numbers[5] = {0}; + PureList *list = pure_list_new(5, numbers); + if (!list || pure_list_keyed(list, 0) != PURE_OK) return 1; + for (size_t i = 0; i < items; ++i) { + PureCell cells[5] = {{.num = (double)(i + 1)}, {.num = 50}, {.num = 0}, {.num = 0}, {.num = 0}}; + if (pure_list_insert(list, i, cells, NULL) != PURE_OK) return 1; + } + pure_list_journal(list, true); + double sink = 0; + const char *names[4] = {"seek", "seek+3 reads", "seek+3 reads+3 changes", "same, a share each 30"}; + for (int way = 0; way < 4; ++way) { + PureRetired retired = {0}; + PureList *copy = NULL; + uint64_t epoch = 0; + uint64_t began = now_ns(); + for (size_t op = 0; op < operations; ++op) { + bool found; + size_t at = pure_list_seek(list, 0, (PureCell){.num = (double)(next() % items + 1)}, &found); + if (way == 0) { sink += (double)at; continue; } + for (unsigned f = 1; f <= 3; ++f) { + double value = pure_list_get(list, at, f).num; + sink += value; + if (way >= 2) pure_list_set(list, at, f, (PureCell){.num = value + 1}, NULL); + } + if (way >= 2 && op % 64 == 63) pure_list_forget(list, 0); + if (way == 3 && op % 30 == 29) { + if (copy) { + pure_list_free(copy); + pure_retired_reuse(&retired, &list, 1); + } + copy = pure_list_share(list, &retired, ++epoch); + } + } + uint64_t took = now_ns() - began; + if (copy) pure_list_free(copy); + pure_retired_free(&retired); + printf("%-26s %7.1f ns\n", names[way], (double)took / (double)operations); + } + /* The latency to memory: a random cycle through 64 MiB of pointers. */ + size_t slots = (64u << 20) / sizeof(size_t); + size_t *chain = malloc(slots * sizeof(*chain)), *order = malloc(slots * sizeof(*order)); + for (size_t i = 0; i < slots; ++i) order[i] = i; + for (size_t i = slots - 1; i > 0; --i) { size_t j = next() % (i + 1), t = order[i]; order[i] = order[j]; order[j] = t; } + for (size_t i = 0; i < slots; ++i) chain[order[i]] = order[(i + 1) % slots]; + size_t at = order[0]; + uint64_t began = now_ns(); + for (size_t i = 0; i < 4000000; ++i) at = chain[at]; + printf("%-26s %7.1f ns\n", "memory latency", (double)(now_ns() - began) / 4000000.0); + sink += (double)at; + fprintf(stderr, "%g\n", sink); + pure_list_free(list); + return 0; +} diff --git a/research/experiments/024-finding-items/micro.py b/research/experiments/024-finding-items/micro.py new file mode 100644 index 0000000..1e80a9e --- /dev/null +++ b/research/experiments/024-finding-items/micro.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +"""bench-seek before and after prefetch.patch, taking turns five times, lists of 100,000 and 400,000 items: +the median ns of each way and the spread (slowest over fastest), and the load average when it began and ended. + + micro.py DIRECTORY (holding bench-before and bench-after)""" +import os +import statistics +import subprocess +import sys +from pathlib import Path + +here = Path(sys.argv[1]) +ways = ['seek', 'seek+3 reads', 'seek+3 reads+3 changes', 'same, a share each 30'] +print('load average at the start:', os.getloadavg()) +for items in (100000, 400000): + runs = {'before': [], 'after': []} + for _ in range(5): + for version in runs: + out = subprocess.run([here / f'bench-{version}', str(items), '1500000'], capture_output=True, text=True, + check=True).stdout.splitlines()[:4] + runs[version].append([float(line.split()[-2]) for line in out]) + for version, measured in runs.items(): + medians = [statistics.median(m[i] for m in measured) for i in range(4)] + spreads = [max(m[i] for m in measured) / min(m[i] for m in measured) for i in range(4)] + print(f'{items:>7} {version:<6} ' + ' '.join(f'{w}: {m:.1f} ns (x{s:.2f})' for w, m, s in zip(ways, medians, spreads))) +print('load average at the end:', os.getloadavg()) diff --git a/research/experiments/024-finding-items/prefetch.patch b/research/experiments/024-finding-items/prefetch.patch new file mode 100644 index 0000000..e642352 --- /dev/null +++ b/research/experiments/024-finding-items/prefetch.patch @@ -0,0 +1,21 @@ +--- a/core/module-list.c ++++ b/core/module-list.c +@@ -1122,12 +1122,17 @@ + unsigned taken = upper(g->keys + 1, FANOUT - 1, key.num); + start += g->before[taken]; + node = child(node, taken); ++ if (!node->leaf) ++ for (unsigned i = 0; i < FANOUT; i += 8) __builtin_prefetch(guide(node)->keys + i); + } + const double *keys = numbers(l, node, field); +- if (list->count > PREFETCHED) /* leaves past the caches: the leaf's keys fetched at once, not probe by probe */ ++ if (true) /* the leaf's keys fetched at once, not probe by probe */ + for (unsigned i = 0; i < node->count; i += 8) __builtin_prefetch(keys + i); + unsigned low = lower(keys, node->count, key.num); + *found = low < node->count && keys[low] == key.num; ++ if (*found) /* the item is read next, a field at a time: its cells, a line each, fetched together */ ++ for (unsigned f = 0; f < l->fields; ++f) ++ __builtin_prefetch(l->text_fields[f] ? (const void *)&texts(l, node, f)[low] : (const void *)&numbers(l, node, f)[low]); + return start + low; + } + while (!node->leaf) { diff --git a/research/experiments/024-finding-items/runs.sh b/research/experiments/024-finding-items/runs.sh new file mode 100644 index 0000000..ddb740a --- /dev/null +++ b/research/experiments/024-finding-items/runs.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# The runs of docs/research/109, from the repository's root: the list +# micro-benchmark before and after prefetch.patch, then TPC-C's pure-serve +# before and after in turns (the tree is patched to build it, then put back). +set -e +out=research/experiments/024-finding-items +work=$(mktemp -d) +rest="core/module.c core/module-save.c core/module-text.c core/module-store.c core/flow.c store/store-tree.c store/store-log.c" +cp core/module-list.c $work/module-list-before.c +cp core/module-list.c $work/module-list-after.c +patch -s $work/module-list-after.c $out/prefetch.patch +for version in before after; do + cc -O2 -g -std=c17 -D_GNU_SOURCE -Icore -Istore $out/bench-seek.c $work/module-list-$version.c $rest -pthread -lm \ + -o $work/bench-$version +done +python3 $out/micro.py $work > $out/2026-09-30-micro-linux-aarch64.txt + +make -s build/pure-serve +cp build/pure-serve $work/pure-serve-before +cp $work/module-list-after.c core/module-list.c +make -s build/pure-serve +cp build/pure-serve $work/pure-serve-after +cp $work/module-list-before.c core/module-list.c +make -s build/pure-serve +for round in 1 2 3 4 5 6; do + first=before second=after + if [ $((round % 2)) = 0 ]; then first=after second=before; fi + for version in $first $second; do + python3 benchmarks/tpcc/run.py --serve $work/pure-serve-$version --warehouses 1 --check 0 --terminals 64 \ + --sqlite-threads '' --sqlite-group '' --seconds 20 > $out/2026-09-30-tpcc-$version-$round-linux-aarch64.jsonl + done +done |
