-
Notifications
You must be signed in to change notification settings - Fork 322
Open
Description
As was shown in #189 (comment). The current memory extension implementation for brilirs is surprisingly slow.
Currently, there are no good benchmarks that are memory intensive enough which makes it difficult to know what to optimize for. The closest program seems to be test/mem/alloc_large.bril which only allocates and frees the same sized chunk of memory in a loop.
The current implementation of Heap which supports the memory extension in brilirs is ported from brili and could be greatly improved.
A couple of possible pain points include.
- The
Heapis implemented as a map from the "base" of the pointer to aVec<Value>. This is nice in that it grows and shrinks with the amount of memory in use at any given. However, the use of maps likeHashMap<usize, Vec<Value>>has historically been a performance hit inbrilirsdue to needing to hash the key and perform the lookup.- Ideally we would compress the Heap into either a
Vec<Vec<Value>>or aVec<Value>with the "base" of the pointer just indexing into the start of it's allocation in the array. In either case we will want the ability to reuse indexes as allocations are freed up. - The implementation using
Vec<Vec<Value>>is probably slower than the alternative because it will require two array access to read/write to a value. However, it's probably easier to implement. Vec<Value>is more along the lines of implementing something like malloc which gives all of the performance benefits / fragmentation complexities involved.- Unlike malloc however, one could implement a form of garbage collection and reassign the indexes of pointers since this implementation detail is not exposed to the user. It's not clear to me how this would affect performance.
- Regardless of the implementation, the
Heapneeds to still enforce errors on buffer over/underflows, use after frees, use of uninitialized memory, and memory leaks.
- Ideally we would compress the Heap into either a
- The current implementation allocates a new
Vec<Value>on every call to alloc. Ideally,brilirsshould be able to reuse previously freed allocations. This would especially targetalloc_large.briland potentially provide a significant improvement overbrili.- Two possible solutions for this are either the previously mentioned
Heapas just one largeVec<Value>or using something like a slab allocator and delegating this reuse to an external library.
- Two possible solutions for this are either the previously mentioned
- Unlike with stack allocation where it is statically known how many variables are in scope, memory allocation is dynamic which limits the interpreters ability to pre-allocate capacity for the
Heapto use during the course of interpretation.brilirsalready employs some static analysis for type checking and it would be interesting if it could use a data flow analysis to get a very rough estimate on whether it should start out with a small or largeHeapsize. Some programs don't use the memory extension or use it sparingly which is the default case. On the other hand, we also want to optimize for programs which make of intense use of memory.
Metadata
Metadata
Assignees
Labels
No labels