Newshot

Strata — memory is explicit I/O

Summary

I've long thought about how we're influenced by CPU architectures, and importantly, their ISAs. In a discussion at a meetup, I brought up a topic that interested me for a while: how would an ISA that exposes memory and cache interactions in a more explicit way (because if you think about it, memory is very much I/O), as opposed to being smart and predictive on its own? An obscure interest, of course. Nevertheless, I wanted to build a quick prototype after that. What ended up transpiring was a bit larger. A multicore architecture with tiered stores, capabilities, a JIT'd emulator, Verilog RTL with a simulator, a small microkernel OS, UI, JIT Forth, an assembler in its own assembly, a bootstrapping C99 compiler, a few games, a visual debugger, and a few other things. (This also shows just how far a directed LLM process can go in little time) Comments

Original text(via Lobsters)

01The idea

Modern CPUs pretend memory is flat and fast, then spend a third of the chip keeping up the pretence. Strata stops pretending. What software can reach directly is small and fast; everything else is a transfer you ask for, and can overlap with work.

Local Stores, not caches

Loads and stores reach only registers and a 64 KiB data Local Store per core. Instructions come only from a 64 KiB instruction Local Store. L1 is an architectural scratchpad, and software decides what lives there.

Transfers, as if synchronous

tget, tput and tgetx move data between tiers with completion tags. Each takes effect at its issue point; the hardware stalls any access to a range still in flight. Overlap is a performance choice, never a correctness one.

Linear capabilities

Far memory is named only through capabilities. Writable ones can be split, joined, given to another core and taken back — never copied. A data race is not something you can write down. Revocation domains take everything back at once.

No interrupts

A device “interrupts” by completing a transfer. tany waits for any of a set of transfers, or for a capability arriving in the inbox. Ctrl-C is a console read that completes when you press the key. The timer is a read that completes at a deadline.

02The tiers, all visible


        ; divide the work by dividing ownership
        csplit c5, c0, s6     ; c0 = my piece, c5 = the rest
        csplit c8, c5, s6     ; c5 = core k's piece
        cgive  c5, s3         ; hand it over (c5 is now empty)
        ...
        ctake  c5, s3         ; take it back from core k only
        cjoin  c0, c5         ; and glue the array together

; stream far data while computing
        tget   tg1, a0, c0, t0, t1   ; ask for the next block
        ...                          ; work on the current one
        twait  tg1                   ; (loads would wait anyway)
      
A Mandelbrot set rendered by eight Strata cores into the framebuffer
A Mandelbrot set rendered by eight Strata cores into the framebuffer

03StrataOS

A microkernel written in Strata assembly, where the explicit machine shows through instead of being hidden. Its architecture, the kernel, and every server's messages →

A kernel that pages itself

A few kilobytes stay resident. The rest of the kernel is code units it loads into its own instruction store on demand — the same xcall / xmiss mechanism programs use.

Servers are processes

proc, dev, fs, tty, pipe and the window server ws run in user mode. A message is a lent buffer capability; programs talk to servers directly, core to core, in hardware.

Context switches you can see

Preemptive multitasking with a configurable time slice (2 ms by default, down to 100 µs). A switch copies the used Local Store out and in — the cache flush other CPUs hide. ps shows each process's switches and kilobytes moved; the window server's core lattice pulses with every one.


        strata$ seq 30 | grep 2 | wc      # three processes, two pipes
strata$ -n 3 mandel &             # three threads, time-shared
strata$ as < hello.s > hi && hi   # the assembler, written in Strata
strata$ ps                        # switches and KiB moved, per process
strata$ ws                        # the window server takes the screen
      

The window server

ws is the only process that touches the framebuffer. It tiles windows on a grid, and makes the machine visible: the strip at the top has one cell per core, lit in the colour of the process running there, pulsing on every context switch; each window's tag shows how many kilobytes its context switches have moved. Clients draw in their own memory and lend each finished band to the server as a capability; only the server writes the screen.

