Revert "performance: Ensure hostptrs removed before creating new one"

This reverts commit 5b2f2f3d83.

Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:
Lukasz Jobczyk
2024-10-21 08:51:59 +00:00
committed by Compute-Runtime-Automation
parent ff80a02fcb
commit 8a647f6a39
14 changed files with 56 additions and 87 deletions

View File

@@ -30,7 +30,7 @@ struct ClearQueueTest : public ::testing::Test,
static void threadMethod(MockDeferredDeleter *deleter) {
while (!startClear)
;
deleter->clearQueue(false);
deleter->clearQueue();
threadStopped++;
}
MockDeferrableDeletion *createDeletion() {

View File

@@ -213,13 +213,13 @@ TEST_F(DeferredDeleterTest, WhenSettingDoWorkInBackgroundThenThreadShouldStopIsS
}
TEST_F(DeferredDeleterTest, givenDeferredDeleterWhenBlockingDrainIsCalledThenArElementsReleasedIsCalled) {
deleter->drain(true, false);
deleter->drain(true);
EXPECT_NE(0, deleter->areElementsReleasedCalled);
EXPECT_EQ(1, deleter->drainCalled);
}
TEST_F(DeferredDeleterTest, givenDeferredDeleterWhenNonBlockingDrainIsCalledThenArElementsReleasedIsNotCalled) {
deleter->drain(false, false);
deleter->drain(false);
EXPECT_EQ(0, deleter->areElementsReleasedCalled);
EXPECT_EQ(1, deleter->drainCalled);
}

View File

@@ -14,8 +14,5 @@ class DeferrableDeletion : public IDNode<DeferrableDeletion> {
template <typename... Args>
static DeferrableDeletion *create(Args... args);
virtual bool apply() = 0;
bool isExternalHostptr() const { return externalHostptr; }
bool externalHostptr = false;
};
} // namespace NEO

View File

