diff options
Diffstat (limited to 'notes')
| -rw-r--r-- | notes/260727-alloc.md | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/notes/260727-alloc.md b/notes/260727-alloc.md index 0988ee7..98a4968 100644 --- a/notes/260727-alloc.md +++ b/notes/260727-alloc.md @@ -200,3 +200,36 @@ caches, so scrap that. However, the following are possible: If either or both of these is implemented, we could then also free memory back to the OS if a slab watermark drops significantly. + +## Addendum B + +Gemini just taught me a little trick: Threads can reserve N slots per +atomic operation. This works as follows: + +* Each thread has a local version of each per-slab watermark value, + bumping the global one in chunks of N, e.g. 32 slots. + +* Another thread-local value keeps track of how many of those slots + are still free; this can be a simple 8-bit counter from N to 0. + +* This way, you don't even need atomic fetch-and-add accessing main + memory most of the time; only once every N allocations. + +This would also help against false sharing on Apple Silicon with its +128 byte cache lines. Although it can still happen if a 64-byte slot +is released into the global free list, and another thread picks it up +while its neighboring 64-byte slot within the same cache line remains +in use by another thread. + +A small amount of false sharing on Apple Silicon isn't too bad, but +there's ways to mitigate it if we ever find it to be an issue. (This +would be ridiculously far in the future of Zisp.) + +One could make the chunk size N dependent on the size class, so that +small size classes reserve chunks of 128 or so, while huge classes +don't reserve any extras because you don't want a thread to reserve +from the sparse number of available slots only to never use it. + +Since the requested size class is generally comptime-known, we don't +cause any additional computation for the "calculation" of the chunk +size N for a size class. |
