summaryrefslogtreecommitdiff
path: root/src/third_party/gperftools-2.5
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2016-04-12 08:41:55 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2016-04-12 08:41:55 -0400
commit58b645f6e784c59f449b3091d927b536ad579fca (patch)
treeaeef6573a513aee181f8bbaa908981588f5b1f30 /src/third_party/gperftools-2.5
parent99436618a0fe429ae5519b02e13f0b22cac5eba1 (diff)
downloadmongo-58b645f6e784c59f449b3091d927b536ad579fca.tar.gz
SERVER-17788 [GPerfTools-2.2 Patch] Cut down number of tcmalloc size classes
Cut down number of size classes from 52 to 42. The fewer sizes classes we have, the less memory we waste in overhead with unused allocations, but the more we waste in roundoff error. We use 12.5% as a threshold here, extending the conceptual limit that already existed in the code to how we merge size classes.
Diffstat (limited to 'src/third_party/gperftools-2.5')
-rw-r--r--src/third_party/gperftools-2.5/src/common.cc47
-rw-r--r--src/third_party/gperftools-2.5/src/common.h4
2 files changed, 30 insertions, 21 deletions
diff --git a/src/third_party/gperftools-2.5/src/common.cc b/src/third_party/gperftools-2.5/src/common.cc
index 30b0a931480..215e6b1bf17 100644
--- a/src/third_party/gperftools-2.5/src/common.cc
+++ b/src/third_party/gperftools-2.5/src/common.cc
@@ -99,7 +99,7 @@ int AlignmentForSize(size_t size) {
int SizeMap::NumMoveSize(size_t size) {
if (size == 0) return 0;
- // Use approx 32k transfers between thread and central caches.
+ // Use a min of (8k, 2 count) transfers between thread and central caches.
int num = kTargetTransferBytes / size;
if (num < 2) num = 2;
@@ -135,6 +135,8 @@ void SizeMap::Init() {
// Compute the size classes we want to use
int sc = 1; // Next size class to assign
+ size_t potential_merge_sizes[kMaxSize];
+ int potential_merge_count = 0;
int alignment = kAlignment;
CHECK_CONDITION(kAlignment <= kMinAlign);
for (size_t size = kAlignment; size <= kMaxSize; size += alignment) {
@@ -142,38 +144,45 @@ void SizeMap::Init() {
CHECK_CONDITION((size % alignment) == 0);
int min_objects_per_span = kTargetTransferBytes / size;
- size_t psize = 0;
+ size_t span_size = 0;
do {
- psize += kPageSize;
+ span_size += kPageSize;
// Allocate enough pages so leftover is less than 1/8 of total.
// This bounds wasted space to at most 12.5%.
- while ((psize % size) > (psize >> 3)) {
- psize += kPageSize;
+ while ((span_size % size) > (span_size >> 3)) {
+ span_size += kPageSize;
}
// Continue to add pages until there are at least as many objects in
// the span as are needed when moving objects from the central
// freelists and spans to the thread caches.
- } while ((psize / size) < min_objects_per_span);
- const size_t my_pages = psize >> kPageShift;
-
- if (sc > 1 && my_pages == class_to_pages_[sc-1]) {
- // See if we can merge this into the previous class without
- // increasing the fragmentation of the previous class.
- const size_t my_objects = (my_pages << kPageShift) / size;
- const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)
- / class_to_size_[sc-1];
- if (my_objects == prev_objects) {
- // Adjust last class to include this size
- class_to_size_[sc-1] = size;
- continue;
- }
+ } while ((span_size / size) < min_objects_per_span);
+ const size_t my_pages = span_size >> kPageShift;
+
+ bool merge = (potential_merge_count != 0);
+ for (int i = 0; i < potential_merge_count; i++) {
+ // See if we can merge this into the previous class(es) without
+ // the fragmentation of any of them going over 12.5%.
+ int objects_per_span = span_size / size;
+ size_t waste = span_size - (potential_merge_sizes[i] * objects_per_span);
+ if (waste > (span_size >> 3))
+ merge = false;
+ }
+
+ if (merge) {
+ // Adjust last class to include this size
+ class_to_size_[sc-1] = size;
+ potential_merge_sizes[potential_merge_count++] = size;
+ continue;
}
+ potential_merge_sizes[0] = size;
+ potential_merge_count = 1;
// Add new class
class_to_pages_[sc] = my_pages;
class_to_size_[sc] = size;
sc++;
}
+
if (sc != kNumClasses) {
Log(kCrash, __FILE__, __LINE__,
"wrong number of size classes: (found vs. expected )", sc, kNumClasses);
diff --git a/src/third_party/gperftools-2.5/src/common.h b/src/third_party/gperftools-2.5/src/common.h
index c110aa403f8..253f23b1da8 100644
--- a/src/third_party/gperftools-2.5/src/common.h
+++ b/src/third_party/gperftools-2.5/src/common.h
@@ -88,10 +88,10 @@ static const size_t kPageShift = 15;
static const size_t kNumClasses = kBaseClasses + 69;
#elif defined(TCMALLOC_64K_PAGES)
static const size_t kPageShift = 16;
-static const size_t kNumClasses = kBaseClasses + 37;
+static const size_t kNumClasses = kBaseClasses + 32;
#else
static const size_t kPageShift = 12;
-static const size_t kNumClasses = kBaseClasses + 43;
+static const size_t kNumClasses = kBaseClasses + 33;
#endif
static const size_t kMaxThreadCacheSize = 4 << 20;