在公司里做视觉AI落地,少不了参考和移植OpenCV的源码。譬如最常见的Mat类对象,做一个减均值的操作,用起来一句话,底层实现其实一堆,调试下来真的是冰山一角的感觉。今天就来说说非SIMD优化情况下的MatExpr到Mat的赋值是怎么实现的。
用的是OpenCV 3.4.9版本,基本上和最新(4.3.0)版本的实现一致。基于VS2017,VSCode,Git,GitBash等工具。
0. HighLevel的函数调用:
Mat a(3, 3, CV_64FC1, Scalar::all(1));
Mat b = a - 1.5;
看,是不是很简单?一个3x3的double类型的矩阵,元素取值都是1;所有元素都减去1.5(也就是Python中所谓的broadcast广播,Matlab中也有类似的原生支持功能)。
实际上断点调试一下就发现没那么简单。1.5
是double双精度浮点数,会被转换为Scalar对象;Mat对象和Scalar对象相减,结果是MatExpr类型,是做了转换才得到Mat类型的。等价于:
Mat a(3, 3, CV_64FC1, Scalar::all(1));
Scalar c = 1.5;
MatExpr d = a - c;
Mat e = d;
只关注Mat e=d
这一步,看似无聊没用,但如果是移植OpenCV为自己的产品所用,发现这其中还不是简单的调试断点就能搞清楚的。
先尝试了最简单的断点调试(需要OpenCV源码debug模式编译),关键几个调用:
image.png image.png image.png image.png
其中
getAddTab()
的一个trick是,函数内用static变量作为返回值,由于存储在静态存储区并且用编译阶段确定的函数名来赋值,因此我们调试进来的时候就晚了(没赶在初始化之前设定断点),于是我稍微修改后得以停留。不过并没有什么用,cv::hal::add64f
并不能跳转到定义。
接下来就贴一下,add64f
是怎么被定义和调用的(简单说来,它是用宏trick来定义函数的,个人觉得比较hack)。
1. getAddTab()
返回的是函数指针数组,为什么它返回的时候我没法设断点?
因为是static局部变量,并且用已经存在的函数初始化的。程序一旦运行,这个局部变量的值就确定了,也就是被初始化过了,当然没法设断点了。搞他!
//static BinaryFuncC addTab[] =
//{
// (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s),
// (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s),
// (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32s),
// (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f), (BinaryFuncC)cv::hal::add64f,
// 0
//};
BinaryFuncC a[8];
a[0] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u);
a[1] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s);
a[2] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u);
a[3] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s);
a[4] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32s);
a[5] = (BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f);
a[6] = (BinaryFuncC)cv::hal::add64f;
a[7] = 0;
static BinaryFuncC addTab[] = {
a[0], a[1], a[2], a[3], a[4], a[5], a[6],a[7]
};
2. 后续其它函数中,发现调用的是函数指针表中的索引为6的,也就是cv::hal::add64f
函数。
这个函数在哪里实现的?
能够断点到这个宏:
DEFINE_SIMD_ALL(add, op_add)
接着断点到如下模板函数:(arithm.simd.hpp
)
#if !CV_SIMD_64F
template<template<typename T1, typename Tvec> class OP, typename T1, typename Tvec>
static void bin_loop_nosimd(const T1* src1, size_t step1, const T1* src2, size_t step2, T1* dst, size_t step, int width, int height)
{
typedef OP<T1, Tvec/*dummy*/> op;
step1 /= sizeof(T1);
step2 /= sizeof(T1);
step /= sizeof(T1);
for (; height--; src1 += step1, src2 += step2, dst += step)
{
int x = 0;
for (; x <= width - 4; x += 4)
{
T1 t0 = op::r(src1[x], src2[x]);
T1 t1 = op::r(src1[x + 1], src2[x + 1]);
dst[x] = t0; dst[x + 1] = t1;
t0 = op::r(src1[x + 2], src2[x + 2]);
t1 = op::r(src1[x + 3], src2[x + 3]);
dst[x + 2] = t0; dst[x + 3] = t1;
}
for (; x < width; x++)
dst[x] = op::r(src1[x], src2[x]);
}
}
为啥会运行到这个函数呢?
3. 调用堆栈:为了搞清楚为啥来这里执行,看看call stack:
arithm_hal_debug_call_stack1.png字太小了,只看函数名吧:
arithm_hal_debug_call_stack2.png
发现栈顶的两次调用,都是cv::hal::cpu_baseline
命名空间(namespace)下的函数。咋没见到这个namespace的定义呢?
其实是有的,但是写成宏定义了。(很垃圾的编码风格。为什么不写namespace而要用宏呢?)
其中,栈顶函数bin_loop_nosimd()
就是刚刚贴出来的naive实现的函数(模板函数);栈顶之下紧接着的函数cv::hal::cpu_baseline::add64f()
就是前面贴出来的宏DEFINE_SIMD_ALL(add, op_add)
。
4. VS不给做静态语法解析了
那就手动解析:
DEFINE_SIMD_ALL(add, op_add)
第一次展开为:
DEFINE_SIMD_SAT(add, op_add) \
DEFINE_SIMD_NSAT(add, op_add)
第二次展开为:
DEFINE_SIMD_U8(add, op_add) \
DEFINE_SIMD_S8(add, op_add) \
DEFINE_SIMD_U16(add, op_add) \
DEFINE_SIMD_S16(add, op_add) \
DEFINE_SIMD_S32(add, op_add) \
DEFINE_SIMD_F32(add, op_add) \
DEFINE_SIMD_F64(add, op_add)
从DEFINE_SIMD_U8
入手,第一次展开为:
DEFINE_SIMD(__CV_CAT(add, 8u), uchar, v_uint8, op_add)
其中__CV_CAT
是做字符串拼接(##
连接符实现),因而第二次展开为:
DEFINE_SIMD(add8u, uchar, v_uint8, op_add)
arithm_hal_debug_call_stack4.png
实际上,arithm.cpp中的函数,naive的实现和SIMD的实现的切换,恐怕就是DEFINE_SIMD
宏了。
现在我更感兴趣的是,任意的op函数的宏跳转DEFINE_SIMD_ALL(fun, ...)
展开。目前展开为
DEFINE_SIMD(__CV_CAT(fun, 8u), uchar, v_uint8, __VA_ARGS__) \
DEFINE_SIMD(__CV_CAT(fun, 8s), schar, v_int8, __VA_ARGS__) \
DEFINE_SIMD(__CV_CAT(fun, 16u), ushort, v_uint16, __VA_ARGS__) \
DEFINE_SIMD(__CV_CAT(fun, 16s), short, v_int16, __VA_ARGS__) \
DEFINE_SIMD(__CV_CAT(fun, 32s), int, v_int32, __VA_ARGS__) \
DEFINE_SIMD(__CV_CAT(fun, 32f), float, v_float32, __VA_ARGS__) \
DEFINE_NOSIMD(__CV_CAT(fun, 64f), double, __VA_ARGS__)
好吧,fun
还是换成具体的函数名字比较直观。
DEFINE_SIMD_U8(add, op_add)
进一步展开为:
DECLARE_SIMD_FUN(fun_name, uchar) \
DEFINE_SIMD_FUN(fun_name, uchar, v_uint8, op_add)
意思是先声明一个函数,再定义这个函数。呃,用宏定义来实现函数声明和定义,看起来是反射,但是这也太蛋疼了。
大概看一下DEFINE_SIMD_FUN
怎么定义的函数?
#define DEFINE_SIMD_FUN(fun, _T1, _Tvec, _OP) \
void fun(BIN_ARGS(_T1)) \
{ \
CV_INSTRUMENT_REGION(); \
bin_loop<_OP, _T1, _Tvec>(BIN_ARGS_PASS); \
}
哦对了,如果是double类型的数据,那么有时候(我这里关掉所有优化,就是这种情况),调用的是这个:
#define DEFINE_NOSIMD_FUN(fun, _T1, _OP) \
void fun(BIN_ARGS(_T1)) \
{ \
CV_INSTRUMENT_REGION(); \
bin_loop_nosimd<_OP, _T1, v_float64>(BIN_ARGS_PASS); \
}
至此,终于串起来了前面断点中的函数调用栈的栈顶和次栈顶,以及栈中其它函数。
实际上,MatExpr到Mat的转换,会执行计算。也即是,Mat和Scalar之间的计算,被转换为MatExpr对象,此对象并不立即做计算(MatExpr意思其实就是Math/Matrix Expression),而是到了MatExpr转为Mat的时候再计算。
前面写到的无法跳转的函数add8u
和add64f
等函数,完整的展开是:
DEFINE_SIMD_ALL(add, op_add)
=>
DEFINE_SIMD_U8(add, op_add) \
DEFINE_SIMD_S8(add, op_add) \
DEFINE_SIMD_U16(add, op_add) \
DEFINE_SIMD_S16(add, op_add) \
DEFINE_SIMD_S32(add, op_add) \
DEFINE_SIMD_F32(add, op_add) \
DEFINE_SIMD_F64(add, op_add)
=>
DEFINE_SIMD(__CV_CAT(add, 8u), uchar, v_uint8, op_add) \
DEFINE_SIMD(__CV_CAT(add, 8s), schar, v_int8, op_add) \
DEFINE_SIMD(__CV_CAT(add, 16u), ushort, v_uint16, op_add) \
DEFINE_SIMD(__CV_CAT(add, 16s), short, v_int16, op_add) \
DEFINE_SIMD(__CV_CAT(add, 32s), int, v_int32, op_add) \
DEFINE_SIMD(__CV_CAT(add, 32f), float, v_float32, op_add) \
DEFINE_NOSIMD(__CV_CAT(add, 64f), double, op_add)
=>
DEFINE_SIMD(add8u, uchar, v_uint8, op_add) \
DEFINE_SIMD(add8s, schar, v_int8, op_add) \
DEFINE_SIMD(add16u, ushort, v_uint16, op_add) \
DEFINE_SIMD(add16s, short, v_int16, op_add) \
DEFINE_SIMD(add32s, int, v_int32, op_add) \
DEFINE_SIMD(add32f, float, v_float32, op_add) \
DEFINE_NOSIMD(add64f, double, op_add)
=>
DECLARE_SIMD_FUN(add8u, uchar) \
DEFINE_SIMD_FUN(add8u, uchar, v_uint8, op_add) \
DECLARE_SIMD_FUN(add8s, schar) \
DEFINE_SIMD_FUN(add8s, schar, v_int8, op_add) \
DECLARE_SIMD_FUN(add16u, ushort) \
DEFINE_SIMD_FUN(add16u, ushort, v_uint16, op_add) \
DECLARE_SIMD_FUN(add16s, short) \
DEFINE_SIMD_FUN(add16s, short, v_int16, op_add) \
DECLARE_SIMD_FUN(add32s, int) \
DEFINE_SIMD_FUN(add32s, int, v_int32, op_add) \
DECLARE_SIMD_FUN(add32f, float) \
DEFINE_SIMD_FUN(add32f, float, v_float32, op_add) \
DECLARE_SIMD_FUN(add64f, double) \
DEFINE_NOSIMD_FUN(add64f, double, op_add)
在Visual Studio里勾选“生成预编译文件”以及“包括注释”
image.png
然后,可以看到add8u
等函数的定义(arithm.dispatch.i
)
void add8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void add8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void add8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void add8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void add16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void add16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void add16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void add16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void add32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void add32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void add32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void add32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop<op_add, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void add64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void add64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn539 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn539 = { &(__cv_trace_location_extra_fn539), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 539, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn539);;; bin_loop_nosimd<op_add, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
void sub8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void sub8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void sub8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void sub8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void sub16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void sub16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void sub16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void sub16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void sub32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void sub32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void sub32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void sub32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop<op_sub, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void sub64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void sub64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn540 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn540 = { &(__cv_trace_location_extra_fn540), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 540, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn540);;; bin_loop_nosimd<op_sub, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
void min8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void min8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void min8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void min8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void min16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void min16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void min16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void min16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void min32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void min32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void min32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void min32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop<op_min, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void min64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void min64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn542 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn542 = { &(__cv_trace_location_extra_fn542), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 542, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn542);;; bin_loop_nosimd<op_min, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
void max8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void max8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void max8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void max8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void max16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void max16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void max16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void max16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void max32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void max32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void max32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void max32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop<op_max, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void max64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void max64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn543 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn543 = { &(__cv_trace_location_extra_fn543), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 543, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn543);;; bin_loop_nosimd<op_max, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
void absdiff8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void absdiff8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); } void absdiff8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height); void absdiff8s(const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, schar, v_int8>(src1, step1, src2, step2, dst, step, width, height); } void absdiff16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height); void absdiff16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, ushort, v_uint16>(src1, step1, src2, step2, dst, step, width, height); } void absdiff16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height); void absdiff16s(const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, short, v_int16>(src1, step1, src2, step2, dst, step, width, height); } void absdiff32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height); void absdiff32s(const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, int, v_int32>(src1, step1, src2, step2, dst, step, width, height); } void absdiff32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height); void absdiff32f(const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop<op_absdiff, float, v_float32>(src1, step1, src2, step2, dst, step, width, height); } void absdiff64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height); void absdiff64f(const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn545 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn545 = { &(__cv_trace_location_extra_fn545), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 545, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn545);;; bin_loop_nosimd<op_absdiff, double, v_float64>(src1, step1, src2, step2, dst, step, width, height); }
void or8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void or8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn547 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn547 = { &(__cv_trace_location_extra_fn547), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 547, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn547);;; bin_loop<op_or, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
void xor8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void xor8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn548 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn548 = { &(__cv_trace_location_extra_fn548), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 548, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn548);;; bin_loop<op_xor, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
void and8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height); void and8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height) { ; static cv::utils::trace::details::Region::LocationExtraData* __cv_trace_location_extra_fn549 = 0; static const cv::utils::trace::details::Region::LocationStaticStorage __cv_trace_location_fn549 = { &(__cv_trace_location_extra_fn549), __FUNCSIG__ , "e:\\dev\\opencv-3.4.9\\modules\\core\\src\\arithm.simd.hpp", 549, ((0) | cv::utils::trace::details::REGION_FLAG_FUNCTION)};; const cv::utils::trace::details::Region __region_fn(__cv_trace_location_fn549);;; bin_loop<op_and, uchar, v_uint8>(src1, step1, src2, step2, dst, step, width, height); }
网友评论