1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2020-03-17 13:23:33 +03:00
24 changed files with 565 additions and 145 deletions
+17
View File
@@ -81,6 +81,23 @@ if(HAVE_MEMALIGN)
ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_MEMALIGN=1")
endif()
option(OPENCV_ENABLE_ALLOCATOR_STATS "Enable Allocator metrics" ON)
if(NOT OPENCV_ENABLE_ALLOCATOR_STATS)
add_definitions(-DOPENCV_DISABLE_ALLOCATOR_STATS=1)
else()
if(NOT DEFINED OPENCV_ALLOCATOR_STATS_COUNTER_TYPE)
if(HAVE_ATOMIC_LONG_LONG AND OPENCV_ENABLE_ATOMIC_LONG_LONG)
set(OPENCV_ALLOCATOR_STATS_COUNTER_TYPE "long long")
else()
set(OPENCV_ALLOCATOR_STATS_COUNTER_TYPE "int")
endif()
endif()
message(STATUS "Allocator metrics storage type: '${OPENCV_ALLOCATOR_STATS_COUNTER_TYPE}'")
add_definitions("-DOPENCV_ALLOCATOR_STATS_COUNTER_TYPE=${OPENCV_ALLOCATOR_STATS_COUNTER_TYPE}")
endif()
ocv_create_module(${extra_libs})
ocv_target_link_libraries(${the_module} PRIVATE
@@ -1564,81 +1564,10 @@ OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_uint32x4, vec_uint4)
OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_int32x4, vec_int4)
OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_float32x4, vec_float4)
template<int i>
inline v_int8x16 v_broadcast_element(v_int8x16 v)
{
return v_int8x16(vec_perm(v.val, v.val, vec_splats((unsigned char)i)));
}
template<int i, typename Tvec>
inline Tvec v_broadcast_element(const Tvec& v)
{ return Tvec(vec_splat(v.val, i)); }
template<int i>
inline v_uint8x16 v_broadcast_element(v_uint8x16 v)
{
return v_uint8x16(vec_perm(v.val, v.val, vec_splats((unsigned char)i)));
}
template<int i>
inline v_int16x8 v_broadcast_element(v_int16x8 v)
{
unsigned char t0 = 2*i, t1 = 2*i + 1;
vec_uchar16 p = {t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1};
return v_int16x8(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_uint16x8 v_broadcast_element(v_uint16x8 v)
{
unsigned char t0 = 2*i, t1 = 2*i + 1;
vec_uchar16 p = {t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1, t0, t1};
return v_uint16x8(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_int32x4 v_broadcast_element(v_int32x4 v)
{
unsigned char t0 = 4*i, t1 = 4*i + 1, t2 = 4*i + 2, t3 = 4*i + 3;
vec_uchar16 p = {t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3};
return v_int32x4(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_uint32x4 v_broadcast_element(v_uint32x4 v)
{
unsigned char t0 = 4*i, t1 = 4*i + 1, t2 = 4*i + 2, t3 = 4*i + 3;
vec_uchar16 p = {t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3};
return v_uint32x4(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_int64x2 v_broadcast_element(v_int64x2 v)
{
unsigned char t0 = 8*i, t1 = 8*i + 1, t2 = 8*i + 2, t3 = 8*i + 3, t4 = 8*i + 4, t5 = 8*i + 5, t6 = 8*i + 6, t7 = 8*i + 7;
vec_uchar16 p = {t0, t1, t2, t3, t4, t5, t6, t7, t0, t1, t2, t3, t4, t5, t6, t7};
return v_int64x2(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_uint64x2 v_broadcast_element(v_uint64x2 v)
{
unsigned char t0 = 8*i, t1 = 8*i + 1, t2 = 8*i + 2, t3 = 8*i + 3, t4 = 8*i + 4, t5 = 8*i + 5, t6 = 8*i + 6, t7 = 8*i + 7;
vec_uchar16 p = {t0, t1, t2, t3, t4, t5, t6, t7, t0, t1, t2, t3, t4, t5, t6, t7};
return v_uint64x2(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_float32x4 v_broadcast_element(v_float32x4 v)
{
unsigned char t0 = 4*i, t1 = 4*i + 1, t2 = 4*i + 2, t3 = 4*i + 3;
vec_uchar16 p = {t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3, t0, t1, t2, t3};
return v_float32x4(vec_perm(v.val, v.val, p));
}
template<int i>
inline v_float64x2 v_broadcast_element(v_float64x2 v)
{
unsigned char t0 = 8*i, t1 = 8*i + 1, t2 = 8*i + 2, t3 = 8*i + 3, t4 = 8*i + 4, t5 = 8*i + 5, t6 = 8*i + 6, t7 = 8*i + 7;
vec_uchar16 p = {t0, t1, t2, t3, t4, t5, t6, t7, t0, t1, t2, t3, t4, t5, t6, t7};
return v_float64x2(vec_perm(v.val, v.val, p));
}
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
@@ -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
};
@@ -72,6 +72,10 @@ public:
CV_Assert(alignment % sizeof(T) == 0);
CV_Assert((alignment & (alignment - 1)) == 0);
allocate_((void**)(&ptr), static_cast<ushort>(sizeof(T)), count, alignment);
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
if (safe)
#endif
CV_Assert(ptr != NULL);
}
/** @brief Fill one of buffers with zeroes
@@ -118,9 +122,11 @@ private:
private:
class Block;
std::vector<Block> blocks;
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
void * oneBuf;
size_t totalSize;
const bool safe;
#endif
};
//! @}
+26 -10
View File
@@ -5,14 +5,10 @@
#include "opencv2/core/utils/buffer_area.private.hpp"
#include "opencv2/core/utils/configuration.private.hpp"
#ifdef OPENCV_ENABLE_MEMORY_SANITIZER
#define BUFFER_AREA_DEFAULT_MODE true
#else
#define BUFFER_AREA_DEFAULT_MODE false
#endif
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
static bool CV_BUFFER_AREA_OVERRIDE_SAFE_MODE =
cv::utils::getConfigurationParameterBool("OPENCV_BUFFER_AREA_ALWAYS_SAFE", BUFFER_AREA_DEFAULT_MODE);
cv::utils::getConfigurationParameterBool("OPENCV_BUFFER_AREA_ALWAYS_SAFE", false);
#endif
namespace cv { namespace utils {
@@ -58,6 +54,7 @@ public:
*ptr = raw_mem;
}
}
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
void * fast_allocate(void * buf) const
{
CV_Assert(ptr && *ptr == NULL);
@@ -66,6 +63,7 @@ public:
*ptr = buf;
return static_cast<void*>(static_cast<uchar*>(*ptr) + type_size * count);
}
#endif
bool operator==(void **other) const
{
CV_Assert(ptr && other);
@@ -86,12 +84,20 @@ private:
//==================================================================================================
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
BufferArea::BufferArea(bool safe_) :
oneBuf(0),
totalSize(0),
safe(safe_ || CV_BUFFER_AREA_OVERRIDE_SAFE_MODE)
{
// nothing
}
#else
BufferArea::BufferArea(bool safe_)
{
CV_UNUSED(safe_);
}
#endif
BufferArea::~BufferArea()
{
@@ -101,10 +107,16 @@ BufferArea::~BufferArea()
void BufferArea::allocate_(void **ptr, ushort type_size, size_t count, ushort alignment)
{
blocks.push_back(Block(ptr, type_size, count, alignment));
if (safe)
blocks.back().real_allocate();
else
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
if (!safe)
{
totalSize += blocks.back().getByteCount();
}
else
#endif
{
blocks.back().real_allocate();
}
}
void BufferArea::zeroFill_(void **ptr)
@@ -129,6 +141,7 @@ void BufferArea::zeroFill()
void BufferArea::commit()
{
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
if (!safe)
{
CV_Assert(totalSize > 0);
@@ -141,6 +154,7 @@ void BufferArea::commit()
ptr = i->fast_allocate(ptr);
}
}
#endif
}
void BufferArea::release()
@@ -150,11 +164,13 @@ void BufferArea::release()
i->cleanup();
}
blocks.clear();
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
if (oneBuf)
{
fastFree(oneBuf);
oneBuf = 0;
}
#endif
}
//==================================================================================================
+2 -2
View File
@@ -638,9 +638,9 @@ int getNumThreads(void)
#elif defined HAVE_CONCURRENCY
return 1 + (pplScheduler == 0
return (pplScheduler == 0)
? Concurrency::CurrentScheduler::Get()->GetNumberOfVirtualProcessors()
: pplScheduler->GetNumberOfVirtualProcessors());
: (1 + pplScheduler->GetNumberOfVirtualProcessors());
#elif defined HAVE_PTHREADS_PF