How does Tachyon Virtual Memory Work?
David Betz
Posts: 14,516
I'm pretty sure I've heard Peter say that Tachyon supports some sort of virtual memory. How does it work? Does it work like XMM in PropGCC where there is a hub cache and a driver that reads/writes cache lines? Or, as I suspect, is it something a bit more creative?
Comments
Hi Dave, meant to get back to this question but unless it's at the top of the thread they tend to get lost as they do.
The virtual memory mechanism in Tachyon is fairly simple, it treats any memory device such as SD or SPI Flash etc as if it were a standard byte addressable "random access memory" with a 32-bit memory address. In Forth the memory access words are @ (fetch) and ! (store) and their byte and word variants etc. They also include CMOVE as well as FILL and so on.
To read a byte of memory in Forth the address is passed to C@ (character fetch) and the contents of that location are returned, the stack notation is ( address -- byte ). Conversely to write a byte of memory the byte and address are passed to C! (character store), the stack notation is ( byte address -- ). The virtual memory words work exactly the same way but hide the details of the type of memory and how that memory is accessed. To access the location in physical RAM to allow direct manipulation there is the XADR word which takes a 32-bit virtual memory address and returns with the address in the Prop's hub RAM. Any of the virtual memory write words will set a write flag to ensure that the buffer is flushed automatically if another "sector" needs to be read into this buffer. XADR checks to see if it needs to read in another sector or stay with the buffer. There are currently 4 buffers and directory entry buffers for up to 4 "files" (or just memory areas) open at a time.
Therefore XC@ in the case of Tachyon fetches a byte from within a 4GB range from the SD card, regardless of file system format. The virtual memory device can also be a file itself or an SPI Flash chip, or some networked device's memory. Since virtual memory uses a 32-bit address it can access the first raw 4GB of an SD card directly or up to 4GB of any open file. In fact the FAT32 layers are built on the virtual memory layer and when files are opened they return a 32-bit address to the start of the file on the card or if the file is selected as the virtual memory then the address will access from the start of the file itself which can be anywhere on an SD card and this I've tested on cards up to 32GB (wasn't game to try my 64GBs).
Some assumptions are made regarding the FAT32 file system on the card, first that the files are non-fragmented as is usually the case with SD cards unlike Windows hard drives, and secondly that the files are accessed using only 8.3 names as I regard Microsoft's LFN an abomination (de)engineered for patent protection. The greatest user of SD cards are digital cameras and files are stored non-fragmented and in 8.3 format too.
So any large memory that needs to be addressed by Python or Basic for instance can just be virtual memory although the buffers could easily be increased in size to improve efficiency if necessary. Various optimizations can be made in this regard but unlike XMM, Tachyon's virtual memory is designed for data, not code, although I do expect to implement bytecode execution from virtual memory in some form to be able to expand the Tachyon VM's code space but this would have to be at a higher level than the tight bytecode interpreter loop. In fact it would almost need to be a high level bytecode interpreter loop, still fast but with the prerequisite hooks into the virtual memory handlers (perhaps).
Since memory is buffered in sector sizes then it is possible to use XADR to return the physical address but a variant of XADR would be needed to either read in two sectors in case physical memory access goes beyond the first buffer or to only have one buffer but made up from halves of two sectors.
Here is a dump of virtual memory where the SD is selected as the "memory" device. @ROOT returns the 32-bit virtual memory address of the start of the root directory.
Then I read a long from this memory and display it as well after which I dump an section that overlaps a sector boundary.
Here's the use of XADR as well