aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research
Commit message (Collapse)AuthorAgeFilesLines
* Research 140: stage 1's instruction counts: the workloads' modules byte for ↵eunhhu8 days1-1/+15
| | | | byte the same, the executor alone moved matmul +0.43% and BFS -0.34% (knapsack, roots, join within 0.03%; the bar of 0.1% missed, mixed signs: four cases more in step), the bank's queries -0.22% to 0.00% (bar 1%); the four cases out of line in a noinline function (b23) cost 6-15% of the executor's instructions (a call taking frame from step: the register cliff) and were taken back; CHECKPOINT's direction row through 027's stage 1
* Research 140, 027's stage 1 measured: SHA-256 written in aup (its ↵eunhhu8 days1-0/+60
| | | | examples/sha256.aup) right for FIPS 180-2's examples and 138 more messages on every path, in make check against hashlib; 52 lines against Python's 28 (the bar missed: no formatting, no bytes joined or sliced, no lists as values, moved into stage 2), 176 times C's time and 0.43 of plain Python's (1,591 ns a byte; a block's 19,129 instructions, 39% of them the inlined fn's literals not folded); 044's check, time.c against the same algorithm in C (digests compared first) and the Python reference
* Research 140: a suite of eleven specs from different fields (DNS, SHA-256, ↵eunhhu8 days1-0/+130
| | | | inflate, JSON, UTF-8 and line breaking, relational queries and graphs, text editing, box layout, HTTP/1.1 by packets, retries and timeouts, constant-time crypto) with five criteria (written in aup and Pure alone, no workaround, lines against a Python reference, time against C, the spec's own vectors passing in Pure's checks on three machines); ten probes (044) show today's aup stops at a byte by position, bit operations, nesting, recursion, variants and reading a character; the core's minimal candidates and the rule against piling up (only what two specs need); SHA-256 and JSON first
* Batch executor: the round's fewest-left marks at the end of Batch: put after ↵eunhhu9 days1-0/+16
| | | | spare_count they moved its large arrays and knapsack ran 7% slower at the same instructions (8.79 against 8.29 ms), at its end about 2% (8.45); research 139's afterword: 026 not taken heavily (the user's word), the one light cut made (a nested count loop's rounds sweeping only when few lanes are left: matmul 25.85 to 24.3 ms), the walk loops kept sweeping each round (held, BFS's batches ran out), and the stop; 041 runs of b21
* Research 139: what a program made at load per batch loop would take (the ↵eunhhu11 days1-2/+49
| | | | deciding prototype 043): the executor's extra over 041 is interpretation, not semantics (matmul 11.1 ms of it, checks 0.2); the program interpreted a step at a time, with the executor's checks, ran matmul's loop in 10.36 ms and knapsack's in 4.16 (straight kernels 7.17 and 3.76; the executor about 22.2 and 7.3), about 14 and 5.4 ms with the making (bars 15 and 6.5; the compiled code 14.2 and 7.9); the buffer rule it found (registers at load, two buffers each so a result never lands on its operand, 24 lanes apart); the suite's five bodies sorted (matmul, knapsack, join's order loop straight-line; roots and BFS not); 026's scope as straight-line programs with the pass for the rest, and its risk
* 043 programs (research 139, in progress): a batch loop's body as the program ↵eunhhu11 days1-0/+52
| | | | a load would make, interpreted a step at a time (scalar steps by the executor's rules, kernel steps over four-byte lane registers fixed at load with two buffers each, a list's cells once a batch, a deferred set after its distance check), against the same kernels called straight and natural.h's C: matmul 10.36 ms (straight 7.17; the executor's 25.8 with 3.6 of making), knapsack 4.16 (straight 3.76; the executor's 8.19); 139's question, bars and b20's split (matmul's 11.1 ms of interpretation, knapsack's 1.9)
* Research 138: the batch executor's stage 5, design 025 made: sums into cells ↵eunhhu11 days1-0/+79
| | | | at once in integers (join 116.0 to 110.5 ms, short of 108: what is left is the same cells' memory, read, add and write again), decide's bit found once (BFS 23.2, short of 21.5: the tail's time was its loads more than its instructions), and the batch executor's loops aligned to 64-byte lines (the hot loops' placement had swung knapsack 6% at the same instructions; the lists' loops aligned too cost the bank's queries 1-2% more instructions, so not they); against b9 matmul -36%, knapsack -28%, roots -7.6%, join -6.2%, BFS -3.9%, the executor alone, the bank queries and TPC-C (+0.7%) as they were; 025's bars and what each stage measured; 024 and CHECKPOINT say so
* Research 137: the batch executor's stage 4 (columns read in place, ↵eunhhu12 days1-0/+66
| | | | comparisons counting their lanes): knapsack 10.07 to 8.25 ms (bar 8.6; b9 11.46, the compiled code 7.9), its instructions 12.2% below b9's; what is left of knapsack's gap is the per-batch interpretation (about 3 ms), not the kernels (ADD 1.7, GT 1.7, the masked set 0.55 ms); the others the same by instructions; make check's server_view_workers timed out once (the known flake), passed 3/3 alone and in a full rerun; bank queries' instructions within 0.1% of b9's, TPC-C -0.3%; the two large gaps left (matmul's nested rounds, BFS's candidate tail) the user's to choose
* Research 136: the batch executor's stage 3 (four-byte MUL, reductions with ↵eunhhu12 days1-0/+65
| | | | no lanes while every lane's e is the same, a list's cells once a batch): against b9, interleaved, matmul 40.01 to 25.97 ms, knapsack 11.47 to 10.07, roots 8.97 to 8.29, join 117.2 to 115.8, BFS and sort the same; sum0 8.69 to 1.01 (bar 1.5); matmul short of its bar (21): the nested rounds' interpretation (about 14 ms) and the matrices' making (4-5) were left out of the arithmetic; the executor alone and the bank queries' instructions as b9 (0.08%), TPC-C +0.7%; stage 4 next (knapsack's six passes to three)
* Research 135: batch plans' stage 2 measured (b11 = 7959885 against b10, ↵eunhhu12 days1-0/+66
| | | | interleaved): matmul 38.18 to 36.10 ms with 4.5% fewer instructions (segments in its nested rounds), knapsack's per-batch cost 0.68 to 0.63 us but knapsack 10.35 to 10.51 ms with 1% fewer instructions (its per-element loops placed elsewhere), sum0 1,743 instructions a batch: short of 025's stage-2 bars (9.2 ms, 0.45 us, 33 ms): 025 priced a segment's instruction at 50 cycles, the counts show about 25 instructions, and a batch's cost sits in finds, bounds, read records, lane setup, masks and the deferred store's check; a list's cells once a batch measured at 3% and not made; next, per element: stage 3's four-byte MUL (matmul 21 ms)
* Research 134: batch plans' stage 1 measured (b10 = a6fabf0 against b9, ↵eunhhu12 days1-0/+72
| | | | interleaved): knapsack's per-batch cost 0.90 to 0.68 us and knapsack 11.48 to 10.34 ms, short of 025's bars (0.60 us, 10.3 ms): 025 counted the pass's per-instruction head as lookups; sum0 2,330 to 1,822 instructions a batch (bar 1,550); matmul 40.0 to 38.2 ms with the same instructions and BFS 24.04 to 24.31 with 0.2% fewer (placement); sum0's 8.69 to 6.13 ms mostly the compiler now vectorizing the reductions' first loop; the executor alone the same instructions; what is left a batch is the pass's Val handling (stage 2); 041 runs.sh pairs, pairs and counts data
* Research 132 and 133 corrected: the per-batch cost was icount's three rounds ↵eunhhu12 days2-10/+14
| | | | over one round's batches, 3x too high; about 2,300 instructions (0.33 us) in a small block, 0.90 us in knapsack's (38% of its time, not 20%)
* Research 133: register tiles measured (132's deciding experiment): past the ↵eunhhu12 days2-1/+89
| | | | bar on roots (0.71x the compiled code's cycles a step), not on knapsack (4x) or BFS (2.4x), as NEON has no gather and a tile's lanes go out and in one by one; tight passes of the batch executor's own shape in the same run at 1.2x (BFS) and 0.4x (knapsack, clang): the shape is right and the 3x is implementation, so 132's A (a batch program made once at load, loops tight by type, width and stride, fewer passes) is the way; tiles kept aside for chains of arithmetic; 132, 024 and CHECKPOINT say so
* Research 132 (no code): where the batch executor's cost sits (an element's ↵eunhhu12 days1-0/+166
| | | | passes through memory; a batch's fixed cost about 6,500 instructions, 1 us, measured by 1024 against 256 lanes: fewer lanes are slower, so 024's L1 sizing was the wrong lever; a candidate's tail about 250), what the database literature measured of the same shape (X100, Kersten 2018's cycles and instructions a tuple, Sompolski 2011, Gubner 2017's in-register aggregation, Photon, Ertl and Gregg), the ways judged by the philosophy (a batch program made once at load; register tiles with threaded dispatch as the one general way past the floor; a table of fused operations and AOT C out), and the deciding experiment with its bar first (three bodies in tiles of 4, 8, 16: within 1.3x the compiled code's cycles an element, or it is not the answer); 041 lanes data
* Research 131: the batch executor's general cuts, by the user's choice of the ↵eunhhu12 days1-0/+95
| | | | general way over a table of fused operations: values computed by the same code taken from the first, if !c one branch, selections (an arm's few lanes alone), keys as bits asked in one loop, L.first + i affine, a slice's bounds at once: the suite's BFS 211 to 112 instructions an edge, 41 to 24 ms (the compiled code 38.5, 7.7); where the rest goes and the floor of the general way (about twice the compiled code); knapsack and matmul 10% slower, cause not fully told; 024 and CHECKPOINT say so
* Research 130: the batch executor's frontiers (a count's guard, walks in a ↵eunhhu13 days1-0/+114
| | | | batch's rounds together or spread into lanes, filters asked as a batch opens and again at its end): the suite's BFS batched, 93 to 41 ms (the compiled code 7.7, C 10); where it goes (211 instructions an edge against 38.5: a filter's code over every lane the most); the floor of operations each a pass over the lanes (about 50 an edge, 1.3x the compiled code) and what would pass it (fused operations from a table, 024's); the choice left: a table of them, or the compiled code kept for such work; 024 and CHECKPOINT say so
* Research 129: the batch executor's costs cut (appends at once 5.18 to 0.65 ↵eunhhu2026-10-061-0/+124
| | | | ms, a recurrence's steps as numbered values and one loop of actions 44.4 to 21.8, reductions' ends in any order where it cannot tell 9.80 to 4.00): knapsack 10.8, matmul 36.4, join 118, sort 55.5 ms without machine code; where each work's time goes now; BFS's arithmetic (a tail of about a tenth of the edges, done batch-side; edges spread into lanes, not walked together) and the three pieces it needs; the view-workers check's flake; 024 and CHECKPOINT say so
* Research 128: the batch executor's appends, recurrences, sums into cells and ↵eunhhu2026-10-061-0/+147
| | | | walks (join 423 to 161 ms without machine code, the tier 74) and what a batch pays for, measured apart: an instruction about 20 ns a batch (0.02 ns a round at 1024 lanes), a reduction's end 4-9 ns a round, an append about 100 ns (the executor's), join's recurrence about 60 ns a round; BFS not batched (a count that grows, a filter that only grows, nested walks), so the JIT stays for now; the next in that order: appends at once, the recurrence's steps in registers, reductions' ends; 022 and 024 and CHECKPOINT say so
* 024, 126, 127: the lanes are 24 buffers (stage 2), about 200 KB a thread; ↵eunhhu2026-10-052-2/+4
| | | | stage 2 under ASan and UBSan (139 programs, the executor's output)
* Research 127: the batch executor's stage 2 (nested loops' rounds run ↵eunhhu2026-10-051-0/+65
| | | | together lane by lane, breaks, reductions folded in the rounds' order) and the measured passes after it (finite checks in the arithmetic's loop, tests as four-byte masks, the loop's value made once): roots 9.13 ms without machine code, below the tier's 9.57; matmul 50 (the tier 14.3: its table's loop and 15 instructions a nested round left); 685 random programs alike; 024 and CHECKPOINT say so
* Research 126: the batch executor's first stage (024) as built and measured: ↵eunhhu2026-10-051-0/+100
| | | | knapsack 1,041 to 13.6 ms in the executor (the compiled code 7.5; its inner loop 1.17x the tier's, the stage's criterion missed; the table's adds left to stage 4), the executor without batch loops unchanged; what measuring overturned (a call among the steps cost 20% of the instructions, so two copies; run aligned to 64 for its cycles; results apart from operands for vector code); tests; 1024 lanes, 134 KB a thread; 024 and CHECKPOINT say so
* 125: forms and newton runs named; BFS's time after the graph's load is the ↵eunhhu2026-10-051-3/+5
| | | | generic code's (steps 0.1%), what the tier needs for it (a list's count as a changing value); 023 cites words at e2e56dd
* Research 125: the tier's first steps against C (e2e56dd: roots 1.40, ↵eunhhu2026-10-051-0/+80
| | | | knapsack 1.19, sort 1.37, join 2.54, words 5.58, matmul 1.85, BFS 1.61; geometric mean 1.92, from 3-300x at 6b45806), what each change did, the forms measured in assembly, the apps unchanged, what is left (text in the executor, BFS's appends, spills); CHECKPOINT says so
* Research 124: 022's BFS past C only by reading ahead (15.7 ms against 9.9 ↵eunhhu2026-10-051-0/+89
| | | | without), the suite of seven kinds of work at 3-300x C, floors at 0.90x C with the meaning's checks hoisted to 0-3%; CHECKPOINT says so
* Measure 021: BFS 190 to 90 ms over HTTP against C's 9.1, short of C; Pure's ↵eunhhu2026-10-051-0/+216
| | | | forms by hand beat C only packed, narrow and read ahead (123)
* The same answers on the final build and the same pure-runs on the Pi, WSL2 ↵eunhhu2026-10-041-1/+5
| | | | and a Mac (121); 019 points at 020's view workers
* Check a pushed view that computes gets the newest value of writes made ↵eunhhu2026-10-041-0/+3
| | | | meanwhile, and queue=N's busy and its places coming back (020)
* Measure views off the connection threads: writes' tail as with the CPU ↵eunhhu2026-10-041-0/+84
| | | | shared, two askers 1.95 times one (122)
* Measure computing faster: a search 2.1 times as fast, TPC-C 4.1%, four ↵eunhhu2026-10-041-0/+160
| | | | fingers found and undone (121)
* Say why the dashboard's push-to-poll CPU sits at a tenth: an event costs ↵eunhhu2026-10-041-0/+4
| | | | what a request does (120)
* Wake each thread at most once a push, end streams only of stopped apps, and ↵eunhhu2026-10-041-0/+15
| | | | show a subscriber costs writes nothing (019)
* Say what pushing views costs and how fresh it keeps them (019, research 120)eunhhu2026-10-041-0/+91
|
* Say what views that compute cost the writes beside them (018 stage 3, ↵eunhhu2026-10-041-0/+82
| | | | research 119)
* Say what computing in one event costs and finds (018 stage 2, research 118)eunhhu2026-10-041-0/+90
|
* Say what a transient state saves a write (018 stage 1, research 117)eunhhu2026-10-041-0/+53
|
* Say what an app's tokens cost (017 3b, research 116)eunhhu2026-10-041-0/+58
| | | | | | | | Requests to an app that checks tokens go 2.92% slower than to an open one on 64 keep-alive connections, 2.2% of it the head the token makes longer (an open app sent the same head is as slow); hashing every request on a new connection costs 0.91%. 031 measures the three in turns.
* Say that reading the code found stage 3's two races, and how a host changes appseunhhu2026-10-041-2/+5
| | | | | | | | | The use after free in local_done and the owner's lock made after another app's outlet used it were found reading the code, not by the check, which passed with both before it was made to change senders (115, 017). The usage now says changed lines change in place unless their store moved; and 115 names the path no check takes: a module refused while changing in place.
* Say what apps that change on a running host showed (017 stage 3, research 115)eunhhu2026-10-041-0/+115
| | | | | | | | | | Changing an app in place keeps a million items' app answering but for 1.12 ms (a host restart: 150 ms; stopping and starting it again from its store, as first built, 150.4 ms), 171.5 ms when its records change shape (332 ms). Another app's p99 stays 0.97 times as it was while one changes every 0.2 s; a host of one app is as it was (TPC-C +0.7%, instructions at most +0.02%); each module change leaves 19 KB. 030 holds the windows of both builds, the isolation, the pairs, the counts and the memory.
* Trade stores with the WSL2 too: its bytes are the Pi's (029, research 114)eunhhu2026-10-041-7/+6
| | | | | | The same events make byte-identical stores on the x86_64 WSL2 (4 KiB pages) as on the Pi and the Mac, and a store made on either of the Pi and the WSL2 opens on the other and goes on the same.
* Say what running on an x86_64 WSL2 and an M3 Mac showed (research 114)eunhhu2026-10-021-0/+122
| | | | | | | | | The same modules and inputs give the same outputs, failures and store bytes on the Pi, an x86_64 WSL2 and an M3 Mac; other compilers found an argument read before it was set, and the core and store build on macOS again. WSL2's wall clock steps back about 2 s every 32 s. The Pi froze twice under a measuring tool that held its output: it now streams it, and experiments run under research/guard.py.
* Say what one sending loop showed (017 2b, research 113)eunhhu2026-10-011-0/+107
| | | | | | | The loop alone slowed four links to half: woken by every record queued, it chased the owner a record at a time. Pushing once a turn made links 1.6 times as fast, with threads or the loop alike; the loop's own cost is within the noise. Twenty outputs now add two threads, not 21.
* Measure sending between two apps of a host: local outlet or link (112)eunhhu2026-10-011-0/+56
| | | | | | | | | | Two apps of one host, src sending one message for each of 1,000 items in a burst event, 2,000 bursts a run, five rounds with the ways in turns: the local outlet stores 1,141,642 sends a second at 1.17 us of the host's CPU each, a loopback pure:// link to the host's own port 578,879 at 2.93 us (1.97 times the sends, 0.40 times the CPU). 017's second stage asked for at least the link's rate at half its CPU or less: it goes in. Every run checks dst's sum: each send came once.
* Measure one host of many apps against a process each (111)eunhhu2026-10-011-0/+109
| | | | | | | | | | | | | | | | | | | | 017's first stage met its four criteria on the Pi (RAM stores, five rounds, the order of the ways turned): app B's 99th percentile while app A is flooded by 64 connections is 168 us, half of two processes' 336 us; the two apps busy together write 146.1k a second against 146.2k, with the same 1.4 ms tail; an app costs a host 120 KiB of its own memory (a process: 1,311 KiB PSS) and 100 apps still run on three threads; a host of one app keeps its speed (TPC-C +1.2% at the median of six pairs, two of them interfered and kept; the bank's queries within 2.6%) and its instructions (+0.94% at most). On the way: apps hopped between workers each turn (fixed in db4ee9c), connections of one app spread over all connection threads made the host a third more expensive a request and its tail a kernel tick (fixed by home threads, d24881d), and the work budget's counting cost every table row 26 instructions (fixed in be297ea). The earlier runs are kept apart (db4ee9c's isolation, d24881d's pairs and counts, the interrupted first try).
* Measure 07047c3 again on a quiet Pi (110)eunhhu2026-09-301-3/+20
| | | | | | | | | | The six pairs rerun once the Pi had been quiet for a minute, on the same binaries. Two pairs were still interfered (the first's before at an owner share of 0.54, the sixth at 0.73 on both sides); the four clean ones are -1.7%, -0.4%, +1.8% and +1.1%, CPU per transaction 43.25 to 42.9 us. The bank's queries are as fast or faster after, though the interference fell more on the before runs; the instruction counts stay the comparison to trust.
* Count instructions where timing cannot tell 3% apart (110)eunhhu2026-09-301-0/+104
| | | | | | | | | | | | | | | | | 016's second stage passed its criterion: six interleaved pairs against ee21aec gave TPC-C (RAM, W=1) -0.6% at the median and the bank's queries 0.0% to +2.2%, no run interfered. The ranks query was slower all six times, and chasing it showed that on this Pi timing cannot separate 1-3%: two servers asked in turns disagree with themselves (ee21aec to e02bfc9 +1.6%, e02bfc9 to 481642f -1.2%, ee21aec to 481642f +2.8%), and a query whose instructions grew 0.6% ran 3.5% faster. Instructions do not move so: pcount.c counts the server's user-mode instructions with perf_event_open (no perf here), and psample.c samples where they go. ranks had grown 0.4% in instructions (the rest was where code and data landed), per_branch 3.6% and tables 20 instructions a row, which 07047c3 halved. The six pairs of 07047c3 were interfered (another session's build, load 4-12) and are kept apart, unused.
* Say what 109 inferred and what it did not measureeunhhu2026-09-301-1/+3
|
* Say that prefetching items did not pay, and why (109)eunhhu2026-09-301-0/+57
| | | | | | | | | 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.
* Say what finding items should gain, before measuring it (109)eunhhu2026-09-301-0/+34
|
* Say what the screen showed of a value, and what Vega now keeps from acting ↵eunhhu2026-09-301-2/+21
| | | | (015, 108)
* Say what a value means at each boundary, and what checking it found (015, 108)eunhhu2026-09-301-0/+45
|