ares/docs/storyboard.md
2023-01-26 18:02:49 -06:00

8.1 KiB

New Mars storyboard

Elevator pitch

An Urbit runtime with near-machine execution speed and NAS-equivalent addressable storage enables most classes of personal applications to be built directly on Urbit.

Wins

Near-machine execution speed

Currently standard library functions which implement highly-iterated loops, such as turn, are jetted to remove arm invocation overhead arising from indirect jumps, dynamic jet matching, and allocation for parameters. The majority of overhead in hot codepaths (such as Ames) is in arm invocations themselves, not in the code for arms.

This is replaced by static jet matching, which removes runtime overhead for jet matching whether a jet is found or not; mostly-direct arm invocations (always direct for idiomatic loops in Hoon) which removes prediction overhead, and bump-allocated and/or register-mapped subjects, which either eliminate memory allocation overhead or make it equivalent to parameter-passing on the stack. Taken together, these approaches should eliminate nearly all overhead in Nock execution and make Urbit performance comparable to native implementations of equivalent programs. (modulo algorithmic mismatches for which jets are still necessary.)

Components: Codegen and 2stackz allocator

NAS-equivalent addressable storage

The current vere is a 32-bit program which addresses a 2, 4, or possibly 8GB "loom" which represents a unified single-level store for both intermediate computational results and persistent state between events. This is implemented by anonymously remapping pages upon writing to them, and then re-writing dirty pages back to the snapshot at regular intervals for durability. The smaller pointer size and the anonymous mapping of "dirty" pages (though primarily the former) limit the size of the loom, necessitating off-Urbit ("off-loom") storage for large objects, especially images and multimedia.

This is replaced by a 64-bit (practically, 47-bit due to limitations of underlying CPU and operating system architectures) arena for persistent data, using a copy-on-write strategy to ensure durability while ensuring all in-use pages can remain mapped to backing disk storage at all times. This retains the single-level store while permitting the underlying OS's virtual memory system to evict pages at will, uncoupling the size of Urbit's data storage from pointer size limitations and available system RAM and swap space. In practice, Urbit can now address many tens of terabytes of locally-stored data

Components: persistent memory arena

Naming

"New Mars" is an excellent skunkworks name but a terrible product name. Perhaps "Ares" is better for a product. Consultation welcome. BIKESHEDDING ENDS HERE

Current status: R&D

Note: Technical risk denotes a low-resolution estimate of the probability that a show-stopping technical problem which returns the project to R&D or makes it demonstrably infeasible emerges from a particular component. Implementation effort is a low-resolution estimation of the developers X effort required to complete and integrate the component into a releasable New Mars/Ares product.

Codegen

Most active work is on code generation, driven by ~ritpub-sipsyl. Subject knowledge analysis, destination-driven linearization, and registerization combine to turn Nock into a nearly zero-cost abstraction. Active implementation effort is focused on the yak-shaving always involved in generating low-level code, and on the problem of propagating subject-knowledge analysis across code-as-state boundaries (arvo-to-vanes, gall-to-agents). Codegen code is currently in Hoon, which requires some bootstrapping story for how codegen code is run and the results supplied to the runtime for execution.

A potential technical risk mitigation is to initially target a bytecode rather than machine code for the lowering of linearized Nock. This eliminates concerns about detecting and managing platform portability and decreases implementation effort and long-tail bugfixes and optimizations significantly.

Technical risk: medium to low

Implementation effort: high

2stackz allocator

The allocator is fully implemented, and requires hardening and benchmarking.

Technical risk: low

Implementation effort: low

Permanent memory arena

This is actively under development, primarily driven by ~finmep-lanteb. The primary innovation is the application to the Urbit runtime of well-understood techniques in database persistence, with pointers instead of semantically higher-level keys as indexes. Open questions no longer implicate feasibility but only the complexity of a successful implementation. The primary open question is one of virtual memory system pressure: can the underlying OS handle the number of virtual memory mappings contained in the table? Or is an on-demand mapping strategy necessary? The latter option is feasible and supported by existing implementation decisions (in particular the use of a B+ tree for the page directory and an always-file-mapped copy-on-write strategy for memory mapping) but represents extra implementation effort.

Technical risk: low

Implementation effort: medium

Non-R&D technical requirements

Jets

One of the hairier yaks to shave to turn New Mars into a product is to rewrite a sufficient set of jets. New Mars' code generation system for Nock should eliminate the need for jets to ameliorate function call and/or looping overheads. Jets will still be needed for algorithmic or numeric hardness, e.g. arithmetic, bit-twiddling, encryption. There are over 350 jets in the current vere, ranging from the absolutely necessary (+add) to the absolutely obsoleted (+turn).

Event logging

The only well-tested approach is logging events to LMDB as the current vere does, so we will initially re-use this approach.

Frontend

We will need to re-implement bootstrapping from a boot sequence (contained in a pill), IPC to communicate with Urth, an event loop which receives events via IPC and dispatches them for logging and processing, and some form of pier import from vere.

Hypothetical storyboard

Task Time P
Jets
Tabulate the jets in current vere 4w Y
Implement jets known absolutely to be necessary ??? Y
Test-and-implement to discover remaining necessary jets 8w N
Codegen
Bytecode generator and interpreter for linearized Nock 4w N
Memory representation of code table keyed by subject knowledge 3w N
SKA propagation through dynamic dispatch (vanes/agents/threads) 12w N
Bootstrapping: compile codegen code to bytecode 8w N
Virtualization and error handling 4w N
2stackz
Harden 3w Y
Integrate with PMA 2w N
PMA
Implement B+ tree page index 5w N
Garbage collection from stack root 4w N
Harden 3w Y
Frontend
Urth IPC protocol 3w N
Bootstrapping from a pill 5w N
Implement an event loop (receive IPC events, log, evaluate) 3w N
Event Log
Re-implement Vere LMDB Event log 4w N
Compatibility
Migration tooling (cue snapshot + metadata) vere->New Mars 2w N