|
Amiga Logo - |
|
Tuesday August 12, 2003 News Events Community Forums Dealers About
-
- - -
  Club Amiga Monthly - Issue #7 Page 7 of 9

Club Amiga Monthly Index | Prev 1 2 3 4 5 6 7 8 9 Next

ExecSG in detail: Memory

After last month's article about the new library system in OS4, I'd like to take the opportunity to introduce yet another area of improvement: The memory system.

Classic Exec view of memory

The Amiga is a 32-bit system. This means that it has 32 bit addresses, which allows it to access 4294967296 individual cells which make up it's address space. Some parts of these addresses are "real" memory, that is, if you store data to these addresses, you can read it back. Other parts are used for other purposes, like, for example, to access the Amiga's custom chip hardware.

Most Amigas have different memory banks. All of them have chip ram (which always starts at address 0), some have additional fast ram (for example on the A4000 mainboard), and if there's a PPC board in the machine, it's likely to have it's own memory bank as well. All of these memory banks are sitting at specific addresses that are fixed by the hardware.

Older exec versions used this exact layout of memory. To allow programs to dynamically allocate memory, these versions use simple lists, covering each consecutive memory area: Free memory is part of the list, occupied memory is not. Initially, the whole memory bank is covered by a list with one node. When memory is allocated, the list is scanned, and the first block that is either larger or the exact size is taken and removed from the list, and if larger than the requested amount, it's split and the remaining memory is returned into the list.

This method is rather simple and can be efficiently implemented, but it bears several problems. One problem, obviously, is that this method only allows programs to allocate up to the amount of memory installed in the machine. If a machine has, for example, 16 MB installed, it's not possible for any program to allocate more than 16 MB, even though the 32-bit address space would allow for 4 GB of "addressable" memory.

Another problem is even more annoying, and chances are that you might already encountered it when working with your Amiga: After several hours, the machine will become slower, and programs might complain about not having enough memory available, even though Workbench shows you that there's enough free memory. This problem is called fragmentation, and is an inherent problem of the list approach described above.

Fragmentation is caused by continuously allocating and freeing memory, which leads to gaps in the free memory. It also causes the list to become quite large, so it takes longer to traverse it (hence the slowdown). Once fragmentation is present, the only method to get rid of it is to reset the machine. not a good solution, one has to admit.

ExecSG: moving towards a virtual environment

To address these issues, ExecSG introduces something called "virtual addressing". Instead of accepting the memory layout introduced by the hardware, ExecSG tries to "reorganize" memory. This allows it to avoid fragmentation, and fix a number of other problems (it introduces some incompatibilities, though).

Before we go on, I have to explain what virtual addressing means. Don't worry; I will try to make it as non-technical as possible.

Virtual addressing

A dictionary defines "virtual" as "existing or resulting in essence or effect though not in actual fact, form, or name". In other words, it describes something that is seen but not actually there, like a mirage.

And this in fact nicely describes virtual addressing: You address memory at a place it's not normally available. For example, the CPU might try to access memory at address 100, but in reality, it's accessing address 2340. A part of the CPU called the "memory management unit" (or MMU for short) just replaces the virtual address by a physical address. So it's possible to use the MMU to completely change the memory layout. We can, for example, combine several areas of memory into one linear block. If you ponder this possibility, you probably know how to prevent memory fragmentation: by combining smaller blocks into one larger (virtual) block.

Of course, this remapping can't be arbitrary. Modern CPUs can remap blocks of memory to other blocks. These blocks are commonly called tiles, or pages. The term tile aptly describes how this works: Imagine the tiles on a bathroom wall. The MMU can "virtually" rearrange those tiles to form a new version of the wall (the comparison is a bit weak, but should give you an idea on how this works).

Note: Even though the term tile more obviously describes what's happening, the term page is normally used.

