Re-use temporary allocations

Resolves: NEO-4123

Change-Id: I44e9de4f1bf576adbbe8d69d1ec2c6ae1bbca35f
Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:
Lukasz Jobczyk
2020-04-15 13:39:09 +02:00
committed by sys_ocldev
parent 11edcd8fc9
commit eabed40e3e
6 changed files with 52 additions and 22 deletions

View File

@@ -855,7 +855,7 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, InForced32BitAllocationsModeStore3
auto newScratchAllocation = commandStreamReceiver->getScratchAllocation();
EXPECT_NE(scratchAllocation, newScratchAllocation); // Allocation changed
std::unique_ptr<GraphicsAllocation> allocationTemporary = commandStreamReceiver->getTemporaryAllocations().detachAllocation(0, *commandStreamReceiver, GraphicsAllocation::AllocationType::SCRATCH_SURFACE);
std::unique_ptr<GraphicsAllocation> allocationTemporary = commandStreamReceiver->getTemporaryAllocations().detachAllocation(0, nullptr, *commandStreamReceiver, GraphicsAllocation::AllocationType::SCRATCH_SURFACE);
EXPECT_EQ(scratchAllocation, allocationTemporary.get());
pDevice->getMemoryManager()->freeGraphicsMemory(allocationTemporary.release());

View File

