From aac8754e67505bb72cbf4e83b013a66320fbec32 Mon Sep 17 00:00:00 2001 From: Szymon Morek Date: Wed, 9 Nov 2022 15:47:00 +0000 Subject: [PATCH] Create reusable list per immediate cmd list Related-To: NEO-7361 Signed-off-by: Szymon Morek --- .../xe_hpc_core/test_cmdlist_xe_hpc_core.cpp | 3 +- .../source/command_container/cmdcontainer.cpp | 14 +++- .../source/command_container/cmdcontainer.h | 1 + .../command_container_tests.cpp | 78 +++++++++++++++---- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/level_zero/core/test/unit_tests/xe_hpc_core/test_cmdlist_xe_hpc_core.cpp b/level_zero/core/test/unit_tests/xe_hpc_core/test_cmdlist_xe_hpc_core.cpp index f61ae3d23a..1c063638ca 100644 --- a/level_zero/core/test/unit_tests/xe_hpc_core/test_cmdlist_xe_hpc_core.cpp +++ b/level_zero/core/test/unit_tests/xe_hpc_core/test_cmdlist_xe_hpc_core.cpp @@ -1332,7 +1332,7 @@ HWTEST2_F(CreateCommandListXeHpcTest, givenXeHpcPlatformsWhenImmediateCommandLis EXPECT_EQ(commandListImmediate->isFlushTaskSubmissionEnabled, commandListImmediate->immediateCmdListHeapSharing); } -HWTEST2_F(CreateCommandListXeHpcTest, whenCreateImmediateCommandListThenAllocationListFilledWithCommandBuffer, IsXeHpcCore) { +HWTEST2_F(CreateCommandListXeHpcTest, whenDestroyImmediateCommandListThenGlobalAllocationListFilledWithCommandBuffer, IsXeHpcCore) { const ze_command_queue_desc_t desc = {}; bool internalEngine = true; @@ -1344,6 +1344,7 @@ HWTEST2_F(CreateCommandListXeHpcTest, whenCreateImmediateCommandListThenAllocati NEO::EngineGroupType::RenderCompute, returnValue)); ASSERT_NE(nullptr, commandList); + commandList.reset(); EXPECT_FALSE(static_cast(device)->allocationsForReuse->peekIsEmpty()); } diff --git a/shared/source/command_container/cmdcontainer.cpp b/shared/source/command_container/cmdcontainer.cpp index 168c0de696..9c566604dc 100644 --- a/shared/source/command_container/cmdcontainer.cpp +++ b/shared/source/command_container/cmdcontainer.cpp @@ -248,6 +248,9 @@ void CommandContainer::createAndAssignNewHeap(HeapType heapType, size_t size) { } void CommandContainer::handleCmdBufferAllocations(size_t startIndex) { + if (immediateReusableAllocationList != nullptr && !immediateReusableAllocationList->peekIsEmpty() && reusableAllocationList != nullptr) { + reusableAllocationList->splice(*immediateReusableAllocationList->detachNodes()); + } for (size_t i = startIndex; i < cmdBufferAllocations.size(); i++) { if (this->reusableAllocationList) { @@ -331,7 +334,11 @@ void CommandContainer::ensureHeapSizePrepared(size_t sshRequiredSize, size_t dsh GraphicsAllocation *CommandContainer::reuseExistingCmdBuffer() { size_t alignedSize = alignUp(this->getTotalCmdBufferSize(), MemoryConstants::pageSize64k); - auto cmdBufferAllocation = this->reusableAllocationList->detachAllocation(alignedSize, nullptr, this->immediateCmdListCsr, AllocationType::COMMAND_BUFFER).release(); + auto cmdBufferAllocation = this->immediateReusableAllocationList->detachAllocation(alignedSize, nullptr, this->immediateCmdListCsr, AllocationType::COMMAND_BUFFER).release(); + if (!cmdBufferAllocation) { + this->reusableAllocationList->detachAllocation(alignedSize, nullptr, this->immediateCmdListCsr, AllocationType::COMMAND_BUFFER).release(); + } + if (cmdBufferAllocation) { this->cmdBufferAllocations.push_back(cmdBufferAllocation); } @@ -367,6 +374,7 @@ GraphicsAllocation *CommandContainer::allocateCommandBuffer() { } void CommandContainer::fillReusableAllocationLists() { + this->immediateReusableAllocationList = std::make_unique(); const auto &hardwareInfo = device->getHardwareInfo(); auto &hwHelper = NEO::HwHelper::get(hardwareInfo.platform.eRenderCoreFamily); auto amountToFill = hwHelper.getAmountOfAllocationsToFill(); @@ -376,7 +384,7 @@ void CommandContainer::fillReusableAllocationLists() { for (auto i = 0u; i < amountToFill; i++) { auto allocToReuse = this->allocateCommandBuffer(); - this->reusableAllocationList->pushTailOne(*allocToReuse); + this->immediateReusableAllocationList->pushTailOne(*allocToReuse); this->getResidencyContainer().push_back(allocToReuse); } @@ -414,7 +422,7 @@ void CommandContainer::storeAllocationAndFlushTagUpdate(GraphicsAllocation *allo allocation->updateTaskCount(taskCount, osContextId); allocation->updateResidencyTaskCount(taskCount, osContextId); if (allocation->getAllocationType() == AllocationType::COMMAND_BUFFER) { - this->reusableAllocationList->pushTailOne(*allocation); + this->immediateReusableAllocationList->pushTailOne(*allocation); } else { getHeapHelper()->storeHeapAllocation(allocation); } diff --git a/shared/source/command_container/cmdcontainer.h b/shared/source/command_container/cmdcontainer.h index 5149c3da46..0caaa19cc4 100644 --- a/shared/source/command_container/cmdcontainer.h +++ b/shared/source/command_container/cmdcontainer.h @@ -146,6 +146,7 @@ class CommandContainer : public NonCopyableOrMovableClass { void *iddBlock = nullptr; Device *device = nullptr; AllocationsList *reusableAllocationList = nullptr; + std::unique_ptr immediateReusableAllocationList; size_t reservedSshSize = 0; CommandStreamReceiver *immediateCmdListCsr = nullptr; IndirectHeap *sharedSshCsrHeap = nullptr; diff --git a/shared/test/unit_test/command_container/command_container_tests.cpp b/shared/test/unit_test/command_container/command_container_tests.cpp index 75cc60fa53..6f00230cb6 100644 --- a/shared/test/unit_test/command_container/command_container_tests.cpp +++ b/shared/test/unit_test/command_container/command_container_tests.cpp @@ -28,6 +28,7 @@ class MyMockCommandContainer : public CommandContainer { using CommandContainer::allocationIndirectHeaps; using CommandContainer::dirtyHeaps; using CommandContainer::getTotalCmdBufferSize; + using CommandContainer::immediateReusableAllocationList; }; struct CommandContainerHeapStateTests : public ::testing::Test { @@ -867,11 +868,12 @@ TEST_F(CommandContainerTest, givenCmdContainerWhenSetCmdBufferThenCmdBufferSetCo } TEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithoutAnyAllocationInListThenReturnNullptr) { - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); auto csr = pDevice->getDefaultEngine().commandStreamReceiver; cmdContainer->setImmediateCmdListCsr(csr); + cmdContainer->immediateReusableAllocationList = std::make_unique(); EXPECT_EQ(cmdContainer->reuseExistingCmdBuffer(), nullptr); @@ -880,13 +882,15 @@ TEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithoutA } HWTEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithAllocationInListAndCsrTaskCountLowerThanAllocationThenReturnNullptr) { - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); auto &csr = pDevice->getUltCommandStreamReceiver(); *csr.tagAddress = 0u; AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); cmdContainer->setImmediateCmdListCsr(&csr); + cmdContainer->immediateReusableAllocationList = std::make_unique(); + cmdContainer->getCmdBufferAllocations()[0]->updateTaskCount(10, 0); auto currectContainerSize = cmdContainer->getCmdBufferAllocations().size(); cmdContainer->addCurrentCommandBufferToReusableAllocationList(); @@ -899,13 +903,14 @@ HWTEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithAl } HWTEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithAllocationInListAndCsrTaskCountSameAsAllocationThenReturnAlloc) { - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); auto &csr = pDevice->getUltCommandStreamReceiver(); *csr.tagAddress = 10u; AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); cmdContainer->setImmediateCmdListCsr(&csr); + cmdContainer->immediateReusableAllocationList = std::make_unique(); cmdContainer->getCmdBufferAllocations()[0]->updateTaskCount(10, 0); cmdContainer->addCurrentCommandBufferToReusableAllocationList(); @@ -927,9 +932,11 @@ TEST_F(CommandContainerTest, GivenCmdContainerWhenContainerIsInitializedThenSurf } HWTEST_F(CommandContainerTest, givenCmdContainerHasImmediateCsrWhenGettingHeapWithoutEnsuringSpaceThenExpectNullptrReturnedOrUnrecoverable) { - CommandContainer cmdContainer; + MyMockCommandContainer cmdContainer; cmdContainer.enableHeapSharing(); cmdContainer.setImmediateCmdListCsr(pDevice->getDefaultEngine().commandStreamReceiver); + cmdContainer.immediateReusableAllocationList = std::make_unique(); + cmdContainer.setNumIddPerBlock(1); auto code = cmdContainer.initialize(pDevice, nullptr, true); EXPECT_EQ(CommandContainer::ErrorCode::SUCCESS, code); @@ -999,19 +1006,21 @@ struct MockHeapHelper : public HeapHelper { TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsThenAllocListsNotEmptyAndMadeResident) { DebugManagerStateRestore dbgRestore; DebugManager.flags.SetAmountOfReusableAllocations.set(1); - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); auto csr = pDevice->getDefaultEngine().commandStreamReceiver; AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, true); cmdContainer->setImmediateCmdListCsr(csr); + auto heapHelper = reinterpret_cast(cmdContainer->getHeapHelper()); - EXPECT_TRUE(allocList.peekIsEmpty()); + EXPECT_EQ(cmdContainer->immediateReusableAllocationList, nullptr); EXPECT_TRUE(heapHelper->storageForReuse->getAllocationsForReuse().peekIsEmpty()); auto actualResidencyContainerSize = cmdContainer->getResidencyContainer().size(); cmdContainer->fillReusableAllocationLists(); - EXPECT_FALSE(allocList.peekIsEmpty()); + ASSERT_NE(cmdContainer->immediateReusableAllocationList, nullptr); + EXPECT_FALSE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); EXPECT_FALSE(heapHelper->storageForReuse->getAllocationsForReuse().peekIsEmpty()); EXPECT_EQ(heapHelper->storageForReuse->getAllocationsForReuse().peekHead()->getResidencyTaskCount(csr->getOsContext().getContextId()), 1u); EXPECT_EQ(cmdContainer->getResidencyContainer().size(), actualResidencyContainerSize + 1); @@ -1067,30 +1076,68 @@ TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsWit TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsWithoutHeapsThenAllocListNotEmpty) { DebugManagerStateRestore dbgRestore; DebugManager.flags.SetAmountOfReusableAllocations.set(1); - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); - EXPECT_TRUE(allocList.peekIsEmpty()); + EXPECT_EQ(cmdContainer->immediateReusableAllocationList, nullptr); cmdContainer->fillReusableAllocationLists(); - EXPECT_FALSE(allocList.peekIsEmpty()); + EXPECT_FALSE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); cmdContainer.reset(); allocList.freeAllGraphicsAllocations(pDevice); } +TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsAndDestroyCmdContainerThenGlobalAllocListNotEmpty) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.SetAmountOfReusableAllocations.set(1); + auto cmdContainer = std::make_unique(); + AllocationsList allocList; + cmdContainer->initialize(pDevice, &allocList, false); + + EXPECT_EQ(cmdContainer->immediateReusableAllocationList, nullptr); + EXPECT_TRUE(allocList.peekIsEmpty()); + + cmdContainer->fillReusableAllocationLists(); + + EXPECT_FALSE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); + EXPECT_TRUE(allocList.peekIsEmpty()); + + cmdContainer.reset(); + + EXPECT_FALSE(allocList.peekIsEmpty()); + + allocList.freeAllGraphicsAllocations(pDevice); +} + +TEST_F(CommandContainerTest, givenCmdContainerWithoutGlobalListWhenFillReusableAllocationListsAndDestroyCmdContainerThenImmediateListUnused) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.SetAmountOfReusableAllocations.set(1); + auto cmdContainer = std::make_unique(); + cmdContainer->initialize(pDevice, nullptr, false); + + EXPECT_EQ(cmdContainer->immediateReusableAllocationList, nullptr); + cmdContainer->fillReusableAllocationLists(); + EXPECT_FALSE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); + cmdContainer->handleCmdBufferAllocations(0); + EXPECT_FALSE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); + + cmdContainer->immediateReusableAllocationList->freeAllGraphicsAllocations(pDevice); + cmdContainer->getCmdBufferAllocations().pop_back(); +} + TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsWithSpecifiedAmountThenAllocationsCreated) { DebugManagerStateRestore dbgRestore; DebugManager.flags.SetAmountOfReusableAllocations.set(10); - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); auto csr = pDevice->getDefaultEngine().commandStreamReceiver; AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); cmdContainer->setImmediateCmdListCsr(csr); - EXPECT_TRUE(allocList.peekIsEmpty()); + EXPECT_EQ(cmdContainer->immediateReusableAllocationList, nullptr); cmdContainer->fillReusableAllocationLists(); - EXPECT_EQ(allocList.peekHead()->countThisAndAllConnected(), 10u); + EXPECT_EQ(cmdContainer->immediateReusableAllocationList->peekHead()->countThisAndAllConnected(), 10u); cmdContainer.reset(); allocList.freeAllGraphicsAllocations(pDevice); @@ -1123,15 +1170,14 @@ TEST_F(CommandContainerTest, givenCmdContainerAndCsrWhenGetHeapWithRequiredSizeA TEST_F(CommandContainerTest, givenCmdContainerWhenFillReusableAllocationListsAndFlagDisabledThenAllocListEmpty) { DebugManagerStateRestore dbgRestore; DebugManager.flags.SetAmountOfReusableAllocations.set(0); - auto cmdContainer = std::make_unique(); + auto cmdContainer = std::make_unique(); auto csr = pDevice->getDefaultEngine().commandStreamReceiver; AllocationsList allocList; cmdContainer->initialize(pDevice, &allocList, false); cmdContainer->setImmediateCmdListCsr(csr); - EXPECT_TRUE(allocList.peekIsEmpty()); cmdContainer->fillReusableAllocationLists(); - EXPECT_TRUE(allocList.peekIsEmpty()); + EXPECT_TRUE(cmdContainer->immediateReusableAllocationList->peekIsEmpty()); cmdContainer.reset(); allocList.freeAllGraphicsAllocations(pDevice);