summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/mheap.c
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2018-06-28 10:59:05 -0400
committerFlorin Coras <florin.coras@gmail.com>2018-06-28 16:33:36 +0000
commit9c949e72a473195c10a1c1caf503db9467c93f9a (patch)
treef44a2128cd25735f553cc9a494a4b12e2580d085 /src/vppinfra/mheap.c
parent7e12d949a346d2e69afb7a8029c0099b5f131b25 (diff)
Fix mheap_get_aligned() performance jackpot
If non-trivial alignment (e.g. 64) requested, and the object size (e.g. 16) is smaller than (alignment_request - MHEAP_ELT_OVERHEAD_BYTES), round up the size request. This avoids creating remainder chunks, which are false-cache-line-sharing bait to begin with. Change-Id: Ie1a21286d29557d125bb346254b1be2def868b1a Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vppinfra/mheap.c')
-rw-r--r--src/vppinfra/mheap.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/vppinfra/mheap.c b/src/vppinfra/mheap.c
index fceca95ff7d..0c72c888498 100644
--- a/src/vppinfra/mheap.c
+++ b/src/vppinfra/mheap.c
@@ -663,12 +663,28 @@ mheap_get_aligned (void *v,
return v;
}
- /* Round requested size. */
+ /*
+ * Round requested size.
+ *
+ * Step 1: round up to the minimum object size.
+ * Step 2: round up to a multiple of the user data size (e.g. 4)
+ * Step 3: if non-trivial alignment requested, round up
+ * so that the object precisely fills a chunk
+ * as big as the alignment request.
+ *
+ * Step 3 prevents the code from going into "bin search hyperspace":
+ * looking at a huge number of fractional remainder chunks, none of which
+ * will satisfy the alignment constraint. This fixes an allocator
+ * performance issue when one requests a large number of 16 byte objects
+ * aligned to 64 bytes, to name one variation on the theme.
+ */
n_user_data_bytes = clib_max (n_user_data_bytes, MHEAP_MIN_USER_DATA_BYTES);
n_user_data_bytes =
round_pow2 (n_user_data_bytes,
STRUCT_SIZE_OF (mheap_elt_t, user_data[0]));
-
+ if (align > MHEAP_ELT_OVERHEAD_BYTES)
+ n_user_data_bytes = clib_max (n_user_data_bytes,
+ align - MHEAP_ELT_OVERHEAD_BYTES);
if (!v)
v = mheap_alloc (0, 64 << 20);