Create reusable list per immediate cmd list

Related-To: NEO-7361

Signed-off-by: Szymon Morek <szymon.morek@intel.com>
This commit is contained in:
Szymon Morek
2022-11-09 15:47:00 +00:00
committed by Compute-Runtime-Automation
parent 25a5ed0dca
commit aac8754e67
4 changed files with 76 additions and 20 deletions

View File

@ -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<size_t>(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<NEO::AllocationsList>();
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);
}

View File

@ -146,6 +146,7 @@ class CommandContainer : public NonCopyableOrMovableClass {
void *iddBlock = nullptr;
Device *device = nullptr;
AllocationsList *reusableAllocationList = nullptr;
std::unique_ptr<AllocationsList> immediateReusableAllocationList;
size_t reservedSshSize = 0;
CommandStreamReceiver *immediateCmdListCsr = nullptr;
IndirectHeap *sharedSshCsrHeap = nullptr;

View File

@ -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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
AllocationsList allocList;
cmdContainer->initialize(pDevice, &allocList, false);
auto csr = pDevice->getDefaultEngine().commandStreamReceiver;
cmdContainer->setImmediateCmdListCsr(csr);
cmdContainer->immediateReusableAllocationList = std::make_unique<NEO::AllocationsList>();
EXPECT_EQ(cmdContainer->reuseExistingCmdBuffer(), nullptr);
@ -880,13 +882,15 @@ TEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithoutA
}
HWTEST_F(CommandContainerTest, givenCmdContainerWhenReuseExistingCmdBufferWithAllocationInListAndCsrTaskCountLowerThanAllocationThenReturnNullptr) {
auto cmdContainer = std::make_unique<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
*csr.tagAddress = 0u;
AllocationsList allocList;
cmdContainer->initialize(pDevice, &allocList, false);
cmdContainer->setImmediateCmdListCsr(&csr);
cmdContainer->immediateReusableAllocationList = std::make_unique<NEO::AllocationsList>();
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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
*csr.tagAddress = 10u;
AllocationsList allocList;
cmdContainer->initialize(pDevice, &allocList, false);
cmdContainer->setImmediateCmdListCsr(&csr);
cmdContainer->immediateReusableAllocationList = std::make_unique<NEO::AllocationsList>();
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<NEO::AllocationsList>();
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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
auto csr = pDevice->getDefaultEngine().commandStreamReceiver;
AllocationsList allocList;
cmdContainer->initialize(pDevice, &allocList, true);
cmdContainer->setImmediateCmdListCsr(csr);
auto heapHelper = reinterpret_cast<MockHeapHelper *>(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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
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<MyMockCommandContainer>();
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<MyMockCommandContainer>();
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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
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<CommandContainer>();
auto cmdContainer = std::make_unique<MyMockCommandContainer>();
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);