@@ -496,6 +496,22 @@ struct CreateAllocationForHostSurfaceTest : public ::testing::Test {
CommandStreamReceiver *commandStreamReceiver = nullptr;
};
TEST_F(CreateAllocationForHostSurfaceTest, givenTemporaryAllocationWhenCreateAllocationForHostSurfaceThenReuseTemporaryAllocationWhenSizeAndAddressMatch) {
auto hostPtr = reinterpret_cast<void *>(0x1234);
size_t size = 100;
auto temporaryAllocation = std::make_unique<MemoryAllocation>(0, GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR, hostPtr, size, 0, MemoryPool::System4KBPages);
auto allocationPtr = temporaryAllocation.get();
temporaryAllocation->updateTaskCount(0u, 0u);
commandStreamReceiver->getInternalAllocationStorage()->storeAllocation(std::move(temporaryAllocation), TEMPORARY_ALLOCATION);
*commandStreamReceiver->getTagAddress() = 1u;
HostPtrSurface hostSurface(hostPtr, size);
commandStreamReceiver->createAllocationForHostSurface(hostSurface, false);
auto hostSurfaceAllocationPtr = hostSurface.getAllocation();
EXPECT_EQ(allocationPtr, hostSurfaceAllocationPtr);
}
TEST_F(CreateAllocationForHostSurfaceTest, givenReadOnlyHostPointerWhenAllocationForHostSurfaceWithPtrCopyAllowedIsCreatedThenCopyAllocationIsCreatedAndMemoryCopied) {
const char memory[8] = {1, 2, 3, 4, 5, 6, 7, 8};
size_t size = sizeof(memory);

View File

@@ -421,29 +421,34 @@ AllocationsList &CommandStreamReceiver::getTemporaryAllocations() { return inter
AllocationsList &CommandStreamReceiver::getAllocationsForReuse() { return internalAllocationStorage->getAllocationsForReuse(); }
bool CommandStreamReceiver::createAllocationForHostSurface(HostPtrSurface &surface, bool requiresL3Flush) {
auto memoryManager = getMemoryManager();
AllocationProperties properties{rootDeviceIndex,
false, // allocateMemory
surface.getSurfaceSize(), GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR,
false, // isMultiStorageAllocation
osContext->getDeviceBitfield()};
properties.flags.flushL3RequiredForRead = properties.flags.flushL3RequiredForWrite = requiresL3Flush;
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties, surface.getMemoryPointer());
if (allocation == nullptr && surface.peekIsPtrCopyAllowed()) {
// Try with no host pointer allocation and copy
AllocationProperties copyProperties{rootDeviceIndex, surface.getSurfaceSize(), GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY};
copyProperties.alignment = MemoryConstants::pageSize;
allocation = memoryManager->allocateGraphicsMemoryWithProperties(copyProperties);
if (allocation) {
memcpy_s(allocation->getUnderlyingBuffer(), allocation->getUnderlyingBufferSize(), surface.getMemoryPointer(), surface.getSurfaceSize());
auto allocation = internalAllocationStorage->obtainTemporaryAllocationWithPtr(surface.getSurfaceSize(), surface.getMemoryPointer(), GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR);
if (allocation == nullptr) {
auto memoryManager = getMemoryManager();
AllocationProperties properties{rootDeviceIndex,
false, // allocateMemory
surface.getSurfaceSize(), GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR,
false, // isMultiStorageAllocation
osContext->getDeviceBitfield()};
properties.flags.flushL3RequiredForRead = properties.flags.flushL3RequiredForWrite = requiresL3Flush;
allocation.reset(memoryManager->allocateGraphicsMemoryWithProperties(properties, surface.getMemoryPointer()));
if (allocation == nullptr && surface.peekIsPtrCopyAllowed()) {
// Try with no host pointer allocation and copy
AllocationProperties copyProperties{rootDeviceIndex, surface.getSurfaceSize(), GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY};
copyProperties.alignment = MemoryConstants::pageSize;
allocation.reset(memoryManager->allocateGraphicsMemoryWithProperties(copyProperties));
if (allocation) {
memcpy_s(allocation->getUnderlyingBuffer(), allocation->getUnderlyingBufferSize(), surface.getMemoryPointer(), surface.getSurfaceSize());
}
}
}
if (allocation == nullptr) {
return false;
}
allocation->updateTaskCount(CompletionStamp::levelNotReady, osContext->getContextId());
surface.setAllocation(allocation);
internalAllocationStorage->storeAllocation(std::unique_ptr<GraphicsAllocation>(allocation), TEMPORARY_ALLOCATION);
surface.setAllocation(allocation.get());
internalAllocationStorage->storeAllocation(std::move(allocation), TEMPORARY_ALLOCATION);
return true;
}

View File

@@ -15,7 +15,7 @@ class CommandStreamReceiver;
class AllocationsList : public IDList<GraphicsAllocation, true, true> {
public:
std::unique_ptr<GraphicsAllocation> detachAllocation(size_t requiredMinimalSize, CommandStreamReceiver &commandStreamReceiver, GraphicsAllocation::AllocationType allocationType);
std::unique_ptr<GraphicsAllocation> detachAllocation(size_t requiredMinimalSize, const void *requiredPtr, CommandStreamReceiver &commandStreamReceiver, GraphicsAllocation::AllocationType allocationType);
private:
GraphicsAllocation *detachAllocationImpl(GraphicsAllocation *, void *);

View File

@@ -62,7 +62,12 @@ void InternalAllocationStorage::freeAllocationsList(uint32_t waitTaskCount, Allo
}
std::unique_ptr<GraphicsAllocation> InternalAllocationStorage::obtainReusableAllocation(size_t requiredSize, GraphicsAllocation::AllocationType allocationType) {
auto allocation = allocationsForReuse.detachAllocation(requiredSize, commandStreamReceiver, allocationType);
auto allocation = allocationsForReuse.detachAllocation(requiredSize, nullptr, commandStreamReceiver, allocationType);
return allocation;
}
std::unique_ptr<GraphicsAllocation> InternalAllocationStorage::obtainTemporaryAllocationWithPtr(size_t requiredSize, const void *requiredPtr, GraphicsAllocation::AllocationType allocationType) {
auto allocation = temporaryAllocations.detachAllocation(requiredSize, requiredPtr, commandStreamReceiver, allocationType);
return allocation;
}
@@ -71,14 +76,16 @@ struct ReusableAllocationRequirements {
volatile uint32_t *csrTagAddress;
GraphicsAllocation::AllocationType allocationType;
uint32_t contextId;
const void *requiredPtr;
};
std::unique_ptr<GraphicsAllocation> AllocationsList::detachAllocation(size_t requiredMinimalSize, CommandStreamReceiver &commandStreamReceiver, GraphicsAllocation::AllocationType allocationType) {
std::unique_ptr<GraphicsAllocation> AllocationsList::detachAllocation(size_t requiredMinimalSize, const void *requiredPtr, CommandStreamReceiver &commandStreamReceiver, GraphicsAllocation::AllocationType allocationType) {
ReusableAllocationRequirements req;
req.requiredMinimalSize = requiredMinimalSize;
req.csrTagAddress = commandStreamReceiver.getTagAddress();
req.allocationType = allocationType;
req.contextId = commandStreamReceiver.getOsContext().getContextId();
req.requiredPtr = requiredPtr;
GraphicsAllocation *a = nullptr;
GraphicsAllocation *retAlloc = processLocked<AllocationsList, &AllocationsList::detachAllocationImpl>(a, static_cast<void *>(&req));
return std::unique_ptr<GraphicsAllocation>(retAlloc);
@@ -91,7 +98,8 @@ GraphicsAllocation *AllocationsList::detachAllocationImpl(GraphicsAllocation *,
auto currentTagValue = *req->csrTagAddress;
if ((req->allocationType == curr->getAllocationType()) &&
(curr->getUnderlyingBufferSize() >= req->requiredMinimalSize) &&
(currentTagValue >= curr->getTaskCount(req->contextId))) {
(currentTagValue >= curr->getTaskCount(req->contextId)) &&
(req->requiredPtr == nullptr || req->requiredPtr == curr->getUnderlyingBuffer())) {
return removeOneImpl(curr, nullptr);
}
curr = curr->next;

View File

@@ -19,6 +19,7 @@ class InternalAllocationStorage {
void storeAllocation(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage);
void storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage, uint32_t taskCount);
std::unique_ptr<GraphicsAllocation> obtainReusableAllocation(size_t requiredSize, GraphicsAllocation::AllocationType allocationType);
std::unique_ptr<GraphicsAllocation> obtainTemporaryAllocationWithPtr(size_t requiredSize, const void *requiredPtr, GraphicsAllocation::AllocationType allocationType);
AllocationsList &getTemporaryAllocations() { return temporaryAllocations; }
AllocationsList &getAllocationsForReuse() { return allocationsForReuse; }