As a real-life example, the PowerPC can remap pages of 4096 bytes each (Older CPUs, like the original 68000 didn't even have such a facility, it was introduced with the 68020 as an external chip, and as part of the CPU since the 68030).

To keep down management overhead, ExecSG uses a page size of 64 KB. This means it divides the complete 4 GB address space into 65536 different pages.

Object oriented memory management

ExecSG goes beyond the list approach used in old exec. Memory areas are now objects that are kept in a priority-sorted list. When memory is required, ExecSG queries the objects in the list, asking if it can fulfill the request in terms of size and requirements (for example, a program might ask for a size of 100 bytes and a require chip ram). If the object can't fulfill the request, the next one is asked.

When the object can fulfill the request, the request is executed, and the object reports the allocated memory area back to ExecSG.

The key point to note is that the actual implementation of the object is opaque: Instead of requiring a memory list, the object is free to implement this however it wants to. This makes it possible to exchange the implementation of an object. An object doesn't even need to have the ability to allocate memory at all (see the next section).

But these objects can do even more: Each object controls an area of address space. In addition to managing memory, it also manages other things. For example, when a program tries to access something inside the area controlled by an object, and this results in an error condition, the object itself can intercept that error condition and act accordingly. This is a very powerful mechanism that can be used for a lot of applications, as we will see in a few moments.

Applications and possibilities

The object-oriented approach allows a lot of mechanisms to be implemented that where not possible with the original design. In this section, I'd like to list some of the possibilities: Some are already implemented, some are planned.

Virtual memory: This is the most basic application of the memory objects. An area of address space is used as memory, with "real" (i.e. physically existing) memory being re-mapped to form one large area of memory. This addresses the fragmentation issues that where plaguing the old Exec memory lists.

In addition, this also allows other features, like resizing allocated memory blocks, and delayed memory allocation. Delayed allocation means that the virtual addresses are allocated, but the physical memory is not. Whenever a program now accesses the memory, the above-mentioned error condition hits. As the memory object can intercept this, it can then allocate a tiny bit of memory to make sure that the access works, and return control to the program.

This can be interesting for programs that want to load compressed data into memory: Allocate a large area with delayed allocation (this does not use real memory), then uncompress into this memory, and afterward resize the block to the necessary size. No more than the necessary memory is really used.

Paging/Swapping: This is what is often referred to as virtual memory. If memory is needed but not available, parts of the existing memory are written to a disk, and the now free memory is used by someone who needs it. Remember that virtual addressing allows blocks of memory to appear anywhere, so it doesn't really matter where the memory comes from.

Automatic stack enlargement: If you ever used gcc on the Amiga, or played one of our game ports, you'll probably know that they use a very big stack. You have to set this manually, either in the shell, or in the program's icon. With the ExecSG memory objects, it's possible to make stacks that are automatically enlarged when they are too small. This doesn't require special code in the program (like it's now), and will come with no additional overhead (normally, programs that check their stack themselves run slower than programs that don't care about it).

Memory mapped files or objects: A feature of other operating systems is the ability to "map" files into memory: Instead of using special functions to read or write to a file, the file is accessible as if it was completely loaded into memory, even if it's bigger than the available memory. This feature is also possible with ExecSG's memory objects.

Mediator support: A simple version of a memory object can also simulate the "MMU feature" of the Mediator.

Memory protection: This is the next big step forward. One of the next versions of AmigaOS 4 will have per-application memory objects. The available objects will depend on the currently running process. This simple step will have a very big effect: It will give each running program it's own memory layout. That means that each program will run in it's own address space, and thus it's memory is protected from accidental access from other programs. Some memory objects will remain valid for all programs, for supplying memory that's part of all programs (shared memory).

This step will give the Amiga a new level of stability and security.

Closing

As you can see, there are lots of possibilities. This article could only scratch the surface. I hope it wasn't too technical, but the subject is inherently technical in nature.

Have fun.

Thomas Frieden
Hyperion Entertainment


Club Amiga Monthly Index | Prev 1 2 3 4 5 6 7 8 9 Next

© 2002-2003 Amiga, Inc. | webmaster@os.amiga.com

Note: Amiga assumes no responsibility for the contents of any linked page or site.

Valid HTML 4.01!