Efficient memory management

It is a design goal of ForwardCom to keep program memory contiguous and to minimize memory fragmentation. Traditional computers often have very complicated memory management systems with multilevel address translation, two-level translation-lookaside-buffers (TLB), and huge page tables. Such a system is necessary when each program has access to a large number of memory fragments scattered over a large address space. If we can keep program memory contiguous and minimize fragmentation then there is no need for the large page tables and TLB. Fixed-size memory pages are necessary for efficient address translation if there are many memory blocks at random addresses. However, if program memory is mostly contiguous and the program has only a few large memory blocks rather than many small memory blocks, then it is more efficient to use a simple memory map with variable-size memory pages.

ForwardCom is employing various techniques to keep memory contiguous and avoid fragmentation. If these techniques are used efficiently, then we can use a simple memory map with few entries and avoid the TLB, the large page tables, the and multilevel address translation. In most cases, the memory map will be small enough to fit on the CPU chip. This avoids the cost of TLB misses, minimizes cache misses, and makes memory management much more efficient. We may need traditional page tables in complicated cases where memory blocks are severely fragmented, but we can still keep the executable code and central parts of the data memory indexed in an on-chip memory map for fast access.

A dominating cause of memory fragmentation in traditional computer systems is dynamic link libraries or shared objects. A typical program may access several such libraries, each stored on its own separate memory pages. ForwardCom is using a new library system that is sure to keep program code and library code contiguous in almost all cases. This library system is described here.

Furthermore, ForwardCom is designed so that all program code and data are position-independent. This makes virtual address translation unnecessary in simple cases. Virtual address translation is still supported in ForwardCom, but performance can be improved in the cases where it is not needed.

Another feature that prevents memory fragmentation is calculation of stack size. The compiler stores information about the stack use of each function in object files. The linker is using this information to calculate the necessary stack size. This prevents stack overflow except in the case of deeply recursive functions.

The main thread of a simple program will typically need a memory map with only three memory blocks: executable code (execute only), constant data (read only), and combined stack, static memory, and heap (read and write access). A child thread needs one more memory block if it has private memory. Each process and each thread has its own memory map.

It is possible to obtain top memory performance with these features if the programmer observes some discipline to avoid memory fragmentation. Difficult cases that produce memory fragmentation may include unpredictable heap size, memory-mapped files, large databases, and large multiuser systems.