|
|
|
@ -11,32 +11,55 @@ |
|
|
|
|
#include <atomic> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
//#define OPENCV_DISABLE_ALLOCATOR_STATS
|
|
|
|
|
|
|
|
|
|
namespace cv { namespace utils { |
|
|
|
|
|
|
|
|
|
#ifndef OPENCV_ALLOCATOR_STATS_COUNTER_TYPE |
|
|
|
|
#if defined(__GNUC__) && (\ |
|
|
|
|
(defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4) || \
|
|
|
|
|
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) \
|
|
|
|
|
) |
|
|
|
|
#define OPENCV_ALLOCATOR_STATS_COUNTER_TYPE int |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifndef OPENCV_ALLOCATOR_STATS_COUNTER_TYPE |
|
|
|
|
#define OPENCV_ALLOCATOR_STATS_COUNTER_TYPE long long |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef CV__ALLOCATOR_STATS_LOG |
|
|
|
|
namespace { |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
class AllocatorStatistics : public AllocatorStatisticsInterface |
|
|
|
|
{ |
|
|
|
|
protected: |
|
|
|
|
#ifdef CV_CXX11 |
|
|
|
|
std::atomic<long long> curr, total, total_allocs, peak; |
|
|
|
|
#else |
|
|
|
|
volatile long long curr, total, total_allocs, peak; // overflow is possible, CV_XADD operates with 'int' only
|
|
|
|
|
#endif |
|
|
|
|
#ifdef OPENCV_DISABLE_ALLOCATOR_STATS |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
AllocatorStatistics() |
|
|
|
|
#ifndef CV_CXX11 |
|
|
|
|
: curr(0), total(0), total_allocs(0), peak(0) |
|
|
|
|
#endif |
|
|
|
|
{} |
|
|
|
|
AllocatorStatistics() {} |
|
|
|
|
~AllocatorStatistics() CV_OVERRIDE {} |
|
|
|
|
|
|
|
|
|
// AllocatorStatisticsInterface
|
|
|
|
|
uint64_t getCurrentUsage() const CV_OVERRIDE { return 0; } |
|
|
|
|
uint64_t getTotalUsage() const CV_OVERRIDE { return 0; } |
|
|
|
|
uint64_t getNumberOfAllocations() const CV_OVERRIDE { return 0; } |
|
|
|
|
uint64_t getPeakUsage() const CV_OVERRIDE { return 0; } |
|
|
|
|
|
|
|
|
|
/** set peak usage = current usage */ |
|
|
|
|
void resetPeakUsage() CV_OVERRIDE {}; |
|
|
|
|
|
|
|
|
|
void onAllocate(size_t /*sz*/) {} |
|
|
|
|
void onFree(size_t /*sz*/) {} |
|
|
|
|
|
|
|
|
|
#elif defined(CV_CXX11) |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
typedef OPENCV_ALLOCATOR_STATS_COUNTER_TYPE counter_t; |
|
|
|
|
std::atomic<counter_t> curr, total, total_allocs, peak; |
|
|
|
|
public: |
|
|
|
|
AllocatorStatistics() {} |
|
|
|
|
~AllocatorStatistics() CV_OVERRIDE {} |
|
|
|
|
|
|
|
|
|
#ifdef CV_CXX11 |
|
|
|
|
uint64_t getCurrentUsage() const CV_OVERRIDE { return (uint64_t)curr.load(); } |
|
|
|
|
uint64_t getTotalUsage() const CV_OVERRIDE { return (uint64_t)total.load(); } |
|
|
|
|
uint64_t getNumberOfAllocations() const CV_OVERRIDE { return (uint64_t)total_allocs.load(); } |
|
|
|
@ -52,7 +75,7 @@ public: |
|
|
|
|
CV__ALLOCATOR_STATS_LOG(cv::format("allocate: %lld (curr=%lld)", (long long int)sz, (long long int)curr.load())); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
long long new_curr = curr.fetch_add((long long)sz) + (long long)sz; |
|
|
|
|
counter_t new_curr = curr.fetch_add((counter_t)sz) + (counter_t)sz; |
|
|
|
|
|
|
|
|
|
// peak = std::max((uint64_t)peak, new_curr);
|
|
|
|
|
auto prev_peak = peak.load(); |
|
|
|
@ -63,7 +86,7 @@ public: |
|
|
|
|
} |
|
|
|
|
// end of peak = max(...)
|
|
|
|
|
|
|
|
|
|
total += (long long)sz; |
|
|
|
|
total += (counter_t)sz; |
|
|
|
|
total_allocs++; |
|
|
|
|
} |
|
|
|
|
void onFree(size_t sz) |
|
|
|
@ -71,10 +94,20 @@ public: |
|
|
|
|
#ifdef CV__ALLOCATOR_STATS_LOG |
|
|
|
|
CV__ALLOCATOR_STATS_LOG(cv::format("free: %lld (curr=%lld)", (long long int)sz, (long long int)curr.load())); |
|
|
|
|
#endif |
|
|
|
|
curr -= (long long)sz; |
|
|
|
|
curr -= (counter_t)sz; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
#else // non C++11
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
typedef OPENCV_ALLOCATOR_STATS_COUNTER_TYPE counter_t; |
|
|
|
|
volatile counter_t curr, total, total_allocs, peak; // overflow is possible, CV_XADD operates with 'int' only
|
|
|
|
|
public: |
|
|
|
|
AllocatorStatistics() |
|
|
|
|
: curr(0), total(0), total_allocs(0), peak(0) |
|
|
|
|
{} |
|
|
|
|
~AllocatorStatistics() CV_OVERRIDE {} |
|
|
|
|
|
|
|
|
|
uint64_t getCurrentUsage() const CV_OVERRIDE { return (uint64_t)curr; } |
|
|
|
|
uint64_t getTotalUsage() const CV_OVERRIDE { return (uint64_t)total; } |
|
|
|
|
uint64_t getNumberOfAllocations() const CV_OVERRIDE { return (uint64_t)total_allocs; } |
|
|
|
@ -89,21 +122,21 @@ public: |
|
|
|
|
CV__ALLOCATOR_STATS_LOG(cv::format("allocate: %lld (curr=%lld)", (long long int)sz, (long long int)curr)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
uint64_t new_curr = (uint64_t)CV_XADD(&curr, (uint64_t)sz) + sz; |
|
|
|
|
counter_t new_curr = (counter_t)CV_XADD(&curr, (counter_t)sz) + (counter_t)sz; |
|
|
|
|
|
|
|
|
|
peak = std::max((uint64_t)peak, new_curr); // non-thread safe
|
|
|
|
|
peak = std::max((counter_t)peak, new_curr); // non-thread safe
|
|
|
|
|
|
|
|
|
|
//CV_XADD(&total, (uint64_t)sz); // overflow with int, non-reliable...
|
|
|
|
|
total += sz; |
|
|
|
|
|
|
|
|
|
CV_XADD(&total_allocs, (uint64_t)1); |
|
|
|
|
CV_XADD(&total_allocs, (counter_t)1); |
|
|
|
|
} |
|
|
|
|
void onFree(size_t sz) |
|
|
|
|
{ |
|
|
|
|
#ifdef CV__ALLOCATOR_STATS_LOG |
|
|
|
|
CV__ALLOCATOR_STATS_LOG(cv::format("free: %lld (curr=%lld)", (long long int)sz, (long long int)curr)); |
|
|
|
|
#endif |
|
|
|
|
CV_XADD(&curr, (uint64_t)-sz); |
|
|
|
|
CV_XADD(&curr, (counter_t)-sz); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|