fix: apply 2MB alignment to large local memory allocations

In this patch, we align up the allocation size to 2MB for all
allocations >= 2MB located in local memory.
2MB alignment support is defined by function:
`is2MBLocalMemAlignmentEnabled`

Related-To: NEO-12287

Signed-off-by: Fabian Zwoliński <fabian.zwolinski@intel.com>
This commit is contained in:
Fabian Zwoliński 2025-01-30 15:37:10 +00:00 committed by Compute-Runtime-Automation
parent 3b571d140c
commit 7918b44a94
7 changed files with 58 additions and 3 deletions

View File

@ -2073,6 +2073,13 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryInDevicePool(const A
} else {
sizeAligned = alignUp(allocationData.size, MemoryConstants::pageSize64k);
}
auto &productHelper = gmmHelper->getRootDeviceEnvironment().getHelper<ProductHelper>();
if (productHelper.is2MBLocalMemAlignmentEnabled() &&
allocationData.size >= MemoryConstants::pageSize2M) {
sizeAligned = alignUp(sizeAligned, MemoryConstants::pageSize2M);
}
if (debugManager.flags.ExperimentalAlignLocalMemorySizeTo2MB.get()) {
sizeAligned = alignUp(sizeAligned, MemoryConstants::pageSize2M);
}

View File

