Skip to content

Commit f6235fd

Browse files
author
Nathan Ricci
committed
Refactored heuristic into static method. Style.
Remove extra define.
1 parent c677eae commit f6235fd

File tree

1 file changed

+70
-68
lines changed

1 file changed

+70
-68
lines changed

src/mono/mono/sgen/sgen-gc.c

Lines changed: 70 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@
155155
This should help weak consistency archs.
156156
*/
157157
#include "config.h"
158-
159158
#ifdef HAVE_SGEN_GC
160159

161160
#ifdef __MACH__
@@ -4091,89 +4090,92 @@ guint64 memory_pressure_gc_count = 0;
40914090
guint64 memory_pressure_iteration = 0;
40924091
guint64 memory_pressure_adds[MEM_PRESSURE_COUNT] = {0, 0, 0, 0};
40934092
guint64 memory_pressure_removes[MEM_PRESSURE_COUNT] = {0, 0, 0, 0}; // history of memory pressure removals
4094-
const unsigned min_memorypressure_budget = 4 * 1024 * 1024; // 4 MB
4093+
const unsigned min_memorypressure_budget = 4 * 1024 * 1024; // 4 MB
40954094

40964095
// Resets pressure accounting after a gen2 GC has occurred.
40974096
static void check_pressure_counts ()
40984097
{
4099-
if (memory_pressure_gc_count != sgen_gc_collection_count(GENERATION_OLD))
4100-
{
4101-
memory_pressure_gc_count = sgen_gc_collection_count(GENERATION_OLD);
4102-
memory_pressure_iteration++;
4098+
if (memory_pressure_gc_count != sgen_gc_collection_count(GENERATION_OLD)) {
4099+
memory_pressure_gc_count = sgen_gc_collection_count(GENERATION_OLD);
4100+
memory_pressure_iteration++;
41034101

4104-
guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
4102+
guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
41054103

4106-
memory_pressure_adds[p] = 0; // new pressure will be accumulated here
4107-
memory_pressure_removes[p] = 0;
4108-
}
4104+
memory_pressure_adds[p] = 0; // new pressure will be accumulated here
4105+
memory_pressure_removes[p] = 0;
4106+
}
41094107
}
41104108

41114109
void sgen_remove_memory_pressure (guint64 bytes_allocated)
41124110
{
4113-
check_pressure_counts();
4111+
check_pressure_counts();
41144112

4115-
guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
4113+
guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
41164114

4117-
mono_atomic_fetch_add_i64((gint64*)&memory_pressure_removes[p], bytes_allocated);
4115+
mono_atomic_fetch_add_i64((gint64*)&memory_pressure_removes[p], bytes_allocated);
41184116
}
41194117

