aboutsummaryrefslogtreecommitdiffstats
path: root/docs
Commit message (Collapse)AuthorAgeFilesLines
* 023: near C is the aim (each within 1.25x, the geometric mean within 1.1x), ↵eunhhu2026-10-051-10/+13
| | | | not past it; representation first, since a keyed list given keys in order stays FLAT and is searched by halves (knapsack's and matmul's 300x)
* 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
* 023: only checks the tier moved know just that they fail (those left in ↵eunhhu2026-10-051-4/+8
| | | | place fault where they are; now is the host's per-event value); value numbering of pure operations, which words' floor assumes
* Design 023, before building it: a tier that lifts every block to SSA, knows ↵eunhhu2026-10-051-0/+178
| | | | types and ranges, hoists the meaning's checks out of loops, counts work per loop, allocates registers; criteria on research 124's suite of seven kinds of work against C (each within 1.25x, the geometric mean below 1.0, the meaning's checks within 5%), from floors at 0.90x C
* Say what finishing 022's stage 3 found: the books and the work in registers, ↵eunhhu2026-10-051-1/+40
| | | | reading ahead to the bucket's last cell, the edge loop's checks; that past C is the reading ahead (16.1 ms without it, C 9.8), and that the criteria move to 023's suite
* Say what 022 decided while building stages 1-4 and how stage 3 ends: ↵eunhhu2026-10-051-1/+36
| | | | integers assumed, the rest of a round in the executor when they break, the books in registers
* Design 022: stored lists as arrays with a bucket index fitted to the keys ↵eunhhu2026-10-051-0/+151
| | | | searched, narrow columns, a JIT with registers and loop guards, read ahead; criteria first
* Measure 021: BFS 190 to 90 ms over HTTP against C's 9.1, short of C; Pure's ↵eunhhu2026-10-052-1/+218
| | | | forms by hand beat C only packed, narrow and read ahead (123)
* Measure an index for a stored list's slices outside the list: three times a ↵eunhhu2026-10-051-3/+8
| | | | tree's seek, still seven times C's (021)
* Say what a search's floor is with stored lists as trees: 373 ns a node to ↵eunhhu2026-10-051-1/+16
| | | | find a slice against C's 21 (021)
* Say how a search gets past C: event lists as arrays, a directory for stored ↵eunhhu2026-10-051-0/+112
| | | | keys, then a JIT, with criteria (021)
* The same answers on the final build and the same pure-runs on the Pi, WSL2 ↵eunhhu2026-10-042-3/+8
| | | | 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)
* Say 020 is built and measured (121, 122)eunhhu2026-10-041-1/+1
|
* 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)
* Compute views with a body on view workers, off the connection threads, asked ↵eunhhu2026-10-041-0/+11
| | | | | | | | | | | | | | | | | | | | and pushed (020) - pure-serve --view-workers N (a CPU each; 0: on the connection threads): a GET of a view with a body (or a table with such a column) goes to the workers, which show it from the app's newest snapshot on readers of their own and give the answer back as an owner does (eventfd). The connection thread reads and writes its other connections meanwhile. - A snapshot of another module than the request was resolved with, or none (the app stopped), answers 503 stopped. Past an app's queue=N of them, 503 busy. - A push group of such a view hands one evaluation at a time; a newer snapshot meanwhile is evaluated after it; a group whose subscribers all left stays until its evaluation is back. - check.py server_view_workers: 8 askers of a long view while its app changes module (another view in its place) and then goes: every answer the old module's, the new one's, 503 or 404; streams closed at once leave nothing; --view-workers 0 as before.
* Keep one finger a thread, as before: four cost the bank's queries ↵eunhhu2026-10-041-4/+6
| | | | instructions and a search no time (020)
* Search an event's keyed lists by a key set and lists by fingers, add by key ↵eunhhu2026-10-041-1/+18
| | | | | | | | | | | | | | | | | | | | in one descent, and loop without recursion (020) - An event's list keyed by a number keeps its keys beside its tree: bits while they are small whole numbers, else an open-addressing table; has() reads only that, and inserts, removes, key changes, their undoing and clears keep it. - Each thread keeps fingers on the last four leaves it read (list id and version must match): reads by position and searches by key that land in them do not descend. - pure_list_add finds a key's place and inserts there in one descent; a stored keyed list's appends take it too, journaled as inserts. - Child searches count over the whole guide; item fields know at load whether they are text; loops run on a stack of loop records, not by recursion; module-list.c builds at -O3. - test-module: the key set and fingers answer as a model at every step (bits to table, removes inside runs, undone changes, clears, shares), and a stored keyed list's adds replay from its journal.
* Say where a search's time goes and how to make it and long views fast, with ↵eunhhu2026-10-041-0/+84
| | | | criteria (020)
* 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-042-1/+92
|
* Push a view's value to its subscribers over SSE, once per group and interval ↵eunhhu2026-10-042-1/+10
| | | | (019)
* Fix 019 before building: compare equal freshness, bound pushes per interval, ↵eunhhu2026-10-041-9/+24
| | | | carry streams across module changes
* Say how pure-serve pushes a view's value to its subscribers, and what it ↵eunhhu2026-10-041-0/+91
| | | | must show (019)
* Say what views that compute cost the writes beside them (018 stage 3, ↵eunhhu2026-10-042-1/+84
| | | | research 119)
* Say why stage 3's first isolation criterion could not hold, and what to ↵eunhhu2026-10-041-0/+21
| | | | measure instead (018)
* Let a view compute in its body, on a reader's own lists (018 stage 3)eunhhu2026-10-042-5/+16
|
* Say what computing in one event costs and finds (018 stage 2, research 118)eunhhu2026-10-042-1/+92
|
* Count in loops that nest, break, and keep an event's own lists, every event ↵eunhhu2026-10-042-10/+30
| | | | bounded (018 stage 2)
* Say what a transient state saves a write (018 stage 1, research 117)eunhhu2026-10-042-1/+55
|
* Keep transient states the app's while it runs, never stored (018 stage 1)eunhhu2026-10-042-5/+13
|
* Say how aup chooses what a state outlives, and computes in memory (018)eunhhu2026-10-041-0/+199
|
* Say what an app's tokens cost (017 3b, research 116)eunhhu2026-10-042-1/+67
| | | | | | | | 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 how an app's routes take tokens, and what it must show (017, 3b)eunhhu2026-10-041-1/+30
| | | | | | | | | An app given a tokens file (tokens=FILE, --tokens FILE) takes requests bearing a token whose SHA-256 the file lists: read for its views, queries and documents, write for all, input=NAME for one input alone; 401 without one, 403 past its grant. A delivery another node sealed needs none: its key told who sent it. A connection keeps its last token's grant; a reading swaps the tokens without stopping the app.
* Say that reading the code found stage 3's two races, and how a host changes appseunhhu2026-10-042-4/+7
| | | | | | | | | 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-042-6/+139
| | | | | | | | | | 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.
* Say how apps start, stop and change on a running host, and what it must show ↵eunhhu2026-10-041-1/+76
| | | | | | | | | | | | (017, stage 3) The --apps file is the host's shape: on SIGHUP the host reads it again and starts the apps of new lines, stops those of lines gone, starts again those whose line changed (states carried by name from the store) and those stopped or uncertain. A request carries the module it was resolved with, and is not applied under another (503 stopped); link streams and local outlets look their input up again. Route authentication (3b) is designed apart.
* 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-012-6/+129
| | | | | | | 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.
* Say how sends will share one loop, and what it must show (017, 2b)eunhhu2026-10-011-3/+18
| | | | | | | | | | | | | | | | Each link and each HTTP wire sends on a thread of its own: a host with twenty outputs runs twenty-one threads more than one without. 2b moves them into one sending loop: an epoll over the links' UDP sockets and the wires' TCP sockets with one wake, waiting until the soonest link timer or wire pause. Links (2b-1) do in the loop what their threads did each round; wires (2b-2) become a non-blocking HTTP/1.1 client state machine, with non-blocking steps added to the crypto table for TLS. A name looked up again still waits where it is, and says so. Before building: every link, wire, answer and seal check green; a host of ten links and ten wires two threads above one without; and link and wire throughput, alternated before and after, no more than 5% lower at the median (four links together: 10%).
* Say that apps of a host send to each other and to other nodes (017)eunhhu2026-10-011-2/+13
| | | | | | | | Stage 2 is built and measured: what was learned (the receiving side needed nothing new, an output goes one way only) and the numbers. The checkpoint adds sending to the many-apps row, and keeps 2b (one loop for the send threads) and stage 3 (apps added and replaced while the host runs) among what is left.
* 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.
* docs: link aup and vega via clean web paths instead of raw server pathseunhhu2026-10-011-1/+1
|
* Say how apps will send to each other and to other nodes, and what it must ↵eunhhu2026-10-011-2/+41
| | | | | | | | | | | | | | | | | | | | show (017) Stage 2: each app of --apps takes its wiring (send=, seal=, reply=), its sends' source being APP.OUTPUT; one --link-port takes every app's inputs, a stream's input name APP/INPUT (012 unchanged); and send= OUTPUT=APP/INPUT hands an app's saved sends to another app of the same host with no socket, seal or packet: an outlet with the window links have, a batch of records as a link delivers them put in the receiving app's queue, applied after its last number heard, and the number heard after its save trimming the sender's outbox. Merging the send threads into one loop is split off as 2b. Before building: it goes in if the inner outlet stores at least as many sends a second as a loopback pure:// link between the same two apps, at half the host's CPU a stored send or less; checked by a host sending to an app of its own and to one of another host, exactly once and in order across a kill -9, and held back by a full receiver.
* Say that one host runs many apps, and what its first stage found (017)eunhhu2026-10-011-10/+41
| | | | | | | | | | 017's first stage is built and measured: the shape now says what was built where it differs from the design (work counted as written, nothing counted without a budget, every app of --apps run by workers, a busy app kept on its worker, a home thread for each app's connections), and what was learned on the way. The checkpoint lists many apps on one host among what Pure shows, and stages 2 and 3 among what is left.
* 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).
* Say how one host will run many apps, and what it must show (017)eunhhu2026-10-011-0/+128
| | | | | | | | | | | | | | | | | | | | | | | pure-serve runs one app a process: a module, a store, its own threads, port and key, scheduled by Linux. Within one process nothing bounds an event's run (it grows with its lists), the requests waiting for the owner, or one store's sync, which holds every other store's commit since the tree store has one writer's turn per process. 017 makes an app an execution domain (007): a host of many apps (--apps FILE, routes /APP/...) runs them by turns on a fixed number of worker threads, none per app; budgets per app in deterministic units (memory in stored bytes as before, work in instructions counted per block and per item visited, queue in requests: 422 work, 503 busy); writer turns per store; and an app that cannot start or whose save became uncertain stops alone. Stage 1 is all that; links, sends between apps and an app's lifetime come after. Before building: it goes in if an app B's p99 under app A's flood is within 1.5 times what two processes give, an app costs under a quarter of an idle process's own memory with no thread of its own, the pair's throughput is within 10% of two processes', and a one-app host keeps its speed (3% in time, 1% in instructions).