Skip to content

Commit

Permalink
Adding Concurrent Mark timing stats in ConcurrentPhaseStatsBase, and …
Browse files Browse the repository at this point in the history
…additional flags for heap resizing

This change introduces several flags which are used to keep track of Concurrent marking work timing/cost.
This change also introduces a handful of flags which can be used by the GC to improve heap resizing.

- `_concurrentMarkProcessStartTime` keeps track of the cpu time for a concurrent mark increment
- Added additional flags for heap expansion and contraction.
- Added `MM_HeapSizingData`. This struct keeps track of several key characteristics that can be used by a GC to resize the heap
- changed `heapExpansionGCTimeThreshold` and `heapContractionGCTimeThreshold` to `MM_UserSpecifiedParameterUDATA`. Renamed the fields to `heapExpansionGCRatioThreshold` and `heapContractionGCRatioThreshold` respectively. Doing this allows each GC policy to configure their own defaults.
- `dnssExpectedTimeRatioMaximum` and `dnssExpectedTimeRatioMinimum` has been changed in the same way as described for `heapExpansionGCTimeThreshold`
- Introduction of `tarokTargetMaxPauseTime`. This will serve as the default pause time target for certain GC policies in which a target pause time will be used
- `reportHeapResizeAttempt()` now takes a memoryType param. This allows GC policies which are resizing logical spaces to print a `heap-resize` line for those logical spaces
- Introduced several tracepoints

Mostly unrelated to the main work in this PR, the following utility function has been added
- `MM_Math::weightedAverage()` for doubles has been added

This PR does not contain any functional/behavioural changes to the GC

Finally, a follow up PR should be performed, which does the following:
- `Trc_MM_MemorySubSpaceTarok_calculateExpandSize_Exit1` should be made obsolete
- `Trc_MM_MemorySubSpaceTarok_calculateTargetContractSize_Entry` should be made obsolete
- `dnssExpectedTimeRatioMaximum/Minimum` should be removed, while `dnssExpectedRatioMaximum/Minimum` should be kept
- `heapExpansionGCTimeThreshold` and `heapContractionGCTimeThreshold` should be removed, and `heapExpansionGCRatioThreshold` and `heapContractionGCRatioThreshold` should be kept.

Signed-off-by: Cedric Hansen <cedric.hansen@ibm.com>
  • Loading branch information
cedrichansen committed Sep 13, 2021
1 parent fa7d68b commit b6dbaee
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 33 deletions.
42 changes: 38 additions & 4 deletions gc/base/GCExtensionsBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,25 @@ class MM_UserSpecifiedParameterUDATA {
}
};

class MM_UserSpecifiedParameterDouble {
/* Data Members */
private:
protected:
public:
bool _wasSpecified; /**< True if this parameter was specified by the user, false means it is undefined */
double _valueSpecified; /**< The value specified by the user or undefined in _wasSpecified is false */

/* Member Functions */
private:
protected:
public:
MM_UserSpecifiedParameterDouble()
: _wasSpecified(false)
, _valueSpecified(0.0)
{
}
};

