fix: move host usm reuse max size to mem manager

Intialize value on memory manager creation.

Related-To: NEO-6893

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
Dominik Dabek
2025-03-21 11:07:58 +00:00
committed by Compute-Runtime-Automation
parent 54cb0e24f8
commit 6e998fc3c1
9 changed files with 67 additions and 48 deletions

View File

@@ -90,6 +90,8 @@ bool ExecutionEnvironment::initializeMemoryManager() {
} break;
}
memoryManager->initUsmReuseMaxSize();
return memoryManager->isInitialized();
}

View File

@@ -389,6 +389,15 @@ uint32_t MemoryManager::getFirstContextIdForRootDevice(uint32_t rootDeviceIndex)
return 0;
}
void MemoryManager::initUsmReuseMaxSize() {
const auto totalSystemMemory = this->getSystemSharedMemory(0u);
auto fractionOfTotalMemoryForRecycling = 0.02;
if (debugManager.flags.ExperimentalEnableHostAllocationCache.get() != -1) {
fractionOfTotalMemoryForRecycling = 0.01 * std::min(100, debugManager.flags.ExperimentalEnableHostAllocationCache.get());
}
this->maxAllocationsSavedForReuseSize = static_cast<size_t>(fractionOfTotalMemoryForRecycling * totalSystemMemory);
}
OsContext *MemoryManager::createAndRegisterOsContext(CommandStreamReceiver *commandStreamReceiver,
const EngineDescriptor &engineDescriptor) {
auto rootDeviceIndex = commandStreamReceiver->getRootDeviceIndex();

View File

@@ -342,15 +342,21 @@ class MemoryManager {
return std::unique_lock<std::mutex>(hostAllocationsReuseMtx);
}
void recordHostAllocationSaveForReuse(size_t size) {
void initUsmReuseMaxSize();
uint64_t getMaxAllocationsSavedForReuseSize() const {
return maxAllocationsSavedForReuseSize;
}
void recordHostAllocationSaveForReuse(uint64_t size) {
hostAllocationsSavedForReuseSize += size;
}
void recordHostAllocationGetFromReuse(size_t size) {
void recordHostAllocationGetFromReuse(uint64_t size) {
hostAllocationsSavedForReuseSize -= size;
}
size_t getHostAllocationsSavedForReuseSize() const {
uint64_t getHostAllocationsSavedForReuseSize() const {
return hostAllocationsSavedForReuseSize;
}
@@ -430,7 +436,8 @@ class MemoryManager {
std::mutex physicalMemoryAllocationMapMutex;
std::unique_ptr<std::atomic<size_t>[]> localMemAllocsSize;
std::atomic<size_t> sysMemAllocsSize;
size_t hostAllocationsSavedForReuseSize = 0u;
uint64_t maxAllocationsSavedForReuseSize = 0u;
uint64_t hostAllocationsSavedForReuseSize = 0u;
mutable std::mutex hostAllocationsReuseMtx;
std::map<std::pair<AllocationType, bool>, CustomHeapAllocatorConfig> customHeapAllocators;
};

View File

@@ -75,7 +75,7 @@ bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr, SvmAll
}
} else {
auto lock = memoryManager->obtainHostAllocationsReuseLock();
if (size + memoryManager->getHostAllocationsSavedForReuseSize() > this->maxSize) {
if (size + memoryManager->getHostAllocationsSavedForReuseSize() > memoryManager->getMaxAllocationsSavedForReuseSize()) {
isSuccess = false;
} else {
memoryManager->recordHostAllocationSaveForReuse(size);
@@ -912,14 +912,8 @@ void SVMAllocsManager::initUsmDeviceAllocationsCache(Device &device) {
}
void SVMAllocsManager::initUsmHostAllocationsCache() {
const auto totalSystemMemory = this->memoryManager->getSystemSharedMemory(0u);
auto fractionOfTotalMemoryForRecycling = 0.02;
if (debugManager.flags.ExperimentalEnableHostAllocationCache.get() != -1) {
fractionOfTotalMemoryForRecycling = 0.01 * std::min(100, debugManager.flags.ExperimentalEnableHostAllocationCache.get());
}
this->usmHostAllocationsCache.reset(new SvmAllocationCache);
this->usmHostAllocationsCache->maxSize = static_cast<size_t>(fractionOfTotalMemoryForRecycling * totalSystemMemory);
if (this->usmHostAllocationsCache->maxSize > 0u) {
if (memoryManager->getMaxAllocationsSavedForReuseSize() > 0u) {
this->usmHostAllocationsCache->allocations.reserve(128u);
this->usmHostAllocationsCache->svmAllocsManager = this;
this->usmHostAllocationsCache->memoryManager = memoryManager;

View File

@@ -201,7 +201,6 @@ class SVMAllocsManager {
std::vector<SvmCacheAllocationInfo> allocations;
std::mutex mtx;
size_t maxSize = 0;
SVMAllocsManager *svmAllocsManager = nullptr;
MemoryManager *memoryManager = nullptr;
bool enablePerformanceLogging = false;

View File

@@ -62,6 +62,7 @@ class MockMemoryManager : public MemoryManagerCreate<OsAgnosticMemoryManager> {
using MemoryManager::latestContextId;
using MemoryManager::localMemAllocsSize;
using MemoryManager::localMemorySupported;
using MemoryManager::maxAllocationsSavedForReuseSize;
using MemoryManager::reservedMemory;
using MemoryManager::secondaryEngines;

View File

@@ -94,6 +94,7 @@ bool UltDeviceFactory::initializeMemoryManager(ExecutionEnvironment &executionEn
bool enableLocalMemory = gfxCoreHelper.getEnableLocalMemory(*defaultHwInfo);
bool aubUsage = (testMode == TestMode::aubTests) || (testMode == TestMode::aubTestsWithTbx);
executionEnvironment.memoryManager.reset(new MockMemoryManager(false, enableLocalMemory, aubUsage, executionEnvironment));
executionEnvironment.memoryManager->initUsmReuseMaxSize();
}
return true;
}

View File

@@ -396,7 +396,9 @@ TEST(ExecutionEnvironment, givenEnvVarUsedInCalConfigAlsoSetByAppWhenCreateExecu
TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenInitializeMemoryManagerIsCalledThenItIsInitalized) {
MockExecutionEnvironment executionEnvironment{};
executionEnvironment.initializeMemoryManager();
EXPECT_NE(nullptr, executionEnvironment.memoryManager);
ASSERT_NE(nullptr, executionEnvironment.memoryManager);
EXPECT_TRUE(executionEnvironment.memoryManager->isInitialized());
EXPECT_NE(0u, executionEnvironment.memoryManager->getMaxAllocationsSavedForReuseSize());
}
static_assert(sizeof(ExecutionEnvironment) == sizeof(std::unique_ptr<MemoryManager>) +

View File

@@ -986,6 +986,9 @@ HWTEST_F(SvmHostAllocationCacheTest, givenOclApiSpecificConfigWhenCheckingIfEnab
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
auto device = deviceFactory->rootDevices[0];
RAIIProductHelperFactory<MockProductHelper> raii(*device->getExecutionEnvironment()->rootDeviceEnvironments[0]);
const auto expectedMaxSize = static_cast<size_t>(0.02 * device->getMemoryManager()->getSystemSharedMemory(0u));
EXPECT_EQ(expectedMaxSize, device->getMemoryManager()->getMaxAllocationsSavedForReuseSize());
{
raii.mockProductHelper->isHostUsmAllocationReuseSupportedResult = false;
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
@@ -999,8 +1002,6 @@ HWTEST_F(SvmHostAllocationCacheTest, givenOclApiSpecificConfigWhenCheckingIfEnab
EXPECT_EQ(nullptr, svmManager->usmHostAllocationsCache);
svmManager->initUsmAllocationsCaches(*device);
EXPECT_NE(nullptr, svmManager->usmHostAllocationsCache);
const auto expectedMaxSize = static_cast<size_t>(0.02 * svmManager->memoryManager->getSystemSharedMemory(0u));
EXPECT_EQ(expectedMaxSize, svmManager->usmHostAllocationsCache->maxSize);
}
}
@@ -1016,10 +1017,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingHostAll
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
auto testDataset = std::vector<SvmHostAllocationCacheSimpleTestDataType>(
{{1u, nullptr},
@@ -1066,7 +1068,7 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenInitializedThe
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
auto expectedMaxSize = static_cast<size_t>(svmManager->memoryManager->getSystemSharedMemory(mockRootDeviceIndex) * 0.02);
EXPECT_EQ(expectedMaxSize, svmManager->usmHostAllocationsCache->maxSize);
EXPECT_EQ(expectedMaxSize, device->getMemoryManager()->getMaxAllocationsSavedForReuseSize());
}
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingHostAllocationThenItIsPutIntoCacheOnlyIfMaxSizeWillNotBeExceeded) {
@@ -1076,14 +1078,13 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingHostAll
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto memoryManager = device->getMemoryManager();
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
constexpr auto allocationSize = MemoryConstants::pageSize64k;
memoryManager->maxAllocationsSavedForReuseSize = allocationSize;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
constexpr auto allocationSize = MemoryConstants::pageSize64k;
svmManager->usmHostAllocationsCache->maxSize = allocationSize;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
{
auto allocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
@@ -1148,18 +1149,16 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledAndMultipleSVMMana
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto memoryManager = device->getMemoryManager();
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
auto secondSvmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
constexpr auto allocationSize = MemoryConstants::pageSize64k;
memoryManager->maxAllocationsSavedForReuseSize = allocationSize;
svmManager->initUsmAllocationsCaches(*device);
secondSvmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
ASSERT_NE(nullptr, secondSvmManager->usmHostAllocationsCache);
constexpr auto allocationSize = MemoryConstants::pageSize64k;
svmManager->usmHostAllocationsCache->maxSize = allocationSize;
secondSvmManager->usmHostAllocationsCache->maxSize = allocationSize;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
{
auto allocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
@@ -1226,10 +1225,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationsWithDifferentSizesWhenAllocat
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
auto testDataset = std::vector<SvmHostAllocationCacheSimpleTestDataType>(
{
@@ -1277,10 +1277,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationsWithDifferentSizesWhenAllocat
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
auto allocation = svmManager->createHostUnifiedMemoryAllocation(SVMAllocsManager::SvmAllocationCache::minimalSizeToCheckUtilization, unifiedMemoryProperties);
@@ -1316,20 +1317,20 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationOverSizeLimitWhenAllocatingAft
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
const auto notAcceptedAllocSize = SVMAllocsManager::SvmAllocationCache::maxServicedSize + 1;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
auto mockMemoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto mockGa = std::make_unique<MockGraphicsAllocation>(mockRootDeviceIndex, nullptr, notAcceptedAllocSize);
mockGa->gpuAddress = 0xbadf00;
mockGa->cpuPtr = reinterpret_cast<void *>(0xbadf00);
mockGa->setAllocationType(AllocationType::svmCpu);
mockMemoryManager->mockGa = mockGa.release();
mockMemoryManager->returnMockGAFromHostPool = true;
memoryManager->mockGa = mockGa.release();
memoryManager->returnMockGAFromHostPool = true;
auto allocation = svmManager->createHostUnifiedMemoryAllocation(notAcceptedAllocSize, unifiedMemoryProperties);
EXPECT_EQ(reinterpret_cast<void *>(0xbadf00), allocation);
@@ -1345,10 +1346,11 @@ TEST_F(SvmHostAllocationCacheTest, givenMultipleAllocationsWhenAllocatingAfterFr
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
auto testDataset = std::vector<SvmHostAllocationCacheSimpleTestDataType>(
{
@@ -1420,10 +1422,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationsWithDifferentFlagsWhenAllocat
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto rootDevice = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(rootDevice->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(rootDevice->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*rootDevice);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
size_t defaultAllocSize = allocationSizeBasis;
std::map<uint32_t, DeviceBitfield> subDeviceBitfields = {{0u, rootDevice->getDeviceBitfield()}};
@@ -1488,9 +1491,9 @@ TEST_F(SvmHostAllocationCacheTest, givenHostOutOfMemoryWhenAllocatingThenCacheIs
device->injectMemoryManager(new MockMemoryManagerWithCapacity(*device->getExecutionEnvironment()));
MockMemoryManagerWithCapacity *memoryManager = static_cast<MockMemoryManagerWithCapacity *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
ASSERT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
memoryManager->capacity = MemoryConstants::pageSize64k * 3;
@@ -1524,10 +1527,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationInUsageWhenAllocatingAfterFree
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
EXPECT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
auto allocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
@@ -1535,8 +1539,7 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationInUsageWhenAllocatingAfterFree
svmManager->freeSVMAlloc(allocation);
EXPECT_EQ(svmManager->usmHostAllocationsCache->allocations.size(), 1u);
MockMemoryManager *mockMemoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
mockMemoryManager->deferAllocInUse = true;
memoryManager->deferAllocInUse = true;
auto testedAllocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
EXPECT_EQ(svmManager->usmHostAllocationsCache->allocations.size(), 1u);
auto svmData = svmManager->getSVMAlloc(testedAllocation);
@@ -1555,10 +1558,11 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationsInReuseWhenTrimOldAllocsCalle
DebugManagerStateRestore restore;
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
auto device = deviceFactory->rootDevices[0];
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
auto memoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
memoryManager->maxAllocationsSavedForReuseSize = 1 * MemoryConstants::gigaByte;
svmManager->initUsmAllocationsCaches(*device);
EXPECT_NE(nullptr, svmManager->usmHostAllocationsCache);
svmManager->usmHostAllocationsCache->maxSize = 1 * MemoryConstants::gigaByte;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
auto allocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);