mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-05-30 00:27:30 +03:00
Remove hpa_sec_batch_fill_extra and calculate nallocs automatically.
This change includes the following improvements: - Remove the hpa_sec_batch_fill_extra parameter. - Refactor the hpa_alloc() code and helper functions to be able to allocate more than one extent out of a single pageslab. This way we can amortize the per-pageslab costs (active bitmap iteration, pageslab metadata updates) across multiple extents. - Decide on a min and max number of extents that will be allocated in hpa_alloc(). The code will try to allocate at least the min and allocate up to the max as long as we can allocate additional ones from the pageslab we already have, as additional allocations are relatively cheap. - Add extent allocation distribution stats. - Amend hpa_sec_integration.c unit test.
This commit is contained in:
parent
639e70fcfb
commit
f008ce9fe1
15 changed files with 675 additions and 105 deletions
|
|
@ -161,11 +161,13 @@ TEST_BEGIN(test_hpa_sec) {
|
|||
sec_opts.nshards = 1;
|
||||
sec_opts.max_alloc = 2 * PAGE;
|
||||
sec_opts.max_bytes = NALLOCS * PAGE;
|
||||
sec_opts.batch_fill_extra = 4;
|
||||
|
||||
hpa_shard_t *shard = create_test_data(&hooks, &opts, &sec_opts);
|
||||
bool deferred_work_generated = false;
|
||||
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
|
||||
size_t min_nallocs, target_nallocs;
|
||||
sec_calc_nallocs_for_size(
|
||||
&shard->sec, PAGE, &min_nallocs, &target_nallocs);
|
||||
|
||||
/* alloc 1 PAGE, confirm sec has fill_extra bytes. */
|
||||
edata_t *edata1 = hpa_alloc(tsdn, shard, PAGE, PAGE, false, false,
|
||||
|
|
@ -174,38 +176,53 @@ TEST_BEGIN(test_hpa_sec) {
|
|||
hpa_shard_stats_t hpa_stats;
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive,
|
||||
1 + sec_opts.batch_fill_extra, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, PAGE * sec_opts.batch_fill_extra,
|
||||
"sec should have fill extra pages");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, target_nallocs, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, (target_nallocs - 1) * PAGE,
|
||||
"sec should have extra pages");
|
||||
expect_u64_eq(
|
||||
hpa_stats.nonderived_stats.hpa_alloc_extents[target_nallocs],
|
||||
(uint64_t)1, "");
|
||||
|
||||
/* Alloc/dealloc NALLOCS times and confirm extents are in sec. */
|
||||
edata_t *edatas[NALLOCS];
|
||||
size_t expected_nactive = NALLOCS + target_nallocs;
|
||||
for (int i = 0; i < NALLOCS; i++) {
|
||||
edatas[i] = hpa_alloc(tsdn, shard, PAGE, PAGE, false,
|
||||
false, false, &deferred_work_generated);
|
||||
edatas[i] = hpa_alloc(tsdn, shard, PAGE, PAGE, false, false,
|
||||
false, &deferred_work_generated);
|
||||
expect_ptr_not_null(edatas[i], "Unexpected null edata");
|
||||
}
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, 2 + NALLOCS, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, PAGE, "2 refills (at 0 and 4)");
|
||||
expect_zu_eq(
|
||||
hpa_stats.psset_stats.merged.nactive, expected_nactive, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, (target_nallocs - 1) * PAGE,
|
||||
"multiple refills (every target_nallocs allocations)");
|
||||
const uint64_t expected_nsuccesses =
|
||||
(uint64_t)((NALLOCS + 1 + target_nallocs - 1) / target_nallocs);
|
||||
expect_u64_eq(
|
||||
hpa_stats.nonderived_stats.hpa_alloc_extents[target_nallocs],
|
||||
expected_nsuccesses, "");
|
||||
|
||||
for (int i = 0; i < NALLOCS - 1; i++) {
|
||||
hpa_dalloc(tsdn, shard, edatas[i], &deferred_work_generated);
|
||||
}
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, (2 + NALLOCS), "");
|
||||
expect_zu_eq(
|
||||
hpa_stats.psset_stats.merged.nactive, expected_nactive, "");
|
||||
expect_zu_eq(
|
||||
hpa_stats.secstats.bytes, sec_opts.max_bytes, "sec should be full");
|
||||
|
||||
/* this one should flush 1 + 0.25 * 8 = 3 extents */
|
||||
/* this one should flush 1 + 0.25 * NALLOCS extents */
|
||||
const size_t flushed_extends = 1 + NALLOCS / 4;
|
||||
const size_t expected_native_minus_flushed = expected_nactive
|
||||
- flushed_extends;
|
||||
hpa_dalloc(tsdn, shard, edatas[NALLOCS - 1], &deferred_work_generated);
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, (NALLOCS - 1), "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.ndirty, 3, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive,
|
||||
expected_native_minus_flushed, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.ndirty, flushed_extends, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, 0.75 * sec_opts.max_bytes,
|
||||
"sec should be full");
|
||||
|
||||
|
|
@ -215,7 +232,8 @@ TEST_BEGIN(test_hpa_sec) {
|
|||
expect_ptr_not_null(edata2, "Unexpected null edata");
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, NALLOCS - 1, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive,
|
||||
expected_native_minus_flushed, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, 0.75 * sec_opts.max_bytes - PAGE,
|
||||
"sec should have max_bytes minus one page that just came from it");
|
||||
|
||||
|
|
@ -223,8 +241,9 @@ TEST_BEGIN(test_hpa_sec) {
|
|||
hpa_dalloc(tsdn, shard, edata2, &deferred_work_generated);
|
||||
memset(&hpa_stats, 0, sizeof(hpa_shard_stats_t));
|
||||
hpa_shard_stats_merge(tsdn, shard, &hpa_stats);
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive, NALLOCS - 1, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.ndirty, 3, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.nactive,
|
||||
expected_native_minus_flushed, "");
|
||||
expect_zu_eq(hpa_stats.psset_stats.merged.ndirty, flushed_extends, "");
|
||||
expect_zu_eq(hpa_stats.secstats.bytes, 0.75 * sec_opts.max_bytes, "");
|
||||
|
||||
destroy_test_data(shard);
|
||||
|
|
|
|||
|
|
@ -312,7 +312,6 @@ TEST_BEGIN(test_mallctl_opt) {
|
|||
TEST_MALLCTL_OPT(size_t, hpa_sec_nshards, always);
|
||||
TEST_MALLCTL_OPT(size_t, hpa_sec_max_alloc, always);
|
||||
TEST_MALLCTL_OPT(size_t, hpa_sec_max_bytes, always);
|
||||
TEST_MALLCTL_OPT(size_t, hpa_sec_batch_fill_extra, always);
|
||||
TEST_MALLCTL_OPT(ssize_t, experimental_hpa_max_purge_nhp, always);
|
||||
TEST_MALLCTL_OPT(size_t, hpa_purge_threshold, always);
|
||||
TEST_MALLCTL_OPT(uint64_t, hpa_min_purge_delay_ms, always);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ TEST_BEGIN(test_sec_fill) {
|
|||
opts.nshards = 1;
|
||||
opts.max_alloc = 2 * PAGE;
|
||||
opts.max_bytes = 4 * PAGE;
|
||||
opts.batch_fill_extra = 2;
|
||||
|
||||
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
|
||||
test_data_init(tsdn, &tdata, &opts);
|
||||
|
|
@ -114,7 +113,6 @@ TEST_BEGIN(test_sec_alloc) {
|
|||
opts.nshards = 1;
|
||||
opts.max_alloc = 2 * PAGE;
|
||||
opts.max_bytes = 4 * PAGE;
|
||||
opts.batch_fill_extra = 1;
|
||||
|
||||
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
|
||||
test_data_init(tsdn, &tdata, &opts);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue