mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Implementations instrumentation framework for OpenCV performance system;
This commit is contained in:
@@ -344,7 +344,7 @@ static struct __IppInitializer__ __ipp_initializer__;
|
||||
#ifdef CV_IPP_RUN_VERBOSE
|
||||
#define CV_IPP_RUN_(condition, func, ...) \
|
||||
{ \
|
||||
if (cv::ipp::useIPP() && (condition) && func) \
|
||||
if (cv::ipp::useIPP() && (condition) && (func)) \
|
||||
{ \
|
||||
printf("%s: IPP implementation is running\n", CV_Func); \
|
||||
fflush(stdout); \
|
||||
@@ -376,7 +376,7 @@ static struct __IppInitializer__ __ipp_initializer__;
|
||||
}
|
||||
#else
|
||||
#define CV_IPP_RUN_(condition, func, ...) \
|
||||
if (cv::ipp::useIPP() && (condition) && func) \
|
||||
if (cv::ipp::useIPP() && (condition) && (func)) \
|
||||
{ \
|
||||
CV_IMPL_ADD(CV_IMPL_IPP); \
|
||||
return __VA_ARGS__; \
|
||||
@@ -393,7 +393,7 @@ static struct __IppInitializer__ __ipp_initializer__;
|
||||
#define CV_IPP_RUN_FAST(func, ...)
|
||||
#endif
|
||||
|
||||
#define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_(condition, func, __VA_ARGS__)
|
||||
#define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_((condition), (func), __VA_ARGS__)
|
||||
|
||||
|
||||
#ifndef IPPI_CALL
|
||||
@@ -449,6 +449,135 @@ CV_EXPORTS void setUseTegra(bool flag);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_INSTRUMENTATION
|
||||
namespace cv
|
||||
{
|
||||
namespace instr
|
||||
{
|
||||
struct InstrTLSStruct
|
||||
{
|
||||
InstrTLSStruct()
|
||||
{
|
||||
pCurrentNode = NULL;
|
||||
}
|
||||
InstrNode* pCurrentNode;
|
||||
};
|
||||
|
||||
class InstrStruct
|
||||
{
|
||||
public:
|
||||
InstrStruct()
|
||||
{
|
||||
useInstr = false;
|
||||
enableMapping = true;
|
||||
|
||||
rootNode.m_payload = NodeData("ROOT", NULL, 0, TYPE_GENERAL, IMPL_PLAIN);
|
||||
tlsStruct.get()->pCurrentNode = &rootNode;
|
||||
}
|
||||
|
||||
Mutex mutexCreate;
|
||||
Mutex mutexCount;
|
||||
|
||||
bool useInstr;
|
||||
bool enableMapping;
|
||||
InstrNode rootNode;
|
||||
TLSData<InstrTLSStruct> tlsStruct;
|
||||
};
|
||||
|
||||
class CV_EXPORTS IntrumentationRegion
|
||||
{
|
||||
public:
|
||||
IntrumentationRegion(const char* funName, const char* fileName, int lineNum, int instrType = TYPE_GENERAL, int implType = IMPL_PLAIN);
|
||||
~IntrumentationRegion();
|
||||
|
||||
private:
|
||||
bool m_disabled; // region status
|
||||
uint64 m_regionTicks;
|
||||
};
|
||||
|
||||
InstrStruct& getInstrumentStruct();
|
||||
InstrTLSStruct& getInstrumentTLSStruct();
|
||||
CV_EXPORTS InstrNode* getCurrentNode();
|
||||
}
|
||||
}
|
||||
|
||||
///// General instrumentation
|
||||
// Instrument region
|
||||
#define CV_INSTRUMENT_REGION_META(TYPE, IMPL, ...) ::cv::instr::IntrumentationRegion __instr_region__(__FUNCTION__, __FILE__, __LINE__, TYPE, IMPL);
|
||||
// Instrument functions with non-void return type
|
||||
#define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\
|
||||
{\
|
||||
if(::cv::instr::useInstrumentation()){\
|
||||
::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, TYPE, IMPL);\
|
||||
try{\
|
||||
auto status = ((FUN)(__VA_ARGS__));\
|
||||
if(ERROR_COND){\
|
||||
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
|
||||
CV_INSTRUMENT_MARK_META(IMPL, ##FUN - BadExit);\
|
||||
}\
|
||||
return status;\
|
||||
}catch(...){\
|
||||
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
|
||||
CV_INSTRUMENT_MARK_META(IMPL, ##FUN - BadExit);\
|
||||
throw;\
|
||||
}\
|
||||
}else{\
|
||||
return ((FUN)(__VA_ARGS__));\
|
||||
}\
|
||||
}())
|
||||
// Instrument functions with void return type
|
||||
#define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\
|
||||
{\
|
||||
if(::cv::instr::useInstrumentation()){\
|
||||
::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, TYPE, IMPL);\
|
||||
try{\
|
||||
(FUN)(__VA_ARGS__);\
|
||||
}catch(...){\
|
||||
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
|
||||
CV_INSTRUMENT_MARK_META(IMPL, ##FUN - BadExit);\
|
||||
throw;\
|
||||
}\
|
||||
}else{\
|
||||
(FUN)(__VA_ARGS__);\
|
||||
}\
|
||||
}())
|
||||
// Instrumentation information marker
|
||||
#define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(#NAME, __FILE__, __LINE__, ::cv::instr::TYPE_MARKER, IMPL);}
|
||||
|
||||
///// General instrumentation
|
||||
// General OpenCV region instrumentation macro
|
||||
#define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_META(cv::instr::TYPE_GENERAL, cv::instr::IMPL_PLAIN)
|
||||
// Parallel OpenCV region instrumentation macro
|
||||
#define CV_INSTRUMENT_REGION_MT() CV_INSTRUMENT_REGION_MT_META(cv::instr::TYPE_GENERAL, cv::instr::IMPL_PLAIN)
|
||||
|
||||
///// IPP instrumentation
|
||||
// Wrapper region instrumentation macro
|
||||
#define CV_INSTRUMENT_REGION_IPP() CV_INSTRUMENT_REGION_META(::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
|
||||
// Function instrumentation macro
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, status < 0, FUN, __VA_ARGS__)
|
||||
// Diagnostic markers
|
||||
#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
|
||||
|
||||
///// OpenCL instrumentation
|
||||
// Wrapper region instrumentation macro
|
||||
#define CV_INSTRUMENT_REGION_OPENCL() CV_INSTRUMENT_REGION_META(::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
|
||||
// Function instrumentation macro
|
||||
#define CV_INSTRUMENT_FUN_OPENCL_KERNEL(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_OPENCL, status == 0, FUN, __VA_ARGS__)
|
||||
// Diagnostic markers
|
||||
#define CV_INSTRUMENT_MARK_OPENCL(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_OPENCL, NAME)
|
||||
#else
|
||||
#define CV_INSTRUMENT_REGION()
|
||||
#define CV_INSTRUMENT_REGION_MT()
|
||||
|
||||
#define CV_INSTRUMENT_REGION_IPP()
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
|
||||
#define CV_INSTRUMENT_MARK_IPP(NAME)
|
||||
|
||||
#define CV_INSTRUMENT_REGION_OPENCL()
|
||||
#define CV_INSTRUMENT_FUN_OPENCL_KERNEL(FUN, ...) ((FUN)(__VA_ARGS__))
|
||||
#define CV_INSTRUMENT_MARK_OPENCL(NAME)
|
||||
#endif
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_PRIVATE_HPP__
|
||||
|
||||
@@ -1002,6 +1002,137 @@ template<> inline std::string CommandLineParser::get<std::string>(const String&
|
||||
|
||||
//! @endcond
|
||||
|
||||
|
||||
// Basic Node class for tree building
|
||||
template<class OBJECT>
|
||||
class CV_EXPORTS Node
|
||||
{
|
||||
public:
|
||||
Node()
|
||||
{
|
||||
m_pParent = 0;
|
||||
}
|
||||
Node(OBJECT& payload) : m_payload(payload)
|
||||
{
|
||||
m_pParent = 0;
|
||||
}
|
||||
~Node()
|
||||
{
|
||||
removeChilds();
|
||||
if (m_pParent)
|
||||
{
|
||||
int idx = m_pParent->findChild(this);
|
||||
if (idx >= 0)
|
||||
m_pParent->m_childs.erase(m_pParent->m_childs.begin() + idx);
|
||||
}
|
||||
}
|
||||
|
||||
Node<OBJECT>* findChild(OBJECT& payload) const
|
||||
{
|
||||
for(int i = 0; i < this->m_childs.size(); i++)
|
||||
{
|
||||
if(this->m_childs[i]->m_payload == payload)
|
||||
return this->m_childs[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int findChild(Node<OBJECT> *pNode) const
|
||||
{
|
||||
for (int i = 0; i < this->m_childs.size(); i++)
|
||||
{
|
||||
if(this->m_childs[i] == pNode)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void addChild(Node<OBJECT> *pNode)
|
||||
{
|
||||
if(!pNode)
|
||||
return;
|
||||
|
||||
CV_Assert(pNode->m_pParent == 0);
|
||||
pNode->m_pParent = this;
|
||||
this->m_childs.push_back(pNode);
|
||||
}
|
||||
|
||||
void removeChilds()
|
||||
{
|
||||
for(int i = 0; i < m_childs.size(); i++)
|
||||
{
|
||||
m_childs[i]->m_pParent = 0; // avoid excessive parent vector trimming
|
||||
delete m_childs[i];
|
||||
}
|
||||
m_childs.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
OBJECT m_payload;
|
||||
Node<OBJECT>* m_pParent;
|
||||
std::vector<Node<OBJECT>*> m_childs;
|
||||
};
|
||||
|
||||
// Instrumentation external interface
|
||||
namespace instr
|
||||
{
|
||||
enum
|
||||
{
|
||||
TYPE_GENERAL = 0, // OpenCV API function, e.g. exported function
|
||||
TYPE_MARKER, // Information marker
|
||||
TYPE_WRAPPER, // Wrapper function for implementation
|
||||
TYPE_FUN, // Simple function call
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
IMPL_PLAIN = 0,
|
||||
IMPL_IPP,
|
||||
IMPL_OPENCL,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FLAGS_MAPPING = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COMMAND_RESET = 0x01,
|
||||
};
|
||||
|
||||
class CV_EXPORTS NodeData
|
||||
{
|
||||
public:
|
||||
NodeData(const char* funName = 0, const char* fileName = NULL, int lineNum = 0, int instrType = TYPE_GENERAL, int implType = IMPL_PLAIN);
|
||||
NodeData(NodeData &ref);
|
||||
~NodeData();
|
||||
NodeData& operator=(const NodeData&);
|
||||
|
||||
cv::String m_funName;
|
||||
int m_instrType;
|
||||
int m_implType;
|
||||
cv::String m_fileName;
|
||||
int m_lineNum;
|
||||
|
||||
bool m_funError;
|
||||
volatile int m_counter;
|
||||
bool m_stopPoint;
|
||||
uint64 m_ticksMean;
|
||||
|
||||
};
|
||||
bool operator==(const NodeData& lhs, const NodeData& rhs);
|
||||
|
||||
typedef Node<NodeData> InstrNode;
|
||||
|
||||
CV_EXPORTS bool useInstrumentation();
|
||||
CV_EXPORTS void setUseInstrumentation(bool flag);
|
||||
CV_EXPORTS InstrNode* getTrace();
|
||||
CV_EXPORTS void resetTrace();
|
||||
CV_EXPORTS void setFlags(int modeFlags);
|
||||
CV_EXPORTS int getFlags();
|
||||
};
|
||||
|
||||
} //namespace cv
|
||||
|
||||
#ifndef DISABLE_OPENCV_24_COMPATIBILITY
|
||||
|
||||
Reference in New Issue
Block a user