class MM_UserSpecifiedParameterBool {
/* Data Members */
private:
Expand Down Expand Up @@ -372,8 +391,12 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
uintptr_t heapFreeMinimumRatioMultiplier;
uintptr_t heapFreeMaximumRatioDivisor;
uintptr_t heapFreeMaximumRatioMultiplier;
uintptr_t heapExpansionGCTimeThreshold; /**< max percentage of time spent in gc before expansion */
uintptr_t heapContractionGCTimeThreshold; /**< min percentage of time spent in gc before contraction */
uintptr_t heapExpansionGCTimeThreshold; /**< max percentage of time spent in gc before expansion - TO BE REMOVED IN FAVOUR OF `heapExpansionGCRatioThreshold` */
uintptr_t heapContractionGCTimeThreshold; /**< min percentage of time spent in gc before contraction - TO BE REMOVED IN FAVOUR OF `heapContractionGCRatioThreshold` */

MM_UserSpecifiedParameterUDATA heapExpansionGCRatioThreshold; /**< max percentage of time spent in gc before expansion */
MM_UserSpecifiedParameterUDATA heapContractionGCRatioThreshold; /**< min percentage of time spent in gc before contraction */

uintptr_t heapExpansionStabilizationCount; /**< GC count required before the heap is allowed to expand due to excessvie time after last heap expansion */
uintptr_t heapContractionStabilizationCount; /**< GC count required before the heap is allowed to contract due to excessvie time after last heap expansion */

Expand Down Expand Up @@ -505,8 +528,13 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
bool dynamicNewSpaceSizing;
bool debugDynamicNewSpaceSizing;
bool dnssAvoidMovingObjects;
double dnssExpectedTimeRatioMinimum;
double dnssExpectedTimeRatioMaximum;

double dnssExpectedTimeRatioMinimum; /**< TO BE REMOVED IN FAVOUR OF `dnssExpectedRatioMinimum` - When the gc ratio for new/nursery space is below this value, new/nursery space should contract */
double dnssExpectedTimeRatioMaximum; /**< TO BE REMOVED IN FAVOUR OF `dnssExpectedRatioMaximum` - When the gc ratio for new/nursery space is above this value, new/nursery space should expand */

MM_UserSpecifiedParameterDouble dnssExpectedRatioMinimum; /**< When the gc ratio for new/nursery space is below this value, new/nursery space should contract */
MM_UserSpecifiedParameterDouble dnssExpectedRatioMaximum; /**< When the gc ratio for new/nursery space is above this value, new/nursery space should expand */

double dnssWeightedTimeRatioFactorIncreaseSmall;
double dnssWeightedTimeRatioFactorIncreaseMedium;
double dnssWeightedTimeRatioFactorIncreaseLarge;
Expand Down Expand Up @@ -787,6 +815,7 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
};
ReserveRegions tarokReserveRegionsFromCollectionSet;
bool tarokEnableRecoverRegionTailsAfterSweep; /**< Enable recovering region tail during post sweep of GMP */
uintptr_t tarokTargetMaxPauseTime; /**< An optional, user specified soft max pause time for PGC's in balanced GC*/
#if defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD)
bool _isConcurrentCopyForward;
#endif
Expand Down Expand Up @@ -1488,6 +1517,8 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
, heapFreeMaximumRatioMultiplier(60)
, heapExpansionGCTimeThreshold(13)
, heapContractionGCTimeThreshold(5)
, heapExpansionGCRatioThreshold()
, heapContractionGCRatioThreshold()
, heapExpansionStabilizationCount(0)
, heapContractionStabilizationCount(3)
, heapSizeStartupHintConservativeFactor((float)0.7)
Expand Down Expand Up @@ -1602,6 +1633,8 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
, dnssAvoidMovingObjects(true)
, dnssExpectedTimeRatioMinimum(0.01)
, dnssExpectedTimeRatioMaximum(0.05)
, dnssExpectedRatioMinimum()
, dnssExpectedRatioMaximum()
, dnssWeightedTimeRatioFactorIncreaseSmall(0.2)
, dnssWeightedTimeRatioFactorIncreaseMedium(0.35)
, dnssWeightedTimeRatioFactorIncreaseLarge(0.5)
Expand Down Expand Up @@ -1812,6 +1845,7 @@ class MM_GCExtensionsBase : public MM_BaseVirtual {
, tarokEnableCopyForwardHybrid(true)
, tarokReserveRegionsFromCollectionSet(RESERVE_REGIONS_NO)
, tarokEnableRecoverRegionTailsAfterSweep(false)
, tarokTargetMaxPauseTime(200)
#if defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD)
, _isConcurrentCopyForward(false)
#endif /* defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD) */
Expand Down
10 changes: 10 additions & 0 deletions gc/base/Math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,13 @@ MM_Math::weightedAverage(float currentAverage, float newValue, float weight)
{
return ((currentAverage) * weight) + ((newValue) * ((float)1.0 - weight));
}

/**
* Return the weighted average through combining the new value to the current value.
* @return the weighted average of the combined parameters.
*/
double
MM_Math::weightedAverage(double currentAverage, double newValue, double weight)
{
return ((currentAverage) * weight) + ((newValue) * ((double)1.0 - weight));
}
2 changes: 2 additions & 0 deletions gc/base/Math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class MM_Math

static float weightedAverage(float currentAverage, float newValue, float weight);

static double weightedAverage(double currentAverage, double newValue, double weight);

/* Round value up */
static MMINLINE uintptr_t roundToCeiling(uintptr_t granularity, uintptr_t number) {
return number + ((number % granularity) ? (granularity - (number % granularity)) : 0);
Expand Down
4 changes: 2 additions & 2 deletions gc/base/MemoryPoolLargeObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ MM_MemoryPoolLargeObjects::resizeLOA(MM_EnvironmentBase* env)
Trc_MM_LOAResize_resizeLOA4(env->getLanguageVMThread(), oldLOARatio, _currentLOARatio);

_extensions->heap->getResizeStats()->setLastLoaResizeReason(LOA_CONTRACT_MIN_SOA);
_memorySubSpace->reportHeapResizeAttempt(env, spaceDelta , HEAP_LOA_CONTRACT);
_memorySubSpace->reportHeapResizeAttempt(env, spaceDelta , HEAP_LOA_CONTRACT, _memorySubSpace->getTypeFlags());

/* Verify all pools in valid state after we are done */
assume0(_memoryPoolSmallObjects->isMemoryPoolValid(env, true));
Expand Down Expand Up @@ -461,7 +461,7 @@ MM_MemoryPoolLargeObjects::resetLOASize(MM_EnvironmentBase* env, double newLOARa

Trc_MM_LOAResize_resetLOASize(env->getLanguageVMThread(), _currentLOABase);

_memorySubSpace->reportHeapResizeAttempt(env, resizeSize , resizeType);
_memorySubSpace->reportHeapResizeAttempt(env, resizeSize , resizeType, _memorySubSpace->getTypeFlags());
}
}

Expand Down
26 changes: 13 additions & 13 deletions gc/base/MemorySubSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,34 +156,34 @@ MM_MemorySubSpace::reportSystemGCEnd(MM_EnvironmentBase* env)
* Report the start of a heap expansion event through hooks.
*/
void
MM_MemorySubSpace::reportHeapResizeAttempt(MM_EnvironmentBase* env, uintptr_t amount, uintptr_t type)
MM_MemorySubSpace::reportHeapResizeAttempt(MM_EnvironmentBase* env, uintptr_t amount, uintptr_t resizeType, uintptr_t memoryType)
{
OMRPORT_ACCESS_FROM_ENVIRONMENT(env);

MM_HeapResizeStats *resizeStats = _extensions->heap->getResizeStats();

uint64_t resizeTime = (type == HEAP_EXPAND)
uint64_t resizeTime = (resizeType == HEAP_EXPAND)
? resizeStats->getLastExpandTime()
: resizeStats->getLastContractTime();

uint32_t gcTimeRatio = 0;

if (HEAP_EXPAND == type) {
if (HEAP_EXPAND == resizeType) {
gcTimeRatio = resizeStats->getRatioExpandPercentage();
} else if (HEAP_CONTRACT == type) {
} else if (HEAP_CONTRACT == resizeType) {
gcTimeRatio = resizeStats->getRatioContractPercentage();
}

uintptr_t reason = 0;

if (HEAP_EXPAND == type) {
if (HEAP_EXPAND == resizeType) {
reason = (uintptr_t)resizeStats->getLastExpandReason();
} else if (HEAP_CONTRACT == type) {
} else if (HEAP_CONTRACT == resizeType) {
reason = (uintptr_t)resizeStats->getLastContractReason();
} else if (HEAP_LOA_EXPAND == type) {
} else if (HEAP_LOA_EXPAND == resizeType) {
reason = (uintptr_t)resizeStats->getLastLoaResizeReason();
Assert_MM_true(reason <= LOA_EXPAND_LAST_RESIZE_REASON);
} else if (HEAP_LOA_CONTRACT == type) {
} else if (HEAP_LOA_CONTRACT == resizeType) {
reason = (uintptr_t)resizeStats->getLastLoaResizeReason();
Assert_MM_true(reason > LOA_EXPAND_LAST_RESIZE_REASON);
}
Expand All @@ -193,8 +193,8 @@ MM_MemorySubSpace::reportHeapResizeAttempt(MM_EnvironmentBase* env, uintptr_t am
env->getOmrVMThread(),
omrtime_hires_clock(),
J9HOOK_MM_PRIVATE_HEAP_RESIZE,
type,
getTypeFlags(),
resizeType,
memoryType,
gcTimeRatio,
amount,
getActiveMemorySize(),
Expand Down Expand Up @@ -1282,7 +1282,7 @@ MM_MemorySubSpace::expand(MM_EnvironmentBase* env, uintptr_t expandSize)
timeEnd = omrtime_hires_clock();
_extensions->heap->getResizeStats()->setLastExpandTime(timeEnd - timeStart);

reportHeapResizeAttempt(env, actualExpandAmount, HEAP_EXPAND);
reportHeapResizeAttempt(env, actualExpandAmount, HEAP_EXPAND, getTypeFlags());

Trc_MM_MemorySubSpace_expand_Exit2(env->getLanguageVMThread(), actualExpandAmount);
return actualExpandAmount;
Expand Down Expand Up @@ -1314,7 +1314,7 @@ MM_MemorySubSpace::contract(MM_EnvironmentBase* env, uintptr_t contractSize)
timeEnd = omrtime_hires_clock();
_extensions->heap->getResizeStats()->setLastContractTime(timeEnd - timeStart);

reportHeapResizeAttempt(env, actualContractAmount, HEAP_CONTRACT);
reportHeapResizeAttempt(env, actualContractAmount, HEAP_CONTRACT, getTypeFlags());

Trc_MM_MemorySubSpace_contract_Exit(env->getLanguageVMThread(), actualContractAmount);
return actualContractAmount;
Expand Down Expand Up @@ -1882,7 +1882,7 @@ MM_MemorySubSpace::runEnqueuedCounterBalancing(MM_EnvironmentBase* env)
_extensions->heap->getResizeStats()->setLastExpandTime(timeEnd - timeStart);

if (0 != expandSize) {
reportHeapResizeAttempt(env, expandSize, HEAP_EXPAND);
reportHeapResizeAttempt(env, expandSize, HEAP_EXPAND, getTypeFlags());
}

break;
Expand Down
4 changes: 2 additions & 2 deletions gc/base/MemorySubSpace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ friend class GC_MemorySubSpaceRegionIterator;

void reportSystemGCStart(MM_EnvironmentBase *env, uint32_t gcCode);
void reportSystemGCEnd(MM_EnvironmentBase *env);
void reportHeapResizeAttempt(MM_EnvironmentBase *env, uintptr_t amount, uintptr_t type);
void reportHeapResizeAttempt(MM_EnvironmentBase *env, uintptr_t amount, uintptr_t resizeType, uintptr_t memoryType);
void reportPercolateCollect(MM_EnvironmentBase *env);

bool initialize(MM_EnvironmentBase *env);
Expand Down Expand Up @@ -330,7 +330,7 @@ friend class GC_MemorySubSpaceRegionIterator;
*/
MM_MemorySubSpace *getTopLevelMemorySubSpace(uintptr_t typeFlags);

MMINLINE uintptr_t getTypeFlags() { return _memoryType; }
MMINLINE uintptr_t getTypeFlags() { return _memoryType; }
MMINLINE uint32_t getObjectFlags() { return _objectFlags; }

virtual bool isActive();
Expand Down
14 changes: 7 additions & 7 deletions gc/base/MemorySubSpaceSemiSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ MM_MemorySubSpaceSemiSpace::checkSubSpaceMemoryPostCollectResize(MM_EnvironmentB
_lastGCEndTime = scavenger->_cycleTimes.cycleEnd;

if (doDynamicNewSpaceSizing) {
double expectedTimeRatio = (extensions->dnssExpectedTimeRatioMaximum + extensions->dnssExpectedTimeRatioMinimum) / 2;
double expectedTimeRatio = (extensions->dnssExpectedRatioMaximum._valueSpecified + extensions->dnssExpectedRatioMinimum._valueSpecified) / 2;

/* Find the ratio of time to scavenge versus the interval time since the last scavenge */
double timeRatio = (double)((int64_t)scavengeTime) / (double)((int64_t) intervalTime);
Expand Down Expand Up @@ -919,9 +919,9 @@ MM_MemorySubSpaceSemiSpace::checkSubSpaceMemoryPostCollectResize(MM_EnvironmentB
* calculating the new average
*/
double weight;
if (timeRatio > _averageScavengeTimeRatio) {
if (timeRatio > expectedTimeRatio) {
if (timeRatio > extensions->dnssExpectedTimeRatioMaximum) {
if(timeRatio > _averageScavengeTimeRatio) {
if(timeRatio > expectedTimeRatio) {
if(timeRatio > extensions->dnssExpectedRatioMaximum._valueSpecified) {
weight = extensions->dnssWeightedTimeRatioFactorIncreaseLarge;
} else {
weight = extensions->dnssWeightedTimeRatioFactorIncreaseMedium;
Expand All @@ -941,7 +941,7 @@ MM_MemorySubSpaceSemiSpace::checkSubSpaceMemoryPostCollectResize(MM_EnvironmentB
}

/* If the average scavenge to interval ratio is greater than the maximum, try to expand */
if ((_averageScavengeTimeRatio > extensions->dnssExpectedTimeRatioMaximum)
if((_averageScavengeTimeRatio > extensions->dnssExpectedRatioMaximum._valueSpecified)
&& (NULL != _physicalSubArena) && _physicalSubArena->canExpand(env) && (maxExpansionInSpace(env) != 0)) {

/* Try to reach 50% of the expected time ratio through expansion */
Expand Down Expand Up @@ -975,11 +975,11 @@ MM_MemorySubSpaceSemiSpace::checkSubSpaceMemoryPostCollectResize(MM_EnvironmentB
uintptr_t softMxForNursery = extensions->heap->getActualSoftMxSize(env, MEMORY_TYPE_NEW);

if ((NULL != _physicalSubArena) && _physicalSubArena->canContract(env) && (maxContractionInSpace(env) != 0)) {
if (_averageScavengeTimeRatio < extensions->dnssExpectedTimeRatioMinimum) {
if (_averageScavengeTimeRatio < extensions->dnssExpectedRatioMinimum._valueSpecified) {
/* If the average scavenge to interval ratio is less than the minimum, try to contract */

/* Try to reach 200% of the expected minimum time ratio through contraction */
double desiredContractionFactor = OMR_MIN(extensions->dnssExpectedTimeRatioMinimum * 2, expectedTimeRatio);
double desiredContractionFactor = OMR_MIN(extensions->dnssExpectedRatioMinimum._valueSpecified * 2, expectedTimeRatio);
desiredContractionFactor = desiredContractionFactor - _averageScavengeTimeRatio;

double adjustedContractionFactor = desiredContractionFactor;
Expand Down
10 changes: 5 additions & 5 deletions gc/base/MemorySubSpaceUniSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ MM_MemorySubSpaceUniSpace::checkForRatioExpand(MM_EnvironmentBase *env, uintptr_
}

/* Is too much time is being spent in GC? */
if (gcPercentage < _extensions->heapExpansionGCTimeThreshold) {
if (gcPercentage < _extensions->heapExpansionGCRatioThreshold._valueSpecified) {
Trc_MM_MemorySubSpaceUniSpace_checkForRatioExpand_Exit2(env->getLanguageVMThread(), gcPercentage);
return 0;
} else {
Expand Down Expand Up @@ -660,10 +660,10 @@ MM_MemorySubSpaceUniSpace::checkForRatioContract(MM_EnvironmentBase *env)
gcPercentage = _extensions->getGlobalCollector()->getGCTimePercentage(env);
}

/* If we are spending less than extensions->heapContractionGCTimeThreshold of
/* If we are spending less than extensions->heapContractionGCRatioThreshold of
* our time in gc then we should attempt to shrink the heap
*/
if (gcPercentage > 0 && gcPercentage < _extensions->heapContractionGCTimeThreshold) {
if (gcPercentage > 0 && gcPercentage < _extensions->heapContractionGCRatioThreshold._valueSpecified) {
Trc_MM_MemorySubSpaceUniSpace_checkForRatioContract_Exit1(env->getLanguageVMThread(), gcPercentage);
return true;
} else {
Expand Down Expand Up @@ -706,7 +706,7 @@ MM_MemorySubSpaceUniSpace::getHeapFreeMaximumHeuristicMultiplier(MM_EnvironmentB
gcPercentage = _extensions->getGlobalCollector()->getGCTimePercentage(env);
}

uintptr_t expectedGcPercentage = (_extensions->heapContractionGCTimeThreshold + _extensions->heapExpansionGCTimeThreshold) / 2;
uintptr_t expectedGcPercentage = (_extensions->heapContractionGCRatioThreshold._valueSpecified + _extensions->heapExpansionGCRatioThreshold._valueSpecified) / 2;
uintptr_t gcRatio = gcPercentage / expectedGcPercentage;
uintptr_t freeMaxMultiplier = OMR_MIN(_extensions->heapFreeMaximumRatioMultiplier + 6 * gcRatio * gcRatio, _extensions->heapFreeMaximumRatioDivisor);

Expand All @@ -726,7 +726,7 @@ MM_MemorySubSpaceUniSpace::getHeapFreeMinimumHeuristicMultiplier(MM_EnvironmentB
gcPercentage = _extensions->getGlobalCollector()->getGCTimePercentage(env);
}

uintptr_t expectedGcPercentage = (_extensions->heapContractionGCTimeThreshold + _extensions->heapExpansionGCTimeThreshold) / 2;
uintptr_t expectedGcPercentage = (_extensions->heapContractionGCRatioThreshold._valueSpecified + _extensions->heapExpansionGCRatioThreshold._valueSpecified) / 2;
uintptr_t gcRatio = gcPercentage / expectedGcPercentage;
uintptr_t freeMinMultiplier = OMR_MIN(_extensions->heapFreeMinimumRatioMultiplier + 1 * gcRatio * gcRatio, _extensions->heapFreeMinimumRatioDivisor - 5);

Expand Down
8 changes: 8 additions & 0 deletions gc/base/gcutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ getContractReasonAsString(ContractReason reason)
return "insufficient time being spent in gc";
case FREE_SPACE_GREATER_MAXF:
return "excess free space following gc";
case FREE_SPACE_HIGH_OR_GC_LOW:
return "insufficient time spent in gc, or excess of free space";
case EDEN_CONTRACTING:
return "gc overhead too low, or target pause time not satisfied";
case SCAV_RATIO_TOO_LOW:
return "insufficient time being spent scavenging";
case SATISFY_EXPAND:
Expand Down Expand Up @@ -211,6 +215,10 @@ getExpandReasonAsString(ExpandReason reason)
return "insufficient free space following gc";
case SCAV_RATIO_TOO_HIGH:
return "excessive time being spent scavenging";
case FREE_SPACE_LOW_OR_GC_HIGH:
return "free space too low or gc ratio too high";
case EDEN_EXPANDING:
return "gc overhead too high";
case SATISFY_COLLECTOR:
return "continue current collection";
case EXPAND_DESPERATE:
Expand Down
Loading

0 comments on commit b6dbaee

Please sign in to comment.