aboutsummaryrefslogtreecommitdiffstats
path: root/benchmarks/http/run.py
Commit message (Collapse)AuthorAgeFilesLines
* Show the new layout costs nothing, and keep code where it waseunhhu2026-09-271-0/+6
| | | | | | | | | | | | The benchmark runs an earlier pure-serve build in turn with the current one (--baseline). Against the build before the move, linking through libpure.a costs nothing: a one-command build with the library's object order has the same size and the same CPU per request. What moved was code placement, so the runtime links last again, as it did; the two orders now differ by less than rounds of one build do (total -0.4%, page +1.2%, mixed -0.1%). The binary is 5,008 B smaller: unused flow.c functions stay in the library, and the linker's A53 erratum padding is gone.
* Lay Pure out as a core with the parts selected around iteunhhu2026-09-271-2/+3
| | | | | | | | | | | | | | | | | | | | | The app model, the tree store and the HTTP host lived in prototypes/connections among the earlier document runtime, the store was known only by its format's name, and Vega compiled six Pure sources by path. Now, as the README's principle has it: core/ runtime, flow and the app model (module*.c), with what the core asks of storage (state.h, store.h) store/ the tree store (PURETRE3, PUREREC1) serve/ pure-serve: HTTP host, outbound delivery, JSON in place cli/ pure-run, pure-edit-module A top-level make builds libpure.a (app model and store, for hosts to link) and the hosts; make check runs the store's and the app model's tests. The earlier runtime still builds from prototypes/connections against core/ and store/ (check, check-tree and check-core pass). Design 009 records the rule: parts by role behind libraries; git repositories split by coupling, so the store stays here while its contract moves with the core, and Vega stays apart.
* Measure reads made while durable writes go oneunhhu2026-09-261-11/+36
| | | | | | | | The app suite's last workload, mixed, runs two load generators at once: 8 connections post durable scores while 56 read the total. It shows whether a server's reads wait while its writes sync. It is reported as two rows, posts and reads; answers per CPU second count both.
* Record the app service against axum and drogon (077)eunhhu2026-09-261-4/+11
| | | | | | | | | | | | The scoreboard, 22 lines of aup served by its views and inputs, against the same service written by hand in axum and drogon on the Pi: durable posts about 76 times as many, reads level with drogon and ahead of axum with the least CPU and memory. The note keeps what the profile showed on the way (the kernel's share of a single thread, integers through printf, an owner that saved too early) and what comes next. run.py gains pure-serve-2 and waits for a server that prints its port before it listens.
* Benchmark an app served by its views and inputseunhhu2026-09-261-3/+29
| | | | | | | | | | run.py --suite app serves the scoreboard of scores.aup (22 lines of aup) with pure-serve against the same scoreboard written by hand in axum and drogon: POST /inputs/score?points=N with a name as the body, GET /views/total and a page of 20 rows as JSON. Durable, the baselines append each score to a log and fdatasync it before answering (replayed at start); the load generator learns the three requests.
* Compare the HTTP host with drogon and by CPU timeeunhhu2026-09-261-9/+27
| | | | | | | | | | | | | | | | | A drogon 1.9 service with the axum baseline's contract joins the benchmark (memory, fdatasync and crash-safe modes, three IO threads), built from Debian's packages unpacked under .deps without installing them. drogon listens once per event loop, so the service picks a free port itself: with port 0 every loop got a port of its own and the load reached one. The load generator has one core and saturates near 150k answers a second, so the harness now also reports answers per second of server CPU time (all threads). Over three rotated rounds: small GETs 151.6k/s on three shards (drogon 145.3k, axum 120.9k) and 128k per CPU-second on one thread (drogon 65k, axum 62k); 1 MiB GETs 2,794/s (axum 1,372, drogon 708); crash-safe PUTs 5.1-5.8 times axum and 13-30 times drogon; peak RSS 5.0 MiB against 14.4 and 76.5 MiB. --workloads is now a regular expression.
* Compare durable writes on a device in the same stateeunhhu2026-09-261-37/+81
| | | | | | | | | | An SD card slows down under sustained syncs, so the order of runs alone changed write results several times over. The HTTP benchmark now repeats rounds with the servers in a rotated order, gives every run a fresh store, times the device (an in-place 4 KiB write + fdatasync) before each write workload and reports medians over rounds with the probe range beside them. --workloads picks workloads by label prefix.
* Shard pure-serve across coreseunhhu2026-09-261-0/+2
| | | | | | | | | | | | | | | | | | A burst now looks at the store once (pure_store_pin) instead of once per request; another shard's commit ends before its answer is sent, so a request made after that answer still reads it. With this alone one thread serves 125k small keep-alive reads per second, as many as axum on three cores, with a shorter p99. --threads N runs a shard per thread: its own SO_REUSEPORT listener, epoll set, runtime domain, app and store handle. Writer sessions of the tree store now take turns inside a process with a mutex (the file lock belongs to the process and does not keep threads apart), and revisions settle concurrent edits of a key. A module with states runs on one thread. Three shards serve 151k reads per second; they still commit one by one, so durable writes and 1 MiB reads are better on one thread for now, which stays the default. Note 075 records the numbers.
* Serve modules over persistent connectionseunhhu2026-09-261-2/+2
| | | | | | | | | | | | | | | | pure-serve replaces the module mode of server.c, which goes back to what it was. It keeps the document contract, the runtime core (a work slot per connection, the payload budget, core-owned ingress, borrowed PUT replies) and the group commits, and adds what server.c lacked: HTTP/1.1 persistent connections with in-order pipelining, an edge-triggered epoll owner thread, up to 1,024 connections allocated as they arrive and reused, one writev per answer, and documents opened through a store handle. On the Pi 5 with one thread it serves 106k small keep-alive reads per second (axum on three cores: 126k) at the same p99, 1,741 1 MiB reads (axum: 1,370), and 1,126 durable writes from 64 connections (crash-safe axum: 372), in 7.3 MiB against axum's 17-20 MiB. Note 075 has the table.
* Benchmark the HTTP hosts against axumeunhhu2026-09-261-0/+133
A C load generator, an axum service with the same document contract (in memory, fdatasync, and crash-safe replacement), and a runner that pins the servers and the load to separate CPUs. On the Pi 5, Pure uses about 40% less memory, wins with a new connection per request and with eight durable writers (3.2x the crash-safe axum), but loses 5x on keep-alive reads and 1.5x on 64 durable writers: no persistent connections, one thread, eight connection slots and two fsyncs per commit. Note 075 records the numbers and the targets.