The StrataOS window server: four tiled windows, a terminal showing ps, a Mandelbrot, a clock and a terminal showing cores, under a strip of core cells
The StrataOS window server: four tiled windows, a terminal showing ps, a Mandelbrot, a clock and a terminal showing cores, under a strip of core cells
The launch palette open over a dimmed desktop
The launch palette open over a dimmed desktop
The boot splash: the word STRATA assembling from horizontal bands
The boot splash: the word STRATA assembling from horizontal bands
A first-person view of a grey hall with a zombie in front of a pistol's muzzle flash and a status bar underneath, in a window of the StrataOS window server
A first-person view of a grey hall with a zombie in front of a pistol's muzzle flash and a status bar underneath, in a window of the StrataOS window server
Four pictures of a children's game in pastel pixel art: a castle hall seen from above with a little princess and a duckling, a garden party with a duck and a bluebird under the word HOORAY, a garden with flowers in patches of soil, and a colouring page of a castle with one part painted purple
Four pictures of a children's game in pastel pixel art: a castle hall seen from above with a little princess and a duckling, a garden party with a duck and a bluebird under the word HOORAY, a garden with flowers in patches of soil, and a colouring page of a castle with one part painted purple
A city-building game in bright pixel art: a small town by a river, with the town's yearly paper, the Plat Ledger, open over it: a headline about traffic jams, the residents, jobs, treasury and the mayor's approval
A city-building game in bright pixel art: a small town by a river, with the town's yearly paper, the Plat Ledger, open over it: a headline about traffic jams, the residents, jobs, treasury and the mayor's approval
A two-panel file navigator in blue and cyan: on the left the results of searching for vi across the whole disk, each file with the directory it is in; on the right a quick view of the selected file, the source of the vi editor
A two-panel file navigator in blue and cyan: on the left the results of searching for vi across the whole disk, each file with the directory it is in; on the right a quick view of the selected file, the source of the vi editor

04Strata Forth

A Forth bootstrapped the classic way — a small kernel of primitives in assembly, the rest of the language defined in Forth — with a modern twist: words compile to native Strata code. Because stores cannot write instruction memory, every definition is assembled in data memory, written to far memory and installed with tgetx: a JIT whose install step you can watch.

  • Inlining, constant folding and tail calls
  • Capabilities, transfers and tags as ordinary words
  • far@ / far! through a software cache built on ltag / linst
  • spawn / await across cores
  • Locals, quotations, catch/throw, see

Every word, with its source, and a playground →


        : sq ( n -- n*n ) dup * ;  ok
7 sq . 49  ok
see sq
: sq  ( xt $8100 , 40 bytes)
  8100:  addi sp, sp, -8
  8104:  sd   ra, 0(sp)
  8108:  addi s0, s0, -8
  810c:  sd   s1, 0(s0)
  8110:  ld   t0, 0(s0)
  8114:  addi s0, s0, 8
  8118:  mul  s1, t0, s1
  811c:  ld   ra, 0(sp)
  8120:  addi sp, sp, 8
  8124:  ret
 ok
: sum-sq ( n -- ) 0 swap 0 do i sq + loop ;  ok
100 sum-sq . 328350  ok
      
A Mandelbrot set rendered in parallel by Strata Forth
A Mandelbrot set rendered in parallel by Strata Forth

05C, compiled on the machine

cc is a C99 compiler that runs inside StrataOS and writes program images directly: one pass, no assembler, no linker. It is written in C and compiles itself; the first compiler, cc0, is the same language in Strata assembly, and compiling the compiler with itself twice gives the same bytes as the cc on the disk.

  • Both compilers pass 521 tests from the suites of two other C compilers
  • asm("...") and intrinsics for what only Strata has: transfers, capabilities
  • 106 KiB of compiler in a 32 KiB instruction store: it pages itself
  • The same source builds as a cross compiler on your machine

The bootstrap, the machine from C, the tests →


        strata$ cc /src/hi.c
strata$ hi there
Hello from C on Strata, there!
strata$ cc0 -p -h 0 -o cc1 /src/cc.c   # assembly compiles the compiler
strata$ cc1 -p -h 0 -o c2 /src/cc.c    # which compiles itself
strata$ cmp c2 /bin/cc
c2 /bin/cc: same
      

06Try it in your browser

The reference emulator, compiled to WebAssembly. Boot StrataOS on 12 cores and type at its shell, watch eight cores draw a Mandelbrot set into the framebuffer, or define words in Forth and see them run as native Strata code, compile a C program with the compiler on the disk — no install.

Run Strata in your browser

07Run it

Needs a C compiler and Verilator 5; SDL2 is optional (for the window). Or read it first: the source browser has every assembly, Forth and C program, syntax-coloured.

The text above was extracted automatically from the source page and may miss images, tables or code blocks. The original is authoritative.

Published by Lobsters
This site only summarises and aggregates; copyright stays with the original author. Headlines and summaries follow the source — where they differ, the original wins.
Read the original ↗