4120-
void sgen_add_memory_pressure (guint64 bytes_allocated)
4118+
4119+
static gboolean pressure_check_heuristic (guint64 new_mem_value)
41214120
{
41224121

4123-
check_pressure_counts ();
4124-
4125-
guint p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
4126-
4127-
guint64 new_mem_value = mono_atomic_fetch_add_i64 ((gint64*)&memory_pressure_adds[p], bytes_allocated);
4128-
4129-
// AddMemoryPressure contains unrolled loops which depend on MEM_PRESSURE_COUNT
4130-
g_assert (MEM_PRESSURE_COUNT == 4);
4131-
4132-
guint64 add = memory_pressure_adds[0] + memory_pressure_adds[1] + memory_pressure_adds[2] + memory_pressure_adds[3] - memory_pressure_adds[p];
4133-
guint64 rem = memory_pressure_removes[0] + memory_pressure_removes[1] + memory_pressure_removes[2] + memory_pressure_removes[3] - memory_pressure_removes[p];
4134-
4135-
if (new_mem_value >= min_memorypressure_budget)
4136-
{
4137-
guint64 budget = min_memorypressure_budget;
4138-
4139-
if (memory_pressure_iteration >= MEM_PRESSURE_COUNT) // wait until we have enough data points
4140-
{
4141-
// Adjust according to effectiveness of GC
4142-
// Scale budget according to past memory_pressure_adds / memory_pressure_removes ratio
4143-
if (add >= rem * MAX_MEMORYPRESSURE_RATIO)
4144-
{
4145-
budget = min_memorypressure_budget * MAX_MEMORYPRESSURE_RATIO;
4146-
}
4147-
else if (add > rem)
4148-
{
4149-
g_assert (rem != 0);
4150-
4151-
// Avoid overflow by calculating addPressure / remPressure as fixed point (1 = 1024)
4152-
budget = (add * 1024 / rem) * budget / 1024;
4153-
}
4154-
}
4155-
4156-
// If still over budget, check current managed heap size
4157-
if (new_mem_value >= budget)
4158-
{
4159-
guint64 heap_over_3 = sgen_gc_info.heap_size_bytes / 3;
4160-
4161-
if (budget < heap_over_3) // Max
4162-
{
4163-
budget = heap_over_3;
4164-
}
4165-
4166-
if (new_mem_value >= budget)
4167-
{
4168-
// last check - if we would exceed 20% of GC "duty cycle", do not trigger GC at this time
4169-
if ((size_t)(mono_time_since_last_stw() + time_last) > (time_last * 5))
4170-
{
4171-
sgen_gc_collect (GENERATION_OLD);
4172-
check_pressure_counts ();
4122+
guint64 add = 0;
4123+
guint64 rem = 0;
4124+
4125+
for (gint i = 0; i < MEM_PRESSURE_COUNT; i++) {
4126+
add += memory_pressure_adds[i];
4127+
rem += memory_pressure_removes[i];
4128+
}
4129+
4130+
if (new_mem_value >= min_memorypressure_budget) {
4131+
guint64 budget = min_memorypressure_budget;
4132+
4133+
if (memory_pressure_iteration >= MEM_PRESSURE_COUNT) { // wait until we have enough data points
4134+
// Adjust according to effectiveness of GC
4135+
// Scale budget according to past memory_pressure_adds / memory_pressure_removes ratio
4136+
if (add >= rem * MAX_MEMORYPRESSURE_RATIO)
4137+
{
4138+
budget = min_memorypressure_budget * MAX_MEMORYPRESSURE_RATIO;
4139+
}
4140+
else if (add > rem)
4141+
{
4142+
g_assert (rem != 0);
4143+
// Avoid overflow by calculating addPressure / remPressure as fixed point (1 = 1024)
4144+
budget = (add * 1024 / rem) * budget / 1024;
4145+
}
4146+
}
4147+
4148+
// If still over budget, check current managed heap size
4149+
if (new_mem_value >= budget) {
4150+
guint64 heap_over_3 = sgen_gc_info.heap_size_bytes / 3;
4151+
4152+
if (budget < heap_over_3) {
4153+
budget = heap_over_3;
4154+
}
4155+
if (new_mem_value >= budget) {
4156+
// last check - if we would exceed 20% of GC "duty cycle", do not trigger GC at this time
4157+
if ((size_t)(mono_time_since_last_stw() + time_last) > (time_last * 5)) {
4158+
return TRUE;
4159+
}
4160+
}
41734161
}
4174-
}
4175-
}
4176-
}
4162+
}
4163+
4164+
return FALSE;
41774165
}
41784166

4179-
#endif /* HAVE_SGEN_GC */
4167+
void sgen_add_memory_pressure (guint64 bytes_allocated)
4168+
{
4169+
4170+
check_pressure_counts ();
4171+
4172+
guint p = memory_pressure_iteration % MEM_PRESSURE_COUNT;
4173+
4174+
guint64 new_mem_value = mono_atomic_fetch_add_i64 ((gint64*)&memory_pressure_adds[p], bytes_allocated);
4175+
4176+
if (pressure_check_heuristic(new_mem_value)) {
4177+
sgen_gc_collect (GENERATION_OLD);
4178+
check_pressure_counts ();
4179+
}
4180+
}
4181+
#endif /* HAVE_SGEN_GC */

0 commit comments

Comments
 (0)