From 7918b44a941b1834c4d22b9ceb9fd322d6a8f1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Zwoli=C5=84ski?= Date: Thu, 30 Jan 2025 15:37:10 +0000 Subject: [PATCH] fix: apply 2MB alignment to large local memory allocations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../os_interface/linux/drm_memory_manager.cpp | 7 ++++ shared/source/os_interface/product_helper.h | 1 + shared/source/os_interface/product_helper.inl | 5 +++ .../source/os_interface/product_helper_hw.h | 1 + .../test/common/mocks/mock_product_helper.h | 3 +- .../linux/drm_memory_manager_tests.cpp | 40 ++++++++++++++++++- .../os_interface/product_helper_tests.cpp | 4 ++ 7 files changed, 58 insertions(+), 3 deletions(-) diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index cfe5384988..e01df86175 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -2073,6 +2073,13 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryInDevicePool(const A } else { sizeAligned = alignUp(allocationData.size, MemoryConstants::pageSize64k); } + + auto &productHelper = gmmHelper->getRootDeviceEnvironment().getHelper(); + if (productHelper.is2MBLocalMemAlignmentEnabled() && + allocationData.size >= MemoryConstants::pageSize2M) { + sizeAligned = alignUp(sizeAligned, MemoryConstants::pageSize2M); + } + if (debugManager.flags.ExperimentalAlignLocalMemorySizeTo2MB.get()) { sizeAligned = alignUp(sizeAligned, MemoryConstants::pageSize2M); } diff --git a/shared/source/os_interface/product_helper.h b/shared/source/os_interface/product_helper.h index 9d9eb519fa..628d9654f5 100644 --- a/shared/source/os_interface/product_helper.h +++ b/shared/source/os_interface/product_helper.h @@ -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; diff --git a/shared/source/os_interface/product_helper.inl b/shared/source/os_interface/product_helper.inl index adbf96f126..9eca35a0e1 100644 --- a/shared/source/os_interface/product_helper.inl +++ b/shared/source/os_interface/product_helper.inl @@ -223,6 +223,11 @@ bool ProductHelperHw::overrideAllocationCacheable(const AllocationDa return false; } +template +bool ProductHelperHw::is2MBLocalMemAlignmentEnabled() const { + return false; +} + template bool ProductHelperHw::isAdditionalStateBaseAddressWARequired(const HardwareInfo &hwInfo) const { return false; diff --git a/shared/source/os_interface/product_helper_hw.h b/shared/source/os_interface/product_helper_hw.h index 6af336cb48..bdbdaa5516 100644 --- a/shared/source/os_interface/product_helper_hw.h +++ b/shared/source/os_interface/product_helper_hw.h @@ -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; diff --git a/shared/test/common/mocks/mock_product_helper.h b/shared/test/common/mocks/mock_product_helper.h index d5c8c139af..c057aaa100 100644 --- a/shared/test/common/mocks/mock_product_helper.h +++ b/shared/test/common/mocks/mock_product_helper.h @@ -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 { 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 diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index f209c90e01..7d409f92a0 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -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(allocation2)->getBO()->peekSize()); + EXPECT_EQ(expectedSize, allocation2->getUnderlyingBufferSize()); + EXPECT_EQ(expectedSize, static_cast(allocation2)->getBO()->peekSize()); EXPECT_TRUE(allocation2->getGpuAddress() % MemoryConstants::pageSize2M == 0u); memoryManager->freeGraphicsMemory(allocation); diff --git a/shared/test/unit_test/os_interface/product_helper_tests.cpp b/shared/test/unit_test/os_interface/product_helper_tests.cpp index f490892442..9d93d00d5a 100644 --- a/shared/test/unit_test/os_interface/product_helper_tests.cpp +++ b/shared/test/unit_test/os_interface/product_helper_tests.cpp @@ -1114,3 +1114,7 @@ HWTEST_F(ProductHelperTest, whenAdjustScratchSizeThenSizeIsNotChanged) { productHelper->adjustScratchSize(scratchSize); EXPECT_EQ(initialScratchSize, scratchSize); } + +HWTEST_F(ProductHelperTest, givenProductHelperWhenCheckingIs2MBLocalMemAlignmentEnabledThenCorrectValueIsReturned) { + EXPECT_FALSE(productHelper->is2MBLocalMemAlignmentEnabled()); +}