From da8dbf6cf5db60a1a1d4b3461af871db29ffd52e Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 6 Jul 2017 17:57:05 +0300 Subject: [PATCH] ocl: async cl_buffer cleanup queue (for event callback) --- modules/core/include/opencv2/core/mat.hpp | 4 ++- modules/core/src/ocl.cpp | 47 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 92d34c1..37ed556 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -497,7 +497,9 @@ struct CV_EXPORTS UMatData { enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2, DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24, - USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64}; + USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64, + ASYNC_CLEANUP=128 + }; UMatData(const MatAllocator* allocator); ~UMatData(); diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 4e30d6b..196cefc 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -42,6 +42,7 @@ #include "precomp.hpp" #include #include +#include #include #include #include // std::cerr @@ -1983,7 +1984,10 @@ struct Kernel::Impl if( u[i] ) { if( CV_XADD(&u[i]->urefcount, -1) == 1 ) + { + u[i]->flags |= UMatData::ASYNC_CLEANUP; u[i]->currAllocator->deallocate(u[i]); + } u[i] = 0; } nu = 0; @@ -3157,6 +3161,10 @@ public: matStdAllocator = Mat::getDefaultAllocator(); } + ~OpenCLAllocator() + { + flushCleanupQueue(); + } UMatData* defaultAllocate(int dims, const int* sizes, int type, void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const @@ -3193,6 +3201,7 @@ public: } Context& ctx = Context::getDefault(); + flushCleanupQueue(); int createFlags = 0, flags0 = 0; getBestFlags(ctx, flags, usageFlags, createFlags, flags0); @@ -3247,6 +3256,8 @@ public: if(!u) return false; + flushCleanupQueue(); + UMatDataAutoLock lock(u); if(u->handle == 0) @@ -3381,6 +3392,15 @@ public: CV_Assert(u->handle != 0); CV_Assert(u->mapcount == 0); + + if (u->flags & UMatData::ASYNC_CLEANUP) + addToCleanupQueue(u); + else + deallocate_(u); + } + + void deallocate_(UMatData* u) const + { if(u->tempUMat()) { CV_Assert(u->origdata); @@ -4184,6 +4204,33 @@ public: } MatAllocator* matStdAllocator; + + mutable cv::Mutex cleanupQueueMutex; + mutable std::deque cleanupQueue; + + void flushCleanupQueue() const + { + if (!cleanupQueue.empty()) + { + std::deque q; + { + cv::AutoLock lock(cleanupQueueMutex); + q.swap(cleanupQueue); + } + for (std::deque::const_iterator i = q.begin(); i != q.end(); ++i) + { + deallocate_(*i); + } + } + } + void addToCleanupQueue(UMatData* u) const + { + //TODO: Validation check: CV_Assert(!u->tempUMat()); + { + cv::AutoLock lock(cleanupQueueMutex); + cleanupQueue.push_back(u); + } + } }; MatAllocator* getOpenCLAllocator() -- 2.7.4