@ -194,6 +194,7 @@ class ProductHelper {
virtual uint32_t getCommandBuffersPreallocatedPerCommandQueue() const = 0;
virtual uint32_t getInternalHeapsPreallocated() const = 0;
virtual bool overrideAllocationCacheable(const AllocationData &allocationData) const = 0;
virtual bool is2MBLocalMemAlignmentEnabled() const = 0;
virtual bool getFrontEndPropertyScratchSizeSupport() const = 0;
virtual bool getFrontEndPropertyPrivateScratchSizeSupport() const = 0;

View File

@ -223,6 +223,11 @@ bool ProductHelperHw<gfxProduct>::overrideAllocationCacheable(const AllocationDa
return false;
}
template <PRODUCT_FAMILY gfxProduct>
bool ProductHelperHw<gfxProduct>::is2MBLocalMemAlignmentEnabled() const {
return false;
}
template <PRODUCT_FAMILY gfxProduct>
bool ProductHelperHw<gfxProduct>::isAdditionalStateBaseAddressWARequired(const HardwareInfo &hwInfo) const {
return false;

View File

@ -136,6 +136,7 @@ class ProductHelperHw : public ProductHelper {
uint32_t getCommandBuffersPreallocatedPerCommandQueue() const override;
uint32_t getInternalHeapsPreallocated() const override;
bool overrideAllocationCacheable(const AllocationData &allocationData) const override;
bool is2MBLocalMemAlignmentEnabled() const override;
bool getFrontEndPropertyScratchSizeSupport() const override;
bool getFrontEndPropertyPrivateScratchSizeSupport() const override;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023-2024 Intel Corporation
* Copyright (C) 2023-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -24,5 +24,6 @@ struct MockProductHelper : ProductHelperHw<IGFX_UNKNOWN> {
ADDMETHOD_CONST_NOBASE(isDeviceUsmAllocationReuseSupported, bool, false, ());
ADDMETHOD_CONST_NOBASE(isHostUsmAllocationReuseSupported, bool, false, ());
ADDMETHOD_CONST_NOBASE(isUsmPoolAllocatorSupported, bool, false, ());
ADDMETHOD_CONST_NOBASE(is2MBLocalMemAlignmentEnabled, bool, false, ());
};
} // namespace NEO

View File

@ -31,6 +31,7 @@
#include "shared/test/common/mocks/mock_gmm_client_context_base.h"
#include "shared/test/common/mocks/mock_gmm_resource_info.h"
#include "shared/test/common/mocks/mock_host_ptr_manager.h"
#include "shared/test/common/mocks/mock_product_helper.h"
#include "shared/test/common/os_interface/linux/drm_memory_manager_fixture.h"
#include "shared/test/common/os_interface/linux/drm_mock_cache_info.h"
#include "shared/test/common/os_interface/linux/drm_mock_memory_info.h"
@ -7350,6 +7351,32 @@ TEST_F(DrmMemoryManagerLocalMemoryAlignmentTest, givenForced2MBSizeAlignmentWhen
}
}
TEST_F(DrmMemoryManagerLocalMemoryAlignmentTest, givenEnabled2MBSizeAlignmentWhenAllocatingAllocationThenUseProperAlignment) {
auto mockProductHelper = new MockProductHelper;
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->productHelper.reset(mockProductHelper);
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true;
ASSERT_TRUE(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->productHelper->is2MBLocalMemAlignmentEnabled());
AllocationData allocationData;
allocationData.allFlags = 0;
allocationData.flags.allocateMemory = true;
allocationData.rootDeviceIndex = rootDeviceIndex;
allocationData.type = AllocationType::buffer;
allocationData.flags.resource48Bit = true;
MemoryManager::AllocationStatus allocationStatus;
allocationData.size = 2 * MemoryConstants::megaByte + 1;
auto memoryManager = createMemoryManager();
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocationData, allocationStatus);
ASSERT_NE(nullptr, allocation);
EXPECT_EQ(MemoryManager::AllocationStatus::Success, allocationStatus);
EXPECT_TRUE(isAllocationWithinHeap(*memoryManager, *allocation, HeapIndex::heapStandard2MB));
EXPECT_EQ(4 * MemoryConstants::megaByte, allocation->getUnderlyingBufferSize());
EXPECT_EQ(4 * MemoryConstants::megaByte, allocation->getReservedAddressSize());
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenNotSetUseSystemMemoryWhenGraphicsAllocationInDevicePoolIsAllocatedForBufferThenLocalMemoryAllocationIsReturnedFromStandard64KbHeap) {
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;
@ -7598,6 +7625,7 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenAllocati
if (!memoryManager->getGfxPartition(rootDeviceIndex)->getHeapLimit(HeapIndex::heapExtended)) {
GTEST_SKIP();
}
auto &productHelper = this->device->getProductHelper();
auto size = 8 * MemoryConstants::gigaByte;
@ -7614,12 +7642,20 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenAllocati
EXPECT_TRUE(allocation->getGpuAddress() % size == 0u);
size = 8 * MemoryConstants::gigaByte + MemoryConstants::pageSize64k;
size_t expectedSize = size;
if (productHelper.is2MBLocalMemAlignmentEnabled()) {
expectedSize = alignUp(size, MemoryConstants::pageSize2M);
} else {
expectedSize = alignUp(size, MemoryConstants::pageSize64k);
}
allocData.size = size;
auto allocation2 = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
ASSERT_NE(nullptr, allocation2);
EXPECT_EQ(allocData.size, allocation2->getUnderlyingBufferSize());
EXPECT_EQ(allocData.size, static_cast<DrmAllocation *>(allocation2)->getBO()->peekSize());
EXPECT_EQ(expectedSize, allocation2->getUnderlyingBufferSize());
EXPECT_EQ(expectedSize, static_cast<DrmAllocation *>(allocation2)->getBO()->peekSize());
EXPECT_TRUE(allocation2->getGpuAddress() % MemoryConstants::pageSize2M == 0u);
memoryManager->freeGraphicsMemory(allocation);

View File

@ -1114,3 +1114,7 @@ HWTEST_F(ProductHelperTest, whenAdjustScratchSizeThenSizeIsNotChanged) {
productHelper->adjustScratchSize(scratchSize);
EXPECT_EQ(initialScratchSize, scratchSize);
}
HWTEST_F(ProductHelperTest, givenProductHelperWhenCheckingIs2MBLocalMemAlignmentEnabledThenCorrectValueIsReturned) {
EXPECT_FALSE(productHelper->is2MBLocalMemAlignmentEnabled());
}