Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-04-05 05:09:36 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-04-05 05:14:05 +0400
commit19b7bb5975afdc2340538cb48d85e445828e9d7f (patch)
tree8ca6fb2b681da0c70c86e966ed92dfad2d004a30 /source/blender/blenlib/intern/BLI_mempool.c
parentaf59ee340f8859bdcd5f09c54bcb48776adf0c0a (diff)
Optimize mempool: round chunk size to powers of 2, account for slop-space
This helps to reduce memory fragmentation.
Diffstat (limited to 'source/blender/blenlib/intern/BLI_mempool.c')
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index e4cff4caae5..673dfdefe8e 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -63,6 +63,10 @@
/* when undefined, merge the allocs for BLI_mempool_chunk and its data */
// #define USE_DATA_PTR
+/* optimize pool size */
+#define USE_CHUNK_POW2
+
+
#ifndef NDEBUG
static bool mempool_debug_memset = false;
#endif
@@ -116,6 +120,26 @@ struct BLI_mempool {
# define CHUNK_DATA(chunk) (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
#endif
+/* extra bytes implicitly used for every chunk alloc */
+#ifdef USE_CHUNK_POW2
+# define CHUNK_OVERHEAD (unsigned int)(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))
+#else
+# define CHUNK_OVERHEAD (unsigned int)(MEM_SIZE_OVERHEAD)
+#endif
+
+#ifdef USE_CHUNK_POW2
+static unsigned int power_of_2_max_u(unsigned int x)
+{
+ x -= 1;
+ x = x | (x >> 1);
+ x = x | (x >> 2);
+ x = x | (x >> 4);
+ x = x | (x >> 8);
+ x = x | (x >>16);
+ return x + 1;
+}
+#endif
+
BLI_INLINE BLI_mempool_chunk *mempool_chunk_find(BLI_mempool_chunk *head, unsigned int index)
{
while (index-- && head) {
@@ -230,7 +254,7 @@ static void mempool_chunk_free_all(BLI_mempool_chunk *mpchunk)
BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
unsigned int pchunk, unsigned int flag)
{
- BLI_mempool *pool = NULL;
+ BLI_mempool *pool;
BLI_freenode *lasttail = NULL;
unsigned int i, maxchunks;
@@ -243,18 +267,28 @@ BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
}
if (flag & BLI_MEMPOOL_ALLOW_ITER) {
- pool->esize = MAX2(esize, (unsigned int)sizeof(BLI_freenode));
- }
- else {
- pool->esize = esize;
+ esize = MAX2(esize, (unsigned int)sizeof(BLI_freenode));
}
maxchunks = mempool_maxchunks(totelem, pchunk);
- pool->flag = flag;
- pool->pchunk = pchunk;
- pool->csize = esize * pchunk;
pool->chunks = NULL;
+ pool->esize = esize;
+ pool->csize = esize * pchunk;
+
+
+ /* Optimize chunk size to powers of 2, accounting for slop-space */
+#ifdef USE_CHUNK_POW2
+ {
+ BLI_assert(pool->csize > CHUNK_OVERHEAD);
+ pool->csize = power_of_2_max_u(pool->csize) - CHUNK_OVERHEAD;
+ pchunk = pool->csize / esize;
+ }
+#endif
+
+
+ pool->pchunk = pchunk;
+ pool->flag = flag;
pool->free = NULL; /* mempool_chunk_add assigns */
pool->maxchunks = maxchunks;
#ifdef USE_TOTALLOC