fix: flag to limit usm reuse based on memory usage

Host usm and device usm for igfx checks system memory usage.
Device usm for dgfx checks local memory usage.

If used memory is above limit threshold:
- no new allocations will be saved for reuse
- cleaner will use shorter hold time of 2 seconds
- cleaner will free all eligible allocations, regardless of async
deleter thread having work

Motivation: in case of gfx memory being full, making resident new
allocations will require evictions which leads to massive slowdown on
enqueue calls.
This change aims to minimize cases where extra memory usage from usm
reuse mechanism leads to above situation.

Related-To: NEO-6893, NEO-14160

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
Dominik Dabek
2025-03-26 14:09:38 +00:00
committed by Compute-Runtime-Automation
parent 5684eb0dca
commit 915d657420
18 changed files with 373 additions and 170 deletions

View File

@@ -389,13 +389,25 @@ uint32_t MemoryManager::getFirstContextIdForRootDevice(uint32_t rootDeviceIndex)
return 0;
}
void MemoryManager::initUsmReuseMaxSize() {
const auto totalSystemMemory = this->getSystemSharedMemory(0u);
auto fractionOfTotalMemoryForRecycling = 0.02;
void MemoryManager::initUsmReuseLimits() {
const auto systemSharedMemorySize = this->getSystemSharedMemory(0u);
auto fractionOfTotalMemoryForReuse = 0.02;
if (debugManager.flags.ExperimentalEnableHostAllocationCache.get() != -1) {
fractionOfTotalMemoryForRecycling = 0.01 * std::min(100, debugManager.flags.ExperimentalEnableHostAllocationCache.get());
fractionOfTotalMemoryForReuse = 0.01 * std::min(100, debugManager.flags.ExperimentalEnableHostAllocationCache.get());
}
this->maxAllocationsSavedForReuseSize = static_cast<size_t>(fractionOfTotalMemoryForRecycling * totalSystemMemory);
auto maxAllocationsSavedForReuseSize = static_cast<uint64_t>(fractionOfTotalMemoryForReuse * systemSharedMemorySize);
auto limitAllocationsReuseThreshold = std::numeric_limits<uint64_t>::max();
const auto limitFlagValue = debugManager.flags.ExperimentalUSMAllocationReuseLimitThreshold.get();
if (limitFlagValue != -1) {
if (limitFlagValue == 0) {
limitAllocationsReuseThreshold = std::numeric_limits<uint64_t>::max();
} else {
const auto fractionOfTotalMemoryToLimitReuse = limitFlagValue / 100.0;
limitAllocationsReuseThreshold = static_cast<uint64_t>(fractionOfTotalMemoryToLimitReuse * systemSharedMemorySize);
}
}
this->usmReuseInfo.init(maxAllocationsSavedForReuseSize, limitAllocationsReuseThreshold);
}
OsContext *MemoryManager::createAndRegisterOsContext(CommandStreamReceiver *commandStreamReceiver,