You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use best-fit strategy in Arena, now O(log(n)) instead O(n)
This replaces the first-fit algorithm used in the Arena with a best-fit. According to "Dynamic Storage Allocation: A Survey and Critical Review", Wilson et. al. 1995, http://www.scs.stanford.edu/14wi-cs140/sched/readings/wilson.pdf, both startegies work well in practice.
The advantage of using best-fit is that we can switch the slow O(n) algorithm to O(log(n)) operations. Additionally, some previously O(log(n)) operations are now replaced with O(1) operations by using a hash map. The end effect is that the benchmark runs about 2.5 times faster on my machine:
old: BenchLockedPool, 5, 530, 5.25749, 0.00196938, 0.00199755, 0.00198172
new: BenchLockedPool, 5, 1300, 5.11313, 0.000781493, 0.000793314, 0.00078606
I've run all unit tests and benchmarks.
// Pick a large enough free-chunk. Returns an iterator pointing to the first element that is not less than key.
69
+
// This allocation strategy is best-fit. According to "Dynamic Storage Allocation: A Survey and Critical Review",
70
+
// Wilson et. al. 1995, http://www.scs.stanford.edu/14wi-cs140/sched/readings/wilson.pdf, best-fit and first-fit
71
+
// policies seem to work well in practice.
72
+
auto sizePtrIt = size_to_free_chunk.lower_bound(size);
73
+
if (sizePtrIt == size_to_free_chunk.end())
70
74
returnnullptr;
71
75
72
76
// Create the used-chunk, taking its space from the end of the free-chunk
73
-
auto alloced = chunks_used.emplace(it->first+ it->second - size, size).first;
74
-
if (!(it->second-= size))
75
-
chunks_free.erase(it);
76
-
returnreinterpret_cast<void*>(alloced->first);
77
-
}
78
-
79
-
/* extend the Iterator if other begins at its end */
0 commit comments