On 5/16/2022 at 2:55 PM, svenvandevelde said:
Here a few test programs that I've written to test the mechanisms and performance of the vera heap manager. It is coming together:
- best fit algorithm for finding the optimal free block.
Just a comment from an ancient ComSci memory: Have you considered "worst fit" allocation? It sounds stupid on the face of it, but is used by some allocators because it causes less heap fragmentation than "best fit". "Best fit" tends to leave little tiny unallocated pieces all over the heap. Finding the block is also easy/fast, 'coz it's at the top of the heap.
And there's always "first fit", which might be the fastest, with fragmentation performance somewhere in between, but that tends to be a compromise solution that no one likes (it isn't that much faster, at best)
I've always wondered about a "perfect or worst fit" allocator that would allocate a perfectly-sized block if one was available, and allocate from the worst-fit otherwise. That should truly provide minimal fragmentation for any given workload. I just haven't sat down and worked out the actual space and performance hit of having to maintain a block-size hash table for the perfect-fit step... And, on small computers, this is a fairly serious tradeoff decision, because both space and time are tightly constrained.
On a side note, I strongly suspect that any text-heavy application would benefit more from the implementation of a "rope" variable type (structure, whatever -- don't get too hung up on the word "type", I'm just an old C++ programmer and think that way) that could be used instead of strings. Cutting apart and reassembling strings is one of the fastest ways to fill and fragment your heap. A rope is made of multiple strings (get it?
? ), and either each piece contains a pointer to the next piece (which precludes re-using any piece in multiple ropes, so it's less useful) or a separate list of pointers to all of the strings. Concatenation then only requires allocation of the pointer-list and doesn't involve copying text at all. This means that string literals inside your code are used directly in place, even when combined into larger ropes, saving even more memory. Of course, you can't use any of the underlying OS I/O routines directly with these (although that would be a cool Kernal extension, to my mind), but it should be a relatively small wrapper to walk through a pointer-list calling the OS routine for each string.
(I wish I could take any credit whatsoever for the rope idea, but it's been an extended C++ "type" for a very long time. Hmmm... Just looked this up, and they're a bit fancier than I described, with the benefit of being faster for more operations because of binary tree optimizations:
https://www.geeksforgeeks.org/stl-ropes-in-c/ )