Skip to content

Commit 2f9a79d

Browse files
committed
Tune collect_interval & sweep_mask settings
1 parent f458d0d commit 2f9a79d

File tree

3 files changed

+44
-39
lines changed

3 files changed

+44
-39
lines changed

src/array.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ static void array_resize_buffer(jl_array_t *a, size_t newlen, size_t oldlen, siz
551551
if (a->how == 2) {
552552
// already malloc'd - use realloc
553553
newdata = (char*)jl_gc_managed_realloc((char*)a->data - oldoffsnb, nbytes,
554-
oldnbytes+oldoffsnb, a->isaligned, a);
554+
oldnbytes+oldoffsnb, a->isaligned, (jl_value_t*)a);
555555
if (offs != a->offset) {
556556
memmove(&newdata[offsnb], &newdata[oldoffsnb], oldnbytes);
557557
}

src/gc.c

+41-37
Original file line numberDiff line numberDiff line change
@@ -979,18 +979,18 @@ static inline void *__pool_alloc(pool_t* p, int osize, int end_offset)
979979
jl_gc_collect();
980980
allocd_bytes += osize;
981981
}
982-
983-
if (__unlikely(!p->freelist)) {
982+
v = p->freelist;
983+
if (__unlikely(!v)) {
984984
add_page(p);
985+
v = p->freelist;
985986
}
986-
v = p->freelist;
987+
end = (gcval_t*)&(GC_PAGE_DATA(v)[end_offset]);
987988
p->nfree--;
988989
p->allocd = 1;
989-
end = (gcval_t*)&(GC_PAGE_DATA(v)[end_offset]);
990-
if (__unlikely((v == end) | (!p->linear))) {
991-
_update_freelist(p, v->next);
992-
} else {
990+
if (p->linear && v != end) {
993991
p->freelist = (gcval_t*)((char*)v + osize);
992+
} else {
993+
_update_freelist(p, v->next);
994994
}
995995
v->flags = 0;
996996
return v;
@@ -1020,7 +1020,7 @@ static const int sizeclasses[N_POOLS] = {
10201020

10211021
static int szclass(size_t sz)
10221022
{
1023-
#ifndef _P64
1023+
#ifndef _P64
10241024
if (sz <= 8) return 0;
10251025
#endif
10261026
if (sz <= 56) return ((sz+3)/4) - 2;
@@ -1102,29 +1102,29 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
11021102
freedall = 1;
11031103
old_nfree += pg->nfree;
11041104
prev_pfl = pfl;
1105+
int pg_gc_bits = 0;
11051106
if (pg->gc_bits == GC_MARKED) {
11061107
// skip
11071108
if (prev_sweep_mask == GC_MARKED_NOESC && sweep_mask == GC_MARKED_NOESC && !pg->allocd) {
1108-
pg_skpd++;
1109-
freedall = 0;
11101109
if (pg->fl_begin_offset != (uint16_t)-1) {
11111110
*pfl = (gcval_t*)PAGE_PFL_BEG(pg);
11121111
pfl = prev_pfl = PAGE_PFL_END(pg);
11131112
}
1113+
pg_skpd++;
1114+
freedall = 0;
1115+
pg_gc_bits = GC_MARKED;
11141116
goto free_page;
11151117
}
1116-
pg->allocd = 0;
11171118
}
11181119
else if(pg->gc_bits == GC_CLEAN) {
1119-
pg->allocd = 0;
11201120
goto free_page;
11211121
}
11221122
if (sweep_mask == GC_MARKED)
11231123
pg->nmarked = 0;
11241124
int pg_nfree = 0;
11251125
gcval_t **pfl_begin = NULL;
1126+
int obj_i = 0;
11261127
while ((char*)v <= lim) {
1127-
int obj_i = ((uintptr_t)v - (uintptr_t)data)/8;
11281128
// we can encouter a queued value at this point
11291129
// if a write barrier was moved back between two
11301130
// sweeping increments TODO
@@ -1136,23 +1136,27 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
11361136
pfl = &v->next;
11371137
pfl_begin = pfl_begin ? pfl_begin : pfl;
11381138
pg_nfree++;
1139-
ages[obj_i/4] &= ~(3 << (obj_i % 4)*2);
1139+
age = 0;
11401140
}
11411141
else {
11421142
if (age >= PROMOTE_AGE) {
11431143
if (sweep_mask == GC_MARKED || bits == GC_MARKED_NOESC) {
11441144
gc_bits(v) = GC_QUEUED;
1145+
} else {
1146+
pg_gc_bits = GC_MARKED;
11451147
}
11461148
}
11471149
else if ((sweep_mask & bits) == sweep_mask) {
11481150
gc_bits(v) = GC_CLEAN;
1151+
} else {
1152+
pg_gc_bits = GC_MARKED;
11491153
}
1150-
11511154
inc_sat(age, PROMOTE_AGE);
1152-
ages[obj_i/4] &= ~(3 << sh);
1153-
ages[obj_i/4] |= age << sh;
11541155
freedall = 0;
11551156
}
1157+
ages[obj_i/4] &= ~(3 << sh);
1158+
ages[obj_i/4] |= age << sh;
1159+
obj_i++;
11561160
v = (gcval_t*)((char*)v + osize);
11571161
}
11581162

@@ -1161,6 +1165,7 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
11611165

11621166
pg->nfree = pg_nfree;
11631167
page_done++;
1168+
pg->allocd = 0;
11641169
free_page:
11651170
if (sweep_mask == GC_MARKED)
11661171
pg->nmarked = 0;
@@ -1192,7 +1197,7 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
11921197
nfree += obj_per_page;
11931198
}
11941199
else {
1195-
pg->gc_bits = GC_MARKED;
1200+
pg->gc_bits = pg_gc_bits;
11961201
pg->linear = 0;
11971202
nfree += pg->nfree;
11981203
}
@@ -1831,7 +1836,6 @@ static void clear_mark(int bits)
18311836
{
18321837
size_t i;
18331838
pool_t* pool;
1834-
gcpage_t* pg;
18351839
gcval_t* pv;
18361840
if (!verifying) {
18371841
for(int i = 0; i < 4; i++)
@@ -2040,7 +2044,7 @@ void jl_gc_collect(void)
20402044
JL_SIGATOMIC_BEGIN();
20412045
uint64_t t0 = jl_hrtime();
20422046
int recollect = 0;
2043-
#if defined(GC_TIME) || defined(GC_FINAL_STATS)
2047+
#if defined(GC_TIME)
20442048
int wb_activations = mark_sp - saved_mark_sp;
20452049
#endif
20462050
if (!sweeping) {
@@ -2111,9 +2115,10 @@ void jl_gc_collect(void)
21112115
total_mark_time += mark_pause;
21122116
#endif
21132117
}
2114-
//#ifdef GC_TIME
2115-
int64_t bonus = -1, SAVE = -1, SAVE2 = -1, SAVE3 = -1, pct = -1, est_fb = -1;
2116-
//#endif
2118+
#ifdef GC_TIME
2119+
int64_t bonus = -1, SAVE = -1, SAVE2 = -1, SAVE3 = -1, pct = -1;
2120+
#endif
2121+
int64_t estimate_freed = -1;
21172122

21182123
#if defined(GC_TIME) || defined(GC_FINAL_STATS)
21192124
uint64_t post_time = 0, finalize_time = 0;
@@ -2133,7 +2138,7 @@ void jl_gc_collect(void)
21332138
#ifdef GC_TIME
21342139
post_time = jl_hrtime() - post_time;
21352140
#endif
2136-
est_fb = live_bytes - scanned_bytes - perm_scanned_bytes + actual_allocd;
2141+
estimate_freed = live_bytes - scanned_bytes - perm_scanned_bytes + actual_allocd;
21372142

21382143
#ifdef GC_VERIFY
21392144
//gc_verify_track();
@@ -2151,15 +2156,13 @@ void jl_gc_collect(void)
21512156
total_allocd_bytes += allocd_bytes_since_sweep;
21522157

21532158
// 5. next collection decision
2154-
if ((est_fb <= 1024 || est_fb < (7*(actual_allocd/10))) && n_pause > 1) {
2155-
if (prev_sweep_mask == GC_MARKED) {
2156-
if (collect_interval <= 2*(max_collect_interval/5)) {
2157-
collect_interval = 5*(collect_interval/2);
2158-
}
2159-
sweep_mask = GC_MARKED;
2160-
} else {
2161-
sweep_mask = GC_MARKED;
2162-
recollect = 1;
2159+
if ((estimate_freed <= 1024 || estimate_freed < (7*(actual_allocd/10))) && n_pause > 1) {
2160+
if (collect_interval <= 2*(max_collect_interval/5)) {
2161+
collect_interval = 5*(collect_interval/2);
2162+
}
2163+
sweep_mask = GC_MARKED;
2164+
if (prev_sweep_mask != GC_MARKED) {
2165+
//recollect = 1; // TODO enable this
21632166
}
21642167
} else {
21652168
collect_interval = default_collect_interval;
@@ -2177,7 +2180,6 @@ void jl_gc_collect(void)
21772180
// sweeping is over
21782181
// 6. if it is a quick sweep, put back the remembered objects in queued state
21792182
// so that we don't trigger the barrier again on them.
2180-
//jl_printf(JL_STDOUT, "SSB PSB %d %d\n", S_sb, S_psb);
21812183
if (sweep_mask == GC_MARKED_NOESC) {
21822184
for (int i = 0; i < remset->len; i++) {
21832185
gc_bits(((uintptr_t)remset->items[i] & ~(uintptr_t)1)) = GC_QUEUED;
@@ -2198,8 +2200,8 @@ void jl_gc_collect(void)
21982200
if (sweep_mask == GC_MARKED) {
21992201
tasks.len = 0;
22002202
}
2201-
SAVE2 = freed_bytes;
22022203
#ifdef GC_TIME
2204+
SAVE2 = freed_bytes;
22032205
SAVE3 = allocd_bytes_since_sweep;
22042206
pct = actual_allocd ? (freed_bytes*100)/actual_allocd : -1;
22052207
#endif
@@ -2228,7 +2230,7 @@ void jl_gc_collect(void)
22282230
total_fin_time += finalize_time + post_time;
22292231
#endif
22302232
#ifdef GC_TIME
2231-
JL_PRINTF(JL_STDOUT, "GC sweep pause %.2f ms live %ld kB (freed %d kB EST %d kB [error %d] = %d%% of allocd %d kB b/r %ld/%ld) (%.2f ms in post_mark, %.2f ms in %d fin) (marked in %d inc) mask %d | next in %d kB\n", NS2MS(sweep_pause), live_bytes/1024, SAVE2/1024, est_fb/1024, (SAVE2 - est_fb), pct, SAVE3/1024, bonus/1024, SAVE/1024, NS2MS(post_time), NS2MS(finalize_time), n_finalized, inc_count, sweep_mask, -allocd_bytes/1024);
2233+
JL_PRINTF(JL_STDOUT, "GC sweep pause %.2f ms live %ld kB (freed %d kB EST %d kB [error %d] = %d%% of allocd %d kB b/r %ld/%ld) (%.2f ms in post_mark, %.2f ms in %d fin) (marked in %d inc) mask %d | next in %d kB\n", NS2MS(sweep_pause), live_bytes/1024, SAVE2/1024, estimate_freed/1024, (SAVE2 - estimate_freed), pct, SAVE3/1024, bonus/1024, SAVE/1024, NS2MS(post_time), NS2MS(finalize_time), n_finalized, inc_count, sweep_mask, -allocd_bytes/1024);
22322234
#endif
22332235
}
22342236
n_pause++;
@@ -2239,10 +2241,12 @@ void jl_gc_collect(void)
22392241
#endif
22402242
JL_SIGATOMIC_END();
22412243
jl_in_gc = 0;
2242-
if (est_fb != SAVE2) {
2244+
#ifdef GC_TIME
2245+
if (estimate_freed != SAVE2) {
22432246
// this should not happen but it does
22442247
// mostly because of gc_counted_* allocations
22452248
}
2249+
#endif
22462250
if (recollect)
22472251
jl_gc_collect();
22482252
}

test/perf/perfcomp.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ end
1111
function main()
1212
baseline = readperf(open(ARGS[1]))
1313
torun = length(ARGS) > 1 ? ARGS[2] : "all"
14-
io,p = open(`make -s $torun`, "r")
14+
e = haskey(ENV,"J") ? "JULIA_EXECUTABLE=$(ENV["J"])" : ""
15+
io,p = open(`make $e -s $torun`, "r")
1516
newp = readperf(io)
1617

1718
names = sort(intersect(keys(baseline),keys(newp)))

0 commit comments

Comments
 (0)