mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-29 03:43:06 +03:00
Track nfills and nflushes for arenas.i.small / large.
Small is added purely for convenience. Large flushes wasn't tracked before and can be useful in analysis. Large fill simply reports nmalloc, since there is no batch fill for large currently.
This commit is contained in:
parent
13e88ae970
commit
07c44847c2
7 changed files with 139 additions and 15 deletions
|
|
@ -151,6 +151,15 @@ arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
|
|||
arena_stats_accum_u64(&astats->nrequests_large,
|
||||
nmalloc + nrequests);
|
||||
|
||||
/* nfill == nmalloc for large currently. */
|
||||
arena_stats_accum_u64(&lstats[i].nfills, nmalloc);
|
||||
arena_stats_accum_u64(&astats->nfills_large, nmalloc);
|
||||
|
||||
uint64_t nflush = arena_stats_read_u64(tsdn, &arena->stats,
|
||||
&arena->stats.lstats[i].nflushes);
|
||||
arena_stats_accum_u64(&lstats[i].nflushes, nflush);
|
||||
arena_stats_accum_u64(&astats->nflushes_large, nflush);
|
||||
|
||||
assert(nmalloc >= ndalloc);
|
||||
assert(nmalloc - ndalloc <= SIZE_T_MAX);
|
||||
size_t curlextents = (size_t)(nmalloc - ndalloc);
|
||||
|
|
|
|||
39
src/ctl.c
39
src/ctl.c
|
|
@ -156,10 +156,14 @@ CTL_PROTO(stats_arenas_i_small_allocated)
|
|||
CTL_PROTO(stats_arenas_i_small_nmalloc)
|
||||
CTL_PROTO(stats_arenas_i_small_ndalloc)
|
||||
CTL_PROTO(stats_arenas_i_small_nrequests)
|
||||
CTL_PROTO(stats_arenas_i_small_nfills)
|
||||
CTL_PROTO(stats_arenas_i_small_nflushes)
|
||||
CTL_PROTO(stats_arenas_i_large_allocated)
|
||||
CTL_PROTO(stats_arenas_i_large_nmalloc)
|
||||
CTL_PROTO(stats_arenas_i_large_ndalloc)
|
||||
CTL_PROTO(stats_arenas_i_large_nrequests)
|
||||
CTL_PROTO(stats_arenas_i_large_nfills)
|
||||
CTL_PROTO(stats_arenas_i_large_nflushes)
|
||||
CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
|
||||
CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
|
||||
CTL_PROTO(stats_arenas_i_bins_j_nrequests)
|
||||
|
|
@ -414,14 +418,18 @@ static const ctl_named_node_t stats_arenas_i_small_node[] = {
|
|||
{NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
|
||||
{NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
|
||||
{NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
|
||||
{NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
|
||||
{NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)},
|
||||
{NAME("nfills"), CTL(stats_arenas_i_small_nfills)},
|
||||
{NAME("nflushes"), CTL(stats_arenas_i_small_nflushes)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t stats_arenas_i_large_node[] = {
|
||||
{NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
|
||||
{NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
|
||||
{NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
|
||||
{NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
|
||||
{NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)},
|
||||
{NAME("nfills"), CTL(stats_arenas_i_large_nfills)},
|
||||
{NAME("nflushes"), CTL(stats_arenas_i_large_nflushes)}
|
||||
};
|
||||
|
||||
#define MUTEX_PROF_DATA_NODE(prefix) \
|
||||
|
|
@ -754,6 +762,8 @@ ctl_arena_clear(ctl_arena_t *ctl_arena) {
|
|||
ctl_arena->astats->nmalloc_small = 0;
|
||||
ctl_arena->astats->ndalloc_small = 0;
|
||||
ctl_arena->astats->nrequests_small = 0;
|
||||
ctl_arena->astats->nfills_small = 0;
|
||||
ctl_arena->astats->nflushes_small = 0;
|
||||
memset(ctl_arena->astats->bstats, 0, SC_NBINS *
|
||||
sizeof(bin_stats_t));
|
||||
memset(ctl_arena->astats->lstats, 0, (SC_NSIZES - SC_NBINS) *
|
||||
|
|
@ -785,6 +795,10 @@ ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
|
|||
ctl_arena->astats->bstats[i].ndalloc;
|
||||
ctl_arena->astats->nrequests_small +=
|
||||
ctl_arena->astats->bstats[i].nrequests;
|
||||
ctl_arena->astats->nfills_small +=
|
||||
ctl_arena->astats->bstats[i].nfills;
|
||||
ctl_arena->astats->nflushes_small +=
|
||||
ctl_arena->astats->bstats[i].nflushes;
|
||||
}
|
||||
} else {
|
||||
arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
|
||||
|
|
@ -867,6 +881,8 @@ MUTEX_PROF_ARENA_MUTEXES
|
|||
sdstats->nmalloc_small += astats->nmalloc_small;
|
||||
sdstats->ndalloc_small += astats->ndalloc_small;
|
||||
sdstats->nrequests_small += astats->nrequests_small;
|
||||
sdstats->nfills_small += astats->nfills_small;
|
||||
sdstats->nflushes_small += astats->nflushes_small;
|
||||
|
||||
if (!destroyed) {
|
||||
accum_atomic_zu(&sdstats->astats.allocated_large,
|
||||
|
|
@ -2847,6 +2863,10 @@ CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
|
|||
arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
|
||||
arenas_i(mib[2])->astats->nrequests_small, uint64_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_small_nfills,
|
||||
arenas_i(mib[2])->astats->nfills_small, uint64_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_small_nflushes,
|
||||
arenas_i(mib[2])->astats->nflushes_small, uint64_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
|
||||
atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
|
||||
ATOMIC_RELAXED), size_t)
|
||||
|
|
@ -2856,12 +2876,19 @@ CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
|
|||
CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
|
||||
ctl_arena_stats_read_u64(
|
||||
&arenas_i(mib[2])->astats->astats.ndalloc_large), uint64_t)
|
||||
/*
|
||||
* Note: "nmalloc" here instead of "nrequests" in the read. This is intentional.
|
||||
*/
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
|
||||
ctl_arena_stats_read_u64(
|
||||
&arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t) /* Intentional. */
|
||||
&arenas_i(mib[2])->astats->astats.nrequests_large), uint64_t)
|
||||
/*
|
||||
* Note: "nmalloc_large" here instead of "nfills" in the read. This is
|
||||
* intentional (large has no batch fill).
|
||||
*/
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_large_nfills,
|
||||
ctl_arena_stats_read_u64(
|
||||
&arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_large_nflushes,
|
||||
ctl_arena_stats_read_u64(
|
||||
&arenas_i(mib[2])->astats->astats.nflushes_large), uint64_t)
|
||||
|
||||
/* Lock profiling related APIs below. */
|
||||
#define RO_MUTEX_CTL_GEN(n, l) \
|
||||
|
|
|
|||
36
src/stats.c
36
src/stats.c
|
|
@ -668,9 +668,11 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
|
|||
uint64_t dirty_npurge, dirty_nmadvise, dirty_purged;
|
||||
uint64_t muzzy_npurge, muzzy_nmadvise, muzzy_purged;
|
||||
size_t small_allocated;
|
||||
uint64_t small_nmalloc, small_ndalloc, small_nrequests;
|
||||
uint64_t small_nmalloc, small_ndalloc, small_nrequests, small_nfills,
|
||||
small_nflushes;
|
||||
size_t large_allocated;
|
||||
uint64_t large_nmalloc, large_ndalloc, large_nrequests;
|
||||
uint64_t large_nmalloc, large_ndalloc, large_nrequests, large_nfills,
|
||||
large_nflushes;
|
||||
size_t tcache_bytes;
|
||||
uint64_t uptime;
|
||||
|
||||
|
|
@ -828,11 +830,23 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
|
|||
COL(alloc_count_row, count_nrequests_ps, right, 10, title);
|
||||
col_count_nrequests_ps.str_val = "(#/sec)";
|
||||
|
||||
COL(alloc_count_row, count_nfills, right, 16, title);
|
||||
col_count_nfills.str_val = "nfill";
|
||||
COL(alloc_count_row, count_nfills_ps, right, 10, title);
|
||||
col_count_nfills_ps.str_val = "(#/sec)";
|
||||
|
||||
COL(alloc_count_row, count_nflushes, right, 16, title);
|
||||
col_count_nflushes.str_val = "nflush";
|
||||
COL(alloc_count_row, count_nflushes_ps, right, 10, title);
|
||||
col_count_nflushes_ps.str_val = "(#/sec)";
|
||||
|
||||
emitter_table_row(emitter, &alloc_count_row);
|
||||
|
||||
col_count_nmalloc_ps.type = emitter_type_uint64;
|
||||
col_count_ndalloc_ps.type = emitter_type_uint64;
|
||||
col_count_nrequests_ps.type = emitter_type_uint64;
|
||||
col_count_nfills_ps.type = emitter_type_uint64;
|
||||
col_count_nflushes_ps.type = emitter_type_uint64;
|
||||
|
||||
#define GET_AND_EMIT_ALLOC_STAT(small_or_large, name, valtype) \
|
||||
CTL_M2_GET("stats.arenas.0." #small_or_large "." #name, i, \
|
||||
|
|
@ -855,6 +869,12 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
|
|||
GET_AND_EMIT_ALLOC_STAT(small, nrequests, uint64)
|
||||
col_count_nrequests_ps.uint64_val =
|
||||
rate_per_second(col_count_nrequests.uint64_val, uptime);
|
||||
GET_AND_EMIT_ALLOC_STAT(small, nfills, uint64)
|
||||
col_count_nfills_ps.uint64_val =
|
||||
rate_per_second(col_count_nfills.uint64_val, uptime);
|
||||
GET_AND_EMIT_ALLOC_STAT(small, nflushes, uint64)
|
||||
col_count_nflushes_ps.uint64_val =
|
||||
rate_per_second(col_count_nflushes.uint64_val, uptime);
|
||||
|
||||
emitter_table_row(emitter, &alloc_count_row);
|
||||
emitter_json_object_end(emitter); /* Close "small". */
|
||||
|
|
@ -872,6 +892,12 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
|
|||
GET_AND_EMIT_ALLOC_STAT(large, nrequests, uint64)
|
||||
col_count_nrequests_ps.uint64_val =
|
||||
rate_per_second(col_count_nrequests.uint64_val, uptime);
|
||||
GET_AND_EMIT_ALLOC_STAT(large, nfills, uint64)
|
||||
col_count_nfills_ps.uint64_val =
|
||||
rate_per_second(col_count_nfills.uint64_val, uptime);
|
||||
GET_AND_EMIT_ALLOC_STAT(large, nflushes, uint64)
|
||||
col_count_nflushes_ps.uint64_val =
|
||||
rate_per_second(col_count_nflushes.uint64_val, uptime);
|
||||
|
||||
emitter_table_row(emitter, &alloc_count_row);
|
||||
emitter_json_object_end(emitter); /* Close "large". */
|
||||
|
|
@ -884,12 +910,18 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
|
|||
col_count_nmalloc.uint64_val = small_nmalloc + large_nmalloc;
|
||||
col_count_ndalloc.uint64_val = small_ndalloc + large_ndalloc;
|
||||
col_count_nrequests.uint64_val = small_nrequests + large_nrequests;
|
||||
col_count_nfills.uint64_val = small_nfills + large_nfills;
|
||||
col_count_nflushes.uint64_val = small_nflushes + large_nflushes;
|
||||
col_count_nmalloc_ps.uint64_val =
|
||||
rate_per_second(col_count_nmalloc.uint64_val, uptime);
|
||||
col_count_ndalloc_ps.uint64_val =
|
||||
rate_per_second(col_count_ndalloc.uint64_val, uptime);
|
||||
col_count_nrequests_ps.uint64_val =
|
||||
rate_per_second(col_count_nrequests.uint64_val, uptime);
|
||||
col_count_nfills_ps.uint64_val =
|
||||
rate_per_second(col_count_nfills.uint64_val, uptime);
|
||||
col_count_nflushes_ps.uint64_val =
|
||||
rate_per_second(col_count_nflushes.uint64_val, uptime);
|
||||
emitter_table_row(emitter, &alloc_count_row);
|
||||
|
||||
emitter_row_t mem_count_row;
|
||||
|
|
|
|||
|
|
@ -282,8 +282,8 @@ tcache_bin_flush_large(tsd_t *tsd, cache_bin_t *tbin, szind_t binind,
|
|||
}
|
||||
if (config_stats) {
|
||||
merged_stats = true;
|
||||
arena_stats_large_nrequests_add(tsd_tsdn(tsd),
|
||||
&tcache_arena->stats, binind,
|
||||
arena_stats_large_flush_nrequests_add(
|
||||
tsd_tsdn(tsd), &tcache_arena->stats, binind,
|
||||
tbin->tstats.nrequests);
|
||||
tbin->tstats.nrequests = 0;
|
||||
}
|
||||
|
|
@ -324,7 +324,7 @@ tcache_bin_flush_large(tsd_t *tsd, cache_bin_t *tbin, szind_t binind,
|
|||
* The flush loop didn't happen to flush to this thread's
|
||||
* arena, so the stats didn't get merged. Manually do so now.
|
||||
*/
|
||||
arena_stats_large_nrequests_add(tsd_tsdn(tsd),
|
||||
arena_stats_large_flush_nrequests_add(tsd_tsdn(tsd),
|
||||
&tcache_arena->stats, binind, tbin->tstats.nrequests);
|
||||
tbin->tstats.nrequests = 0;
|
||||
}
|
||||
|
|
@ -615,7 +615,7 @@ tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena) {
|
|||
|
||||
for (; i < nhbins; i++) {
|
||||
cache_bin_t *tbin = tcache_large_bin_get(tcache, i);
|
||||
arena_stats_large_nrequests_add(tsdn, &arena->stats, i,
|
||||
arena_stats_large_flush_nrequests_add(tsdn, &arena->stats, i,
|
||||
tbin->tstats.nrequests);
|
||||
tbin->tstats.nrequests = 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue