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:
parent
3b571d140c
commit
7918b44a94
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1114,3 +1114,7 @@ HWTEST_F(ProductHelperTest, whenAdjustScratchSizeThenSizeIsNotChanged) {
|
|||
productHelper->adjustScratchSize(scratchSize);
|
||||
EXPECT_EQ(initialScratchSize, scratchSize);
|
||||
}
|
||||
|
||||
HWTEST_F(ProductHelperTest, givenProductHelperWhenCheckingIs2MBLocalMemAlignmentEnabledThenCorrectValueIsReturned) {
|
||||
EXPECT_FALSE(productHelper->is2MBLocalMemAlignmentEnabled());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue