fix: track usm reuse usage in multiple contexts
Add tracking of memory used for usm reuse mechanism when multiple cl contexts are used. Tracking for device added to NEO::Device, for host added to NEO::MemoryManager. This fixes usm reuse using x% of memory per each context instead of globally. Related-To: NEO-13308 Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
parent
250171688f
commit
e55aa958b7
|
@ -216,6 +216,22 @@ class Device : public ReferenceTrackedObject<Device> {
|
|||
|
||||
std::atomic<uint32_t> debugExecutionCounter = 0;
|
||||
|
||||
std::unique_lock<std::mutex> obtainAllocationsReuseLock() const {
|
||||
return std::unique_lock<std::mutex>(allocationsReuseMtx);
|
||||
}
|
||||
|
||||
void recordAllocationSaveForReuse(size_t size) {
|
||||
allocationsSavedForReuseSize += size;
|
||||
}
|
||||
|
||||
void recordAllocationGetFromReuse(size_t size) {
|
||||
allocationsSavedForReuseSize -= size;
|
||||
}
|
||||
|
||||
size_t getAllocationsSavedForReuseSize() const {
|
||||
return allocationsSavedForReuseSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
Device() = delete;
|
||||
Device(ExecutionEnvironment *executionEnvironment, const uint32_t rootDeviceIndex);
|
||||
|
@ -292,6 +308,9 @@ class Device : public ReferenceTrackedObject<Device> {
|
|||
ISAPoolAllocator isaPoolAllocator;
|
||||
std::unique_ptr<UsmMemAllocPoolsManager> deviceUsmMemAllocPoolsManager;
|
||||
|
||||
size_t allocationsSavedForReuseSize = 0u;
|
||||
mutable std::mutex allocationsReuseMtx;
|
||||
|
||||
struct {
|
||||
bool isValid = false;
|
||||
std::array<uint8_t, ProductHelper::uuidSize> id;
|
||||
|
|
|
@ -326,6 +326,22 @@ class MemoryManager {
|
|||
|
||||
virtual void getExtraDeviceProperties(uint32_t rootDeviceIndex, uint32_t *moduleId, uint16_t *serverType) { return; }
|
||||
|
||||
std::unique_lock<std::mutex> obtainHostAllocationsReuseLock() const {
|
||||
return std::unique_lock<std::mutex>(hostAllocationsReuseMtx);
|
||||
}
|
||||
|
||||
void recordHostAllocationSaveForReuse(size_t size) {
|
||||
hostAllocationsSavedForReuseSize += size;
|
||||
}
|
||||
|
||||
void recordHostAllocationGetFromReuse(size_t size) {
|
||||
hostAllocationsSavedForReuseSize -= size;
|
||||
}
|
||||
|
||||
size_t getHostAllocationsSavedForReuseSize() const {
|
||||
return hostAllocationsSavedForReuseSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool getAllocationData(AllocationData &allocationData, const AllocationProperties &properties, const void *hostPtr, const StorageInfo &storageInfo);
|
||||
static void overrideAllocationData(AllocationData &allocationData, const AllocationProperties &properties);
|
||||
|
@ -398,6 +414,8 @@ class MemoryManager {
|
|||
std::mutex physicalMemoryAllocationMapMutex;
|
||||
std::unique_ptr<std::atomic<size_t>[]> localMemAllocsSize;
|
||||
std::atomic<size_t> sysMemAllocsSize;
|
||||
size_t hostAllocationsSavedForReuseSize = 0u;
|
||||
mutable std::mutex hostAllocationsReuseMtx;
|
||||
};
|
||||
|
||||
std::unique_ptr<DeferredDeleter> createDeferredDeleter();
|
||||
|
|
|
@ -54,16 +54,27 @@ void SVMAllocsManager::MapBasedAllocationTracker::freeAllocations(NEO::MemoryMan
|
|||
}
|
||||
}
|
||||
|
||||
bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr) {
|
||||
bool SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr, SvmAllocationData *svmData, MemoryManager *memoryManager) {
|
||||
if (false == sizeAllowed(size)) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(this->mtx);
|
||||
if (size + this->totalSize > this->maxSize) {
|
||||
return false;
|
||||
if (auto device = svmData->device) {
|
||||
auto lock = device->obtainAllocationsReuseLock();
|
||||
const auto usedSize = device->getAllocationsSavedForReuseSize();
|
||||
if (size + usedSize > this->maxSize) {
|
||||
return false;
|
||||
}
|
||||
device->recordAllocationSaveForReuse(size);
|
||||
} else {
|
||||
auto lock = memoryManager->obtainHostAllocationsReuseLock();
|
||||
const auto usedSize = memoryManager->getHostAllocationsSavedForReuseSize();
|
||||
if (size + usedSize > this->maxSize) {
|
||||
return false;
|
||||
}
|
||||
memoryManager->recordHostAllocationSaveForReuse(size);
|
||||
}
|
||||
allocations.emplace(std::lower_bound(allocations.begin(), allocations.end(), size), size, ptr);
|
||||
this->totalSize += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -75,7 +86,7 @@ bool SVMAllocsManager::SvmAllocationCache::allocUtilizationAllows(size_t request
|
|||
return true;
|
||||
}
|
||||
|
||||
void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties, SVMAllocsManager *svmAllocsManager) {
|
||||
void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties, SVMAllocsManager *svmAllocsManager, MemoryManager *memoryManager) {
|
||||
if (false == sizeAllowed(size)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -92,7 +103,13 @@ void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemory
|
|||
if (svmAllocData->device == unifiedMemoryProperties.device &&
|
||||
svmAllocData->allocationFlagsProperty.allFlags == unifiedMemoryProperties.allocationFlags.allFlags &&
|
||||
svmAllocData->allocationFlagsProperty.allAllocFlags == unifiedMemoryProperties.allocationFlags.allAllocFlags) {
|
||||
totalSize -= allocationIter->allocationSize;
|
||||
if (svmAllocData->device) {
|
||||
auto lock = svmAllocData->device->obtainAllocationsReuseLock();
|
||||
svmAllocData->device->recordAllocationGetFromReuse(allocationIter->allocationSize);
|
||||
} else {
|
||||
auto lock = memoryManager->obtainHostAllocationsReuseLock();
|
||||
memoryManager->recordHostAllocationGetFromReuse(allocationIter->allocationSize);
|
||||
}
|
||||
allocations.erase(allocationIter);
|
||||
return allocationPtr;
|
||||
}
|
||||
|
@ -100,15 +117,21 @@ void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemory
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void SVMAllocsManager::SvmAllocationCache::trim(SVMAllocsManager *svmAllocsManager) {
|
||||
void SVMAllocsManager::SvmAllocationCache::trim(SVMAllocsManager *svmAllocsManager, MemoryManager *memoryManager) {
|
||||
std::lock_guard<std::mutex> lock(this->mtx);
|
||||
for (auto &cachedAllocationInfo : this->allocations) {
|
||||
SvmAllocationData *svmData = svmAllocsManager->getSVMAlloc(cachedAllocationInfo.allocation);
|
||||
DEBUG_BREAK_IF(nullptr == svmData);
|
||||
if (svmData->device) {
|
||||
auto lock = svmData->device->obtainAllocationsReuseLock();
|
||||
svmData->device->recordAllocationGetFromReuse(cachedAllocationInfo.allocationSize);
|
||||
} else {
|
||||
auto lock = memoryManager->obtainHostAllocationsReuseLock();
|
||||
memoryManager->recordHostAllocationGetFromReuse(cachedAllocationInfo.allocationSize);
|
||||
}
|
||||
svmAllocsManager->freeSVMAllocImpl(cachedAllocationInfo.allocation, FreePolicyType::none, svmData);
|
||||
}
|
||||
this->allocations.clear();
|
||||
this->totalSize = 0u;
|
||||
}
|
||||
|
||||
SvmAllocationData *SVMAllocsManager::MapBasedAllocationTracker::get(const void *ptr) {
|
||||
|
@ -251,7 +274,7 @@ void *SVMAllocsManager::createHostUnifiedMemoryAllocation(size_t size,
|
|||
unifiedMemoryProperties.cacheRegion = MemoryPropertiesHelper::getCacheRegion(memoryProperties.allocationFlags);
|
||||
|
||||
if (this->usmHostAllocationsCacheEnabled) {
|
||||
void *allocationFromCache = this->usmHostAllocationsCache.get(size, memoryProperties, this);
|
||||
void *allocationFromCache = this->usmHostAllocationsCache.get(size, memoryProperties, this, memoryManager);
|
||||
if (allocationFromCache) {
|
||||
return allocationFromCache;
|
||||
}
|
||||
|
@ -329,7 +352,7 @@ void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size,
|
|||
unifiedMemoryProperties.flags.isUSMDeviceAllocation = true;
|
||||
if (this->usmDeviceAllocationsCacheEnabled &&
|
||||
false == memoryProperties.isInternalAllocation) {
|
||||
void *allocationFromCache = this->usmDeviceAllocationsCache.get(size, memoryProperties, this);
|
||||
void *allocationFromCache = this->usmDeviceAllocationsCache.get(size, memoryProperties, this, memoryManager);
|
||||
if (allocationFromCache) {
|
||||
return allocationFromCache;
|
||||
}
|
||||
|
@ -478,13 +501,13 @@ bool SVMAllocsManager::freeSVMAlloc(void *ptr, bool blocking) {
|
|||
if (InternalMemoryType::deviceUnifiedMemory == svmData->memoryType &&
|
||||
false == svmData->isInternalAllocation &&
|
||||
this->usmDeviceAllocationsCacheEnabled) {
|
||||
if (this->usmDeviceAllocationsCache.insert(svmData->gpuAllocations.getDefaultGraphicsAllocation()->getUnderlyingBufferSize(), ptr)) {
|
||||
if (this->usmDeviceAllocationsCache.insert(svmData->gpuAllocations.getDefaultGraphicsAllocation()->getUnderlyingBufferSize(), ptr, svmData, memoryManager)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (InternalMemoryType::hostUnifiedMemory == svmData->memoryType &&
|
||||
this->usmHostAllocationsCacheEnabled) {
|
||||
if (this->usmHostAllocationsCache.insert(svmData->size, ptr)) {
|
||||
if (this->usmHostAllocationsCache.insert(svmData->size, ptr, svmData, memoryManager)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -508,13 +531,13 @@ bool SVMAllocsManager::freeSVMAllocDefer(void *ptr) {
|
|||
if (svmData) {
|
||||
if (InternalMemoryType::deviceUnifiedMemory == svmData->memoryType &&
|
||||
this->usmDeviceAllocationsCacheEnabled) {
|
||||
if (this->usmDeviceAllocationsCache.insert(svmData->size, ptr)) {
|
||||
if (this->usmDeviceAllocationsCache.insert(svmData->size, ptr, svmData, memoryManager)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (InternalMemoryType::hostUnifiedMemory == svmData->memoryType &&
|
||||
this->usmHostAllocationsCacheEnabled) {
|
||||
if (this->usmHostAllocationsCache.insert(svmData->size, ptr)) {
|
||||
if (this->usmHostAllocationsCache.insert(svmData->size, ptr, svmData, memoryManager)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -585,11 +608,11 @@ void SVMAllocsManager::freeSVMAllocDeferImpl() {
|
|||
}
|
||||
|
||||
void SVMAllocsManager::trimUSMDeviceAllocCache() {
|
||||
this->usmDeviceAllocationsCache.trim(this);
|
||||
this->usmDeviceAllocationsCache.trim(this, memoryManager);
|
||||
}
|
||||
|
||||
void SVMAllocsManager::trimUSMHostAllocCache() {
|
||||
this->usmHostAllocationsCache.trim(this);
|
||||
this->usmHostAllocationsCache.trim(this, memoryManager);
|
||||
}
|
||||
|
||||
void *SVMAllocsManager::createZeroCopySvmAllocation(size_t size, const SvmAllocationProperties &svmProperties,
|
||||
|
|
|
@ -165,15 +165,14 @@ class SVMAllocsManager {
|
|||
static constexpr double minimalAllocUtilization = 0.5;
|
||||
|
||||
static bool sizeAllowed(size_t size) { return size <= SvmAllocationCache::maxServicedSize; }
|
||||
bool insert(size_t size, void *);
|
||||
bool insert(size_t size, void *ptr, SvmAllocationData *svmData, MemoryManager *memoryManager);
|
||||
static bool allocUtilizationAllows(size_t requestedSize, size_t reuseCandidateSize);
|
||||
void *get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties, SVMAllocsManager *svmAllocsManager);
|
||||
void trim(SVMAllocsManager *svmAllocsManager);
|
||||
void *get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties, SVMAllocsManager *svmAllocsManager, MemoryManager *memoryManager);
|
||||
void trim(SVMAllocsManager *svmAllocsManager, MemoryManager *memoryManager);
|
||||
|
||||
std::vector<SvmCacheAllocationInfo> allocations;
|
||||
std::mutex mtx;
|
||||
size_t maxSize = 0;
|
||||
size_t totalSize = 0;
|
||||
};
|
||||
|
||||
enum class FreePolicyType : uint32_t {
|
||||
|
|
|
@ -252,56 +252,128 @@ TEST_F(SvmDeviceAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingDevic
|
|||
{
|
||||
auto allocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = svmManager->createUnifiedMemoryAllocation(1u, unifiedMemoryProperties);
|
||||
auto allocation2 = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(1u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMDeviceAllocCache();
|
||||
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
}
|
||||
{
|
||||
auto allocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = svmManager->createUnifiedMemoryAllocation(1u, unifiedMemoryProperties);
|
||||
auto allocation2 = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(allocation2);
|
||||
EXPECT_EQ(1u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMDeviceAllocCache();
|
||||
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SvmDeviceAllocationCacheTest, givenAllocationCacheEnabledAndMultipleSVMManagersWhenFreeingDeviceAllocationThenItIsPutIntoCacheOnlyIfMaxSizeWillNotBeExceeded) {
|
||||
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
|
||||
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
|
||||
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
|
||||
DebugManagerStateRestore restore;
|
||||
debugManager.flags.ExperimentalEnableDeviceAllocationCache.set(1);
|
||||
auto device = deviceFactory->rootDevices[0];
|
||||
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
|
||||
auto secondSvmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
|
||||
svmManager->initUsmAllocationsCaches(*device);
|
||||
secondSvmManager->initUsmAllocationsCaches(*device);
|
||||
ASSERT_TRUE(svmManager->usmDeviceAllocationsCacheEnabled);
|
||||
ASSERT_TRUE(secondSvmManager->usmDeviceAllocationsCacheEnabled);
|
||||
|
||||
constexpr auto allocationSize = MemoryConstants::pageSize64k;
|
||||
svmManager->usmDeviceAllocationsCache.maxSize = allocationSize;
|
||||
secondSvmManager->usmDeviceAllocationsCache.maxSize = allocationSize;
|
||||
|
||||
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::deviceUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
|
||||
unifiedMemoryProperties.device = device;
|
||||
{
|
||||
auto allocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = secondSvmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
secondSvmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(0u, secondSvmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMDeviceAllocCache();
|
||||
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
}
|
||||
{
|
||||
auto allocation = svmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = secondSvmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
|
||||
secondSvmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(1u, secondSvmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(0u, svmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = secondSvmManager->createUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation2);
|
||||
EXPECT_EQ(0u, secondSvmManager->usmDeviceAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
|
||||
secondSvmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
secondSvmManager->trimUSMDeviceAllocCache();
|
||||
EXPECT_EQ(secondSvmManager->usmDeviceAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, device->getAllocationsSavedForReuseSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -699,7 +771,7 @@ struct SvmHostAllocationCacheSimpleTestDataType {
|
|||
void *allocation;
|
||||
};
|
||||
|
||||
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingDeviceAllocationThenItIsPutIntoCache) {
|
||||
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingHostAllocationThenItIsPutIntoCache) {
|
||||
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
|
||||
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
|
||||
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
|
||||
|
@ -759,14 +831,15 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenInitializedThe
|
|||
EXPECT_EQ(expectedMaxSize, svmManager->usmHostAllocationsCache.maxSize);
|
||||
}
|
||||
|
||||
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingDeviceAllocationThenItIsPutIntoCacheOnlyIfMaxSizeWillNotBeExceeded) {
|
||||
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingHostAllocationThenItIsPutIntoCacheOnlyIfMaxSizeWillNotBeExceeded) {
|
||||
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
|
||||
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
|
||||
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
|
||||
DebugManagerStateRestore restore;
|
||||
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
|
||||
auto device = deviceFactory->rootDevices[0];
|
||||
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
|
||||
auto memoryManager = device->getMemoryManager();
|
||||
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
|
||||
svmManager->initUsmAllocationsCaches(*device);
|
||||
ASSERT_TRUE(svmManager->usmHostAllocationsCacheEnabled);
|
||||
|
||||
|
@ -780,26 +853,26 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingDeviceA
|
|||
auto allocation2 = svmManager->createHostUnifiedMemoryAllocation(1u, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(1u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMHostAllocCache();
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
}
|
||||
{
|
||||
auto allocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
|
@ -807,26 +880,104 @@ TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledWhenFreeingDeviceA
|
|||
auto allocation2 = svmManager->createHostUnifiedMemoryAllocation(1u, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(allocation2);
|
||||
EXPECT_EQ(1u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAllocDefer(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMHostAllocCache();
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.totalSize);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheEnabledAndMultipleSVMManagersWhenFreeingHostAllocationThenItIsPutIntoCacheOnlyIfMaxSizeWillNotBeExceeded) {
|
||||
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
|
||||
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
|
||||
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
|
||||
DebugManagerStateRestore restore;
|
||||
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
|
||||
auto device = deviceFactory->rootDevices[0];
|
||||
auto memoryManager = device->getMemoryManager();
|
||||
auto svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
|
||||
auto secondSvmManager = std::make_unique<MockSVMAllocsManager>(memoryManager, false);
|
||||
svmManager->initUsmAllocationsCaches(*device);
|
||||
secondSvmManager->initUsmAllocationsCaches(*device);
|
||||
ASSERT_TRUE(svmManager->usmHostAllocationsCacheEnabled);
|
||||
ASSERT_TRUE(secondSvmManager->usmHostAllocationsCacheEnabled);
|
||||
|
||||
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);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = secondSvmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, secondSvmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(1u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
secondSvmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(0u, secondSvmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation);
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
svmManager->trimUSMHostAllocCache();
|
||||
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
}
|
||||
{
|
||||
auto allocation = svmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation, nullptr);
|
||||
auto allocation2 = secondSvmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
ASSERT_NE(allocation2, nullptr);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, secondSvmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
secondSvmManager->freeSVMAlloc(allocation2);
|
||||
EXPECT_EQ(1u, secondSvmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
svmManager->freeSVMAlloc(allocation);
|
||||
EXPECT_EQ(0u, svmManager->usmHostAllocationsCache.allocations.size());
|
||||
EXPECT_EQ(allocationSize, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
auto recycledAllocation = secondSvmManager->createHostUnifiedMemoryAllocation(allocationSize, unifiedMemoryProperties);
|
||||
EXPECT_EQ(recycledAllocation, allocation2);
|
||||
EXPECT_EQ(secondSvmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
|
||||
secondSvmManager->freeSVMAlloc(recycledAllocation);
|
||||
|
||||
secondSvmManager->trimUSMHostAllocCache();
|
||||
EXPECT_EQ(secondSvmManager->usmHostAllocationsCache.allocations.size(), 0u);
|
||||
EXPECT_EQ(0u, memoryManager->getHostAllocationsSavedForReuseSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue