summaryrefslogtreecommitdiff
path: root/src/include/utils/memutils.h
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2017-02-27 03:41:44 -0800
committerAndres Freund <andres@anarazel.de>2017-02-27 03:41:44 -0800
commit58b25e98106dbe062cec0f3d31d64977bffaa4af (patch)
treeb112271d687728227732bb3ccdf03dd39a799708 /src/include/utils/memutils.h
parentbfd12cccbd72c1846bfa3e4031155c9bd479d70a (diff)
downloadpostgresql-58b25e98106dbe062cec0f3d31d64977bffaa4af.tar.gz
Add "Slab" MemoryContext implementation for efficient equal-sized allocations.
The default general purpose aset.c style memory context is not a great choice for allocations that are all going to be evenly sized, especially when those objects aren't small, and have varying lifetimes. There tends to be a lot of fragmentation, larger allocations always directly go to libc rather than have their cost amortized over several pallocs. These problems lead to the introduction of ad-hoc slab allocators in reorderbuffer.c. But it turns out that the simplistic implementation leads to problems when a lot of objects are allocated and freed, as aset.c is still the underlying implementation. Especially freeing can easily run into O(n^2) behavior in aset.c. While the O(n^2) behavior in aset.c can, and probably will, be addressed, custom allocators for this behavior are more efficient both in space and time. This allocator is for evenly sized allocations, and supports both cheap allocations and freeing, without fragmenting significantly. It does so by allocating evenly sized blocks via malloc(), and carves them into chunks that can be used for allocations. In order to release blocks to the OS as early as possible, chunks are allocated from the fullest block that still has free objects, increasing the likelihood of a block being entirely unused. A subsequent commit uses this in reorderbuffer.c, but a further allocator is needed to resolve the performance problems triggering this work. There likely are further potentialy uses of this allocator besides reorderbuffer.c. There's potential further optimizations of the new slab.c, in particular the array of freelists could be replaced by a more intelligent structure - but for now this looks more than good enough. Author: Tomas Vondra, editorialized by Andres Freund Reviewed-By: Andres Freund, Petr Jelinek, Robert Haas, Jim Nasby Discussion: https://postgr.es/m/d15dff83-0b37-28ed-0809-95a5cc7292ad@2ndquadrant.com
Diffstat (limited to 'src/include/utils/memutils.h')
-rw-r--r--src/include/utils/memutils.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 1d1035e374..5223a4da39 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -135,6 +135,12 @@ extern MemoryContext AllocSetContextCreate(MemoryContext parent,
Size initBlockSize,
Size maxBlockSize);
+/* slab.c */
+extern MemoryContext SlabContextCreate(MemoryContext parent,
+ const char *name,
+ Size blockSize,
+ Size chunkSize);
+
/*
* Recommended default alloc parameters, suitable for "ordinary" contexts
* that might hold quite a lot of data.
@@ -171,4 +177,7 @@ extern MemoryContext AllocSetContextCreate(MemoryContext parent,
*/
#define ALLOCSET_SEPARATE_THRESHOLD 8192
+#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
+#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
+
#endif /* MEMUTILS_H */