From b2f286fc4aa2e94ffa577edf6e475479246933ca Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Thu, 9 Dec 2021 14:09:54 +0000 Subject: [PATCH] Reuse command buffers in L0 command queue Signed-off-by: Lukasz Jobczyk --- level_zero/core/source/cmdqueue/cmdqueue.cpp | 20 ++++++++++++++----- .../core/source/cmdqueue/cmdqueue_hw.inl | 2 +- .../core/source/cmdqueue/cmdqueue_imp.h | 2 +- .../sources/cmdqueue/test_cmdqueue_2.cpp | 16 +++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/level_zero/core/source/cmdqueue/cmdqueue.cpp b/level_zero/core/source/cmdqueue/cmdqueue.cpp index b12a4ddfb7..18ff4ddf90 100644 --- a/level_zero/core/source/cmdqueue/cmdqueue.cpp +++ b/level_zero/core/source/cmdqueue/cmdqueue.cpp @@ -178,8 +178,18 @@ ze_result_t CommandQueueImp::CommandBufferManager::initialize(Device *device, si false, device->getNEODevice()->getDeviceBitfield()}; - buffers[BUFFER_ALLOCATION::FIRST] = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties); - buffers[BUFFER_ALLOCATION::SECOND] = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties); + auto firstBuffer = device->obtainReusableAllocation(alignedSize, NEO::GraphicsAllocation::AllocationType::COMMAND_BUFFER); + if (!firstBuffer) { + firstBuffer = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties); + } + + auto secondBuffer = device->obtainReusableAllocation(alignedSize, NEO::GraphicsAllocation::AllocationType::COMMAND_BUFFER); + if (!secondBuffer) { + secondBuffer = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties); + } + + buffers[BUFFER_ALLOCATION::FIRST] = firstBuffer; + buffers[BUFFER_ALLOCATION::SECOND] = secondBuffer; if (!buffers[BUFFER_ALLOCATION::FIRST] || !buffers[BUFFER_ALLOCATION::SECOND]) { return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; @@ -192,13 +202,13 @@ ze_result_t CommandQueueImp::CommandBufferManager::initialize(Device *device, si return ZE_RESULT_SUCCESS; } -void CommandQueueImp::CommandBufferManager::destroy(NEO::MemoryManager *memoryManager) { +void CommandQueueImp::CommandBufferManager::destroy(Device *device) { if (buffers[BUFFER_ALLOCATION::FIRST]) { - memoryManager->freeGraphicsMemory(buffers[BUFFER_ALLOCATION::FIRST]); + device->storeReusableAllocation(*buffers[BUFFER_ALLOCATION::FIRST]); buffers[BUFFER_ALLOCATION::FIRST] = nullptr; } if (buffers[BUFFER_ALLOCATION::SECOND]) { - memoryManager->freeGraphicsMemory(buffers[BUFFER_ALLOCATION::SECOND]); + device->storeReusableAllocation(*buffers[BUFFER_ALLOCATION::SECOND]); buffers[BUFFER_ALLOCATION::SECOND] = nullptr; } } diff --git a/level_zero/core/source/cmdqueue/cmdqueue_hw.inl b/level_zero/core/source/cmdqueue/cmdqueue_hw.inl index 925432e478..df807a7481 100644 --- a/level_zero/core/source/cmdqueue/cmdqueue_hw.inl +++ b/level_zero/core/source/cmdqueue/cmdqueue_hw.inl @@ -55,7 +55,7 @@ ze_result_t CommandQueueHw::destroy() { delete commandStream; commandStream = nullptr; } - buffers.destroy(this->getDevice()->getNEODevice()->getMemoryManager()); + buffers.destroy(this->getDevice()); delete this; return ZE_RESULT_SUCCESS; } diff --git a/level_zero/core/source/cmdqueue/cmdqueue_imp.h b/level_zero/core/source/cmdqueue/cmdqueue_imp.h index 31834067e1..1a1a1306e8 100644 --- a/level_zero/core/source/cmdqueue/cmdqueue_imp.h +++ b/level_zero/core/source/cmdqueue/cmdqueue_imp.h @@ -36,7 +36,7 @@ struct CommandQueueImp : public CommandQueue { }; ze_result_t initialize(Device *device, size_t sizeRequested); - void destroy(NEO::MemoryManager *memoryManager); + void destroy(Device *device); void switchBuffers(NEO::CommandStreamReceiver *csr); NEO::GraphicsAllocation *getCurrentBufferAllocation() { diff --git a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_2.cpp b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_2.cpp index a218283cff..3a7b4e41bc 100644 --- a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_2.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_2.cpp @@ -506,6 +506,22 @@ TEST_F(CommandQueueInitTests, givenMultipleSubDevicesWhenInitializingThenAllocat commandQueue->destroy(); } +TEST_F(CommandQueueInitTests, whenDestroyCommandQueueThenStoreCommandBuffersAsReusableAllocations) { + ze_command_queue_desc_t desc = {}; + auto csr = std::unique_ptr(neoDevice->createCommandStreamReceiver()); + csr->setupContext(*neoDevice->getDefaultEngine().osContext); + + ze_result_t returnValue; + L0::CommandQueue *commandQueue = CommandQueue::create(productFamily, device, csr.get(), &desc, false, false, returnValue); + EXPECT_NE(nullptr, commandQueue); + auto deviceImp = static_cast(device); + EXPECT_TRUE(deviceImp->allocationsForReuse.peekIsEmpty()); + + commandQueue->destroy(); + + EXPECT_FALSE(deviceImp->allocationsForReuse.peekIsEmpty()); +} + struct DeviceWithDualStorage : Test { void SetUp() override { NEO::MockCompilerEnableGuard mock(true);