@@ -11,7 +11,10 @@
#include "shared/source/os_interface/os_thread.h"
namespace NEO {
DeferredDeleter::DeferredDeleter() = default;
DeferredDeleter::DeferredDeleter() {
doWorkInBackground = false;
elementsToRelease = 0;
}
void DeferredDeleter::stop() {
// Called with threadMutex acquired
@@ -32,7 +35,7 @@ void DeferredDeleter::stop() {
// Delete working thread
worker.reset();
}
drain(false, false);
drain(false);
}
void DeferredDeleter::safeStop() {
@@ -46,14 +49,8 @@ DeferredDeleter::~DeferredDeleter() {
void DeferredDeleter::deferDeletion(DeferrableDeletion *deletion) {
std::unique_lock<std::mutex> lock(queueMutex);
this->elementsToRelease++;
if (deletion->isExternalHostptr()) {
this->hostptrsToRelease++;
}
elementsToRelease++;
queue.pushTailOne(*deletion);
lock.unlock();
condition.notify_one();
}
@@ -79,8 +76,8 @@ void DeferredDeleter::ensureThread() {
worker = Thread::createFunc(run, reinterpret_cast<void *>(this));
}
bool DeferredDeleter::areElementsReleased(bool hostptrsOnly) {
return hostptrsOnly ? this->hostptrsToRelease == 0 : this->elementsToRelease == 0;
bool DeferredDeleter::areElementsReleased() {
return elementsToRelease == 0;
}
bool DeferredDeleter::shouldStop() {
@@ -99,7 +96,7 @@ void *DeferredDeleter::run(void *arg) {
}
lock.unlock();
// Delete items placed into deferred delete queue
self->clearQueue(false);
self->clearQueue();
lock.lock();
// Check whether working thread should be stopped
} while (!self->shouldStop());
@@ -107,28 +104,24 @@ void *DeferredDeleter::run(void *arg) {
return nullptr;
}
void DeferredDeleter::drain(bool blocking, bool hostptrsOnly) {
clearQueue(hostptrsOnly);
void DeferredDeleter::drain(bool blocking) {
clearQueue();
if (blocking) {
while (!areElementsReleased(hostptrsOnly))
while (!areElementsReleased())
;
}
}
void DeferredDeleter::clearQueue(bool hostptrsOnly) {
void DeferredDeleter::clearQueue() {
do {
auto deletion = queue.removeFrontOne();
if (deletion) {
bool isDeletionHostptr = deletion->isExternalHostptr();
if ((!hostptrsOnly || isDeletionHostptr) && deletion->apply()) {
this->elementsToRelease--;
if (isDeletionHostptr) {
this->hostptrsToRelease--;
}
if (deletion->apply()) {
elementsToRelease--;
} else {
queue.pushTailOne(*deletion.release());
}
}
} while (hostptrsOnly ? !areElementsReleased(hostptrsOnly) : !queue.peekIsEmpty());
} while (!queue.peekIsEmpty());
}
} // namespace NEO

View File

@@ -29,21 +29,20 @@ class DeferredDeleter {
MOCKABLE_VIRTUAL void removeClient();
MOCKABLE_VIRTUAL void drain(bool blocking, bool hostptrsOnly);
MOCKABLE_VIRTUAL void drain(bool blocking);
protected:
void stop();
void safeStop();
void ensureThread();
MOCKABLE_VIRTUAL void clearQueue(bool hostptrsOnly);
MOCKABLE_VIRTUAL bool areElementsReleased(bool hostptrsOnly);
MOCKABLE_VIRTUAL void clearQueue();
MOCKABLE_VIRTUAL bool areElementsReleased();
MOCKABLE_VIRTUAL bool shouldStop();
static void *run(void *);
std::atomic<bool> doWorkInBackground = false;
std::atomic<int> elementsToRelease = 0;
std::atomic<int> hostptrsToRelease = 0;
std::atomic<bool> doWorkInBackground;
std::atomic<int> elementsToRelease;
std::unique_ptr<Thread> worker;
int32_t numClients = 0;
IDList<DeferrableDeletion, true> queue;

View File

@@ -190,7 +190,7 @@ void *MemoryManager::allocateSystemMemory(size_t size, size_t alignment) {
GraphicsAllocation *MemoryManager::allocateGraphicsMemoryWithHostPtr(const AllocationData &allocationData) {
if (deferredDeleter) {
deferredDeleter->drain(true, false);
deferredDeleter->drain(true);
}
GraphicsAllocation *graphicsAllocation = nullptr;
auto osStorage = hostPtrManager->prepareOsStorageForAllocation(*this, allocationData.size, allocationData.hostPtr, allocationData.rootDeviceIndex);
@@ -307,7 +307,7 @@ void MemoryManager::checkGpuUsageAndDestroyGraphicsAllocations(GraphicsAllocatio
if (gfxAllocation->isUsed()) {
if (gfxAllocation->isUsedByManyOsContexts()) {
multiContextResourceDestructor->deferDeletion(new DeferrableAllocationDeletion{*this, *gfxAllocation});
multiContextResourceDestructor->drain(false, false);
multiContextResourceDestructor->drain(false);
return;
}
for (auto &engine : getRegisteredEngines(gfxAllocation->getRootDeviceIndex())) {
@@ -337,7 +337,7 @@ bool MemoryManager::isLimitedRange(uint32_t rootDeviceIndex) {
void MemoryManager::waitForDeletions() {
if (deferredDeleter) {
deferredDeleter->drain(false, false);
deferredDeleter->drain(false);
}
deferredDeleter.reset(nullptr);
}
@@ -735,12 +735,6 @@ bool MemoryManager::mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) {
}
GraphicsAllocation *MemoryManager::allocateGraphicsMemory(const AllocationData &allocationData) {
if (allocationData.type == AllocationType::externalHostPtr &&
allocationData.hostPtr &&
this->getDeferredDeleter()) {
this->getDeferredDeleter()->drain(true, true);
}
if (allocationData.type == AllocationType::image || allocationData.type == AllocationType::sharedResourceCopy) {
UNRECOVERABLE_IF(allocationData.imgInfo == nullptr);
return allocateGraphicsMemoryForImage(allocationData);

View File

@@ -7,7 +7,6 @@
#include "shared/source/os_interface/windows/deferrable_deletion_win.h"
#include "shared/source/memory_manager/allocation_type.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
namespace NEO {
@@ -16,10 +15,9 @@ template <typename... Args>
DeferrableDeletion *DeferrableDeletion::create(Args... args) {
return new DeferrableDeletionImpl(std::forward<Args>(args)...);
}
template DeferrableDeletion *DeferrableDeletion::create(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle);
template DeferrableDeletion *DeferrableDeletion::create(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type);
DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type)
DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle)
: wddm(wddm), allocationCount(allocationCount), resourceHandle(resourceHandle) {
if (handles) {
this->handles = new D3DKMT_HANDLE[allocationCount];
@@ -27,15 +25,12 @@ DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *
this->handles[i] = handles[i];
}
}
this->externalHostptr = type == AllocationType::externalHostPtr;
}
bool DeferrableDeletionImpl::apply() {
[[maybe_unused]] bool destroyStatus = wddm->destroyAllocations(handles, allocationCount, resourceHandle);
DEBUG_BREAK_IF(!destroyStatus);
return true;
}
DeferrableDeletionImpl::~DeferrableDeletionImpl() {
if (handles) {
delete[] handles;

View File

@@ -15,11 +15,10 @@ namespace NEO {
class OsContextWin;
class Wddm;
enum class AllocationType;
class DeferrableDeletionImpl : public DeferrableDeletion {
public:
DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type);
DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle);
bool apply() override;
~DeferrableDeletionImpl() override;

View File

@@ -811,8 +811,8 @@ void WddmMemoryManager::handleFenceCompletion(GraphicsAllocation *allocation) {
bool WddmMemoryManager::tryDeferDeletions(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, uint32_t rootDeviceIndex, AllocationType type) {
bool status = true;
if (deferredDeleter) {
deferredDeleter->deferDeletion(DeferrableDeletion::create(&getWddm(rootDeviceIndex), handles, allocationCount, resourceHandle, type));
if (deferredDeleter && type != AllocationType::externalHostPtr) {
deferredDeleter->deferDeletion(DeferrableDeletion::create(&getWddm(rootDeviceIndex), handles, allocationCount, resourceHandle));
} else {
status = getWddm(rootDeviceIndex).destroyAllocations(handles, allocationCount, resourceHandle);
}
@@ -1035,7 +1035,7 @@ bool WddmMemoryManager::mapGpuVaForOneHandleAllocation(WddmAllocation *allocatio
auto status = getWddm(allocation->getRootDeviceIndex()).mapGpuVirtualAddress(allocation->getDefaultGmm(), allocation->getDefaultHandle(), minimumAddress, maximumAddress, addressToMap, allocation->getGpuAddressToModify(), allocation->getAllocationType());
if (!status && deferredDeleter) {
deferredDeleter->drain(true, false);
deferredDeleter->drain(true);
status = getWddm(allocation->getRootDeviceIndex()).mapGpuVirtualAddress(allocation->getDefaultGmm(), allocation->getDefaultHandle(), minimumAddress, maximumAddress, addressToMap, allocation->getGpuAddressToModify(), allocation->getAllocationType());
}
if (!status) {
@@ -1081,7 +1081,7 @@ bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *alloca
gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress, allocation->getAllocationType());
if (!status && deferredDeleter) {
deferredDeleter->drain(true, false);
deferredDeleter->drain(true);
status = wddm.mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress, allocation->getAllocationType());
}
@@ -1104,7 +1104,7 @@ bool WddmMemoryManager::createGpuAllocationsWithRetry(WddmAllocation *allocation
auto gmm = allocation->getGmm(handleId);
auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
if (status == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) {
deferredDeleter->drain(true, false);
deferredDeleter->drain(true);
status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify());
}
if (status != STATUS_SUCCESS) {

View File

@@ -34,20 +34,19 @@ void MockDeferredDeleter::removeClient() {
--numClients;
}
void MockDeferredDeleter::drain(bool blocking, bool hostptrsOnly) {
void MockDeferredDeleter::drain(bool blocking) {
if (expectDrainCalled) {
EXPECT_EQ(expectedDrainValue, blocking);
}
DeferredDeleter::drain(blocking, hostptrsOnly);
DeferredDeleter::drain(blocking);
drainCalled++;
}
void MockDeferredDeleter::drain() {
return drain(true, false);
return drain(true);
}
bool MockDeferredDeleter::areElementsReleased(bool hostptrsOnly) {
this->areElementsReleasedCalledForHostptrs = hostptrsOnly;
bool MockDeferredDeleter::areElementsReleased() {
areElementsReleasedCalled++;
return areElementsReleasedCalled != 1;
}
@@ -66,8 +65,8 @@ bool MockDeferredDeleter::shouldStop() {
return shouldStopCalled > 1;
}
void MockDeferredDeleter::clearQueue(bool hostptrsOnly) {
DeferredDeleter::clearQueue(hostptrsOnly);
void MockDeferredDeleter::clearQueue() {
DeferredDeleter::clearQueue();
clearCalled++;
}
@@ -101,7 +100,7 @@ void MockDeferredDeleter::setDoWorkInBackgroundValue(bool value) {
}
bool MockDeferredDeleter::baseAreElementsReleased() {
return DeferredDeleter::areElementsReleased(false);
return DeferredDeleter::areElementsReleased();
}
bool MockDeferredDeleter::baseShouldStop() {

View File

@@ -22,9 +22,9 @@ class MockDeferredDeleter : public DeferredDeleter {
void removeClient() override;
void drain(bool blocking, bool hostptrsOnly) override;
void drain(bool blocking) override;
bool areElementsReleased(bool hostptrsOnly) override;
bool areElementsReleased() override;
bool shouldStop() override;
@@ -56,8 +56,6 @@ class MockDeferredDeleter : public DeferredDeleter {
int areElementsReleasedCalled = 0;
bool areElementsReleasedCalledForHostptrs = false;
std::atomic<int> shouldStopCalled;
std::atomic<int> clearCalled;
@@ -75,6 +73,6 @@ class MockDeferredDeleter : public DeferredDeleter {
bool expectDrainCalled = false;
void clearQueue(bool hostptrsOnly) override;
void clearQueue() override;
};
} // namespace NEO

View File

@@ -23,23 +23,14 @@ TEST(DeferredDeleter, WhenDeferredDeleterIsCreatedThenItIsNotAssignable) {
TEST(DeferredDeleter, givenDeferredDeleterWhenBlockingDrainIsCalledThenArElementsReleasedIsCalled) {
auto deleter = std::make_unique<MockDeferredDeleter>();
deleter->drain(true, false);
deleter->drain(true);
EXPECT_NE(0, deleter->areElementsReleasedCalled);
EXPECT_FALSE(deleter->areElementsReleasedCalledForHostptrs);
EXPECT_EQ(1, deleter->drainCalled);
}
TEST(DeferredDeleter, givenDeferredDeleterWhenBlockingDrainOnlyForHostptrsIsCalledThenArElementsReleasedIsCalledWithHostptrsOnly) {
auto deleter = std::make_unique<MockDeferredDeleter>();
deleter->drain(true, true);
EXPECT_NE(0, deleter->areElementsReleasedCalled);
EXPECT_TRUE(deleter->areElementsReleasedCalledForHostptrs);
EXPECT_EQ(1, deleter->drainCalled);
}
TEST(DeferredDeleter, givenDeferredDeleterWhenNonBlockingDrainIsCalledThenArElementsReleasedIsNotCalled) {
auto deleter = std::make_unique<MockDeferredDeleter>();
deleter->drain(false, false);
deleter->drain(false);
EXPECT_EQ(0, deleter->areElementsReleasedCalled);
EXPECT_EQ(1, deleter->drainCalled);
}

View File

@@ -51,21 +51,18 @@ class DeferrableDeletionTest : public ::testing::Test {
};
TEST_F(DeferrableDeletionTest, givenDeferrableDeletionWhenIsCreatedThenObjectMembersAreSetProperly) {
MockDeferrableDeletion deletion(wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::buffer);
MockDeferrableDeletion deletion(wddm.get(), &handle, allocationCount, resourceHandle);
EXPECT_EQ(wddm.get(), deletion.wddm);
EXPECT_NE(nullptr, deletion.handles);
EXPECT_EQ(handle, *deletion.handles);
EXPECT_NE(&handle, deletion.handles);
EXPECT_EQ(allocationCount, deletion.allocationCount);
EXPECT_EQ(resourceHandle, deletion.resourceHandle);
EXPECT_FALSE(deletion.isExternalHostptr());
MockDeferrableDeletion deletion2(wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::externalHostPtr);
EXPECT_TRUE(deletion2.isExternalHostptr());
}
TEST_F(DeferrableDeletionTest, givenDeferrableDeletionWhenApplyIsCalledThenDeletionIsApplied) {
wddm->callBaseDestroyAllocations = false;
std::unique_ptr<DeferrableDeletion> deletion(DeferrableDeletion::create((Wddm *)wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::buffer));
std::unique_ptr<DeferrableDeletion> deletion(DeferrableDeletion::create((Wddm *)wddm.get(), &handle, allocationCount, resourceHandle));
EXPECT_EQ(0u, wddm->destroyAllocationResult.called);
deletion->apply();
EXPECT_EQ(1u, wddm->destroyAllocationResult.called);

View File

@@ -4032,6 +4032,13 @@ struct WddmMemoryManagerWithAsyncDeleterTest : public ::testing::Test {
WddmMock *wddm;
};
TEST_F(WddmMemoryManagerWithAsyncDeleterTest, givenWddmWhenAsyncDeleterIsEnabledThenDoNotDeferExternalHostptrDeletions) {
EXPECT_EQ(0, deleter->deferDeletionCalled);
memoryManager->tryDeferDeletions(nullptr, 0, 0, 0, AllocationType::externalHostPtr);
EXPECT_EQ(0, deleter->deferDeletionCalled);
EXPECT_EQ(1u, wddm->destroyAllocationResult.called);
}
TEST_F(WddmMemoryManagerWithAsyncDeleterTest, givenWddmWhenAsyncDeleterIsEnabledThenCanDeferDeletions) {
EXPECT_EQ(0, deleter->deferDeletionCalled);
memoryManager->tryDeferDeletions(nullptr, 0, 0, 0, AllocationType::unknown);