Commit f937d68d authored by Andrey Kamaev's avatar Andrey Kamaev

Fixed build for x64 with sse2 disabled; several improvements in performance…

Fixed build for x64 with sse2 disabled; several improvements in performance testing framework; enabled SANITY_CHECK() for performance tests
parent e7946d98
...@@ -43,6 +43,6 @@ PERF_TEST_P(PointsNumber, solvePnP, testing::Values(4, 3*9, 7*13) ...@@ -43,6 +43,6 @@ PERF_TEST_P(PointsNumber, solvePnP, testing::Values(4, 3*9, 7*13)
solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false); solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false);
} }
SANITY_CHECK(rvec); SANITY_CHECK(rvec, 1e-6);
SANITY_CHECK(tvec); SANITY_CHECK(tvec, 1e-6);
} }
...@@ -72,9 +72,11 @@ ...@@ -72,9 +72,11 @@
#if (_MSC_VER >= 1400 && defined _M_X64) || (__GNUC__ >= 4 && defined __x86_64__) #if (_MSC_VER >= 1400 && defined _M_X64) || (__GNUC__ >= 4 && defined __x86_64__)
#if defined WIN32 #if defined WIN32
#include <intrin.h> #include <intrin.h>
#endif #endif
#include <emmintrin.h> #if __SSE2__ || !defined __GNUC__
#include <emmintrin.h>
#endif
#endif #endif
#if defined __BORLANDC__ #if defined __BORLANDC__
...@@ -292,7 +294,7 @@ enum { ...@@ -292,7 +294,7 @@ enum {
CV_INLINE int cvRound( double value ) CV_INLINE int cvRound( double value )
{ {
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && !defined __APPLE__) #if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value ); __m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t); return _mm_cvtsd_si32(t);
#elif defined _MSC_VER && defined _M_IX86 #elif defined _MSC_VER && defined _M_IX86
......
...@@ -25,7 +25,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f, __testset) \ ...@@ -25,7 +25,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f, __testset) \
\ \
TEST_CYCLE(100) __f(a,b, c); \ TEST_CYCLE(100) __f(a,b, c); \
\ \
SANITY_CHECK(c); \ SANITY_CHECK(c, 1e-8); \
} }
#define PERF_TEST_P__CORE_ARITHM_SCALAR(__f, __testset) \ #define PERF_TEST_P__CORE_ARITHM_SCALAR(__f, __testset) \
...@@ -42,7 +42,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f ##__Scalar, __testset) \ ...@@ -42,7 +42,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f ##__Scalar, __testset) \
\ \
TEST_CYCLE(100) __f(a,b, c); \ TEST_CYCLE(100) __f(a,b, c); \
\ \
SANITY_CHECK(c); \ SANITY_CHECK(c, 1e-8); \
} }
PERF_TEST_P__CORE_ARITHM(bitwise_and, TYPICAL_MATS_BITW_ARITHM) PERF_TEST_P__CORE_ARITHM(bitwise_and, TYPICAL_MATS_BITW_ARITHM)
......
...@@ -24,5 +24,5 @@ PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT) ...@@ -24,5 +24,5 @@ PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT)
dft(src, dst); dft(src, dst);
} }
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-5);
} }
...@@ -17,5 +17,5 @@ PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*102 ...@@ -17,5 +17,5 @@ PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*102
TEST_CYCLE(200) cv::phase(X, Y, angle, true); TEST_CYCLE(200) cv::phase(X, Y, angle, true);
SANITY_CHECK(angle); SANITY_CHECK(angle, 5e-5);
} }
...@@ -21,7 +21,7 @@ PERF_TEST_P( Size_MatType, sum, TYPICAL_MATS ) ...@@ -21,7 +21,7 @@ PERF_TEST_P( Size_MatType, sum, TYPICAL_MATS )
TEST_CYCLE(100) { s = sum(arr); } TEST_CYCLE(100) { s = sum(arr); }
SANITY_CHECK(s); SANITY_CHECK(s, 1e-6);
} }
...@@ -40,7 +40,7 @@ PERF_TEST_P( Size_MatType, mean, TYPICAL_MATS ) ...@@ -40,7 +40,7 @@ PERF_TEST_P( Size_MatType, mean, TYPICAL_MATS )
TEST_CYCLE(100) { s = mean(src); } TEST_CYCLE(100) { s = mean(src); }
SANITY_CHECK(s); SANITY_CHECK(s, 1e-6);
} }
...@@ -60,7 +60,7 @@ PERF_TEST_P( Size_MatType, mean_mask, TYPICAL_MATS ) ...@@ -60,7 +60,7 @@ PERF_TEST_P( Size_MatType, mean_mask, TYPICAL_MATS )
TEST_CYCLE(100) { s = mean(src, mask); } TEST_CYCLE(100) { s = mean(src, mask); }
SANITY_CHECK(s); SANITY_CHECK(s, 1e-6);
} }
CV_FLAGS(NormType, NORM_INF, NORM_L1, NORM_L2, NORM_TYPE_MASK, NORM_RELATIVE, NORM_MINMAX) CV_FLAGS(NormType, NORM_INF, NORM_L1, NORM_L2, NORM_TYPE_MASK, NORM_RELATIVE, NORM_MINMAX)
...@@ -89,7 +89,7 @@ PERF_TEST_P( Size_MatType_NormType, norm, ...@@ -89,7 +89,7 @@ PERF_TEST_P( Size_MatType_NormType, norm,
TEST_CYCLE(100) { n = norm(src1, normType); } TEST_CYCLE(100) { n = norm(src1, normType); }
SANITY_CHECK(n); SANITY_CHECK(n, 1e-5);
} }
...@@ -116,7 +116,7 @@ PERF_TEST_P( Size_MatType_NormType, norm_mask, ...@@ -116,7 +116,7 @@ PERF_TEST_P( Size_MatType_NormType, norm_mask,
TEST_CYCLE(100) { n = norm(src1, normType, mask); } TEST_CYCLE(100) { n = norm(src1, normType, mask); }
SANITY_CHECK(n); SANITY_CHECK(n, 1e-5);
} }
...@@ -143,7 +143,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2, ...@@ -143,7 +143,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2,
TEST_CYCLE(100) { n = norm(src1, src2, normType); } TEST_CYCLE(100) { n = norm(src1, src2, normType); }
SANITY_CHECK(n); SANITY_CHECK(n, 1e-5);
} }
...@@ -171,7 +171,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2_mask, ...@@ -171,7 +171,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2_mask,
TEST_CYCLE(100) { n = norm(src1, src2, normType, mask); } TEST_CYCLE(100) { n = norm(src1, src2, normType, mask); }
SANITY_CHECK(n); SANITY_CHECK(n, 1e-5);
} }
...@@ -200,7 +200,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize, ...@@ -200,7 +200,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize,
TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType); } TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType); }
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-6);
} }
...@@ -230,7 +230,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_mask, ...@@ -230,7 +230,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_mask,
TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, -1, mask); } TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, -1, mask); }
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-6);
} }
...@@ -259,7 +259,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_32f, ...@@ -259,7 +259,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_32f,
TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, CV_32F); } TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, CV_32F); }
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-6);
} }
...@@ -279,7 +279,7 @@ PERF_TEST_P( Size_MatType, normalize_minmax, TYPICAL_MATS ) ...@@ -279,7 +279,7 @@ PERF_TEST_P( Size_MatType, normalize_minmax, TYPICAL_MATS )
TEST_CYCLE(100) { normalize(src, dst, 20., 100., NORM_MINMAX); } TEST_CYCLE(100) { normalize(src, dst, 20., 100., NORM_MINMAX); }
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-6);
} }
...@@ -298,8 +298,8 @@ PERF_TEST_P( Size_MatType, meanStdDev, TYPICAL_MATS ) ...@@ -298,8 +298,8 @@ PERF_TEST_P( Size_MatType, meanStdDev, TYPICAL_MATS )
TEST_CYCLE(100) { meanStdDev(src, mean, dev); } TEST_CYCLE(100) { meanStdDev(src, mean, dev); }
SANITY_CHECK(mean); SANITY_CHECK(mean, 1e-6);
SANITY_CHECK(dev); SANITY_CHECK(dev, 1e-6);
} }
...@@ -319,8 +319,8 @@ PERF_TEST_P( Size_MatType, meanStdDev_mask, TYPICAL_MATS ) ...@@ -319,8 +319,8 @@ PERF_TEST_P( Size_MatType, meanStdDev_mask, TYPICAL_MATS )
TEST_CYCLE(100) { meanStdDev(src, mean, dev, mask); } TEST_CYCLE(100) { meanStdDev(src, mean, dev, mask); }
SANITY_CHECK(mean); SANITY_CHECK(mean, 1e-6);
SANITY_CHECK(dev); SANITY_CHECK(dev, 1e-6);
} }
...@@ -368,8 +368,8 @@ PERF_TEST_P( Size_MatType, minMaxLoc, testing::Combine( ...@@ -368,8 +368,8 @@ PERF_TEST_P( Size_MatType, minMaxLoc, testing::Combine(
TEST_CYCLE(100) { minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); } TEST_CYCLE(100) { minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); }
SANITY_CHECK(minVal); SANITY_CHECK(minVal, 1e-12);
SANITY_CHECK(maxVal); SANITY_CHECK(maxVal, 1e-12);
} }
......
...@@ -26,7 +26,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear, ...@@ -26,7 +26,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear,
TEST_CYCLE(100) cv::resize(src, dst, to); TEST_CYCLE(100) cv::resize(src, dst, to);
SANITY_CHECK(dst); SANITY_CHECK(dst, 1 + 1e-6);
} }
PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear, PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear,
...@@ -50,6 +50,6 @@ PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear, ...@@ -50,6 +50,6 @@ PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear,
TEST_CYCLE(100) cv::resize(src, dst, to); TEST_CYCLE(100) cv::resize(src, dst, to);
SANITY_CHECK(dst); SANITY_CHECK(dst, 1 + 1e-6);
} }
...@@ -269,6 +269,7 @@ private: ...@@ -269,6 +269,7 @@ private:
int64 totalTime; int64 totalTime;
int64 timeLimit; int64 timeLimit;
static int64 timeLimitDefault; static int64 timeLimitDefault;
static unsigned int iterationsLimitDefault;
unsigned int nIters; unsigned int nIters;
unsigned int currentIter; unsigned int currentIter;
...@@ -297,7 +298,7 @@ private: ...@@ -297,7 +298,7 @@ private:
_declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, int wtype = WARMUP_WRITE); _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, int wtype = WARMUP_WRITE);
_declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, cv::InputOutputArray a4, int wtype = WARMUP_WRITE); _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, cv::InputOutputArray a4, int wtype = WARMUP_WRITE);
_declareHelper& iterations(int n); _declareHelper& iterations(unsigned int n);
_declareHelper& time(double timeLimitSecs); _declareHelper& time(double timeLimitSecs);
_declareHelper& tbb_threads(int n = -1); _declareHelper& tbb_threads(int n = -1);
private: private:
......
...@@ -204,12 +204,12 @@ void Regression::write(cv::Mat m) ...@@ -204,12 +204,12 @@ void Regression::write(cv::Mat m)
void Regression::verify(cv::FileNode node, cv::Mat actual, double eps, std::string argname) void Regression::verify(cv::FileNode node, cv::Mat actual, double eps, std::string argname)
{ {
double actualmin, actualmax; double actual_min, actual_max;
cv::minMaxLoc(actual, &actualmin, &actualmax); cv::minMaxLoc(actual, &actual_min, &actual_max);
ASSERT_NEAR((double)node["min"], actualmin, eps) ASSERT_NEAR((double)node["min"], actual_min, eps)
<< " " << argname << " has unexpected minimal value"; << " " << argname << " has unexpected minimal value";
ASSERT_NEAR((double)node["max"], actualmax, eps) ASSERT_NEAR((double)node["max"], actual_max, eps)
<< " " << argname << " has unexpected maximal value"; << " " << argname << " has unexpected maximal value";
cv::FileNode last = node["last"]; cv::FileNode last = node["last"];
...@@ -265,13 +265,13 @@ void Regression::write(cv::InputArray array) ...@@ -265,13 +265,13 @@ void Regression::write(cv::InputArray array)
void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) void Regression::verify(cv::FileNode node, cv::InputArray array, double eps)
{ {
ASSERT_EQ((int)node["kind"], array.kind()) << " Argument " << node.name() << " has unexpected kind"; ASSERT_EQ((int)node["kind"], array.kind()) << " Argument \"" << node.name() << "\" has unexpected kind";
ASSERT_EQ((int)node["type"], array.type()) << " Argument " << node.name() << " has unexpected type"; ASSERT_EQ((int)node["type"], array.type()) << " Argument \"" << node.name() << "\" has unexpected type";
cv::FileNode valnode = node["val"]; cv::FileNode valnode = node["val"];
if (isVector(array)) if (isVector(array))
{ {
ASSERT_EQ((int)node["len"], (int)array.total()) << " Vector " << node.name() << " has unexpected length"; ASSERT_EQ((int)node["len"], (int)array.total()) << " Vector \"" << node.name() << "\" has unexpected length";
int idx = node["idx"]; int idx = node["idx"];
cv::Mat actual = array.getMat(idx); cv::Mat actual = array.getMat(idx);
...@@ -279,7 +279,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) ...@@ -279,7 +279,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps)
if (valnode.isNone()) if (valnode.isNone())
{ {
ASSERT_LE((size_t)26, actual.total() * (size_t)actual.channels()) ASSERT_LE((size_t)26, actual.total() * (size_t)actual.channels())
<< " " << node.name() << "[" << idx << "] has unexpected number of elements"; << " \"" << node.name() << "[" << idx << "]\" has unexpected number of elements";
verify(node, actual, eps, cv::format("%s[%d]", node.name().c_str(), idx)); verify(node, actual, eps, cv::format("%s[%d]", node.name().c_str(), idx));
} }
else else
...@@ -293,8 +293,12 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) ...@@ -293,8 +293,12 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps)
cv::Mat diff; cv::Mat diff;
cv::absdiff(expected, actual, diff); cv::absdiff(expected, actual, diff);
if (!cv::checkRange(diff, true, 0, 0, eps)) if (!cv::checkRange(diff, true, 0, 0, eps))
FAIL() << " Difference between argument " {
<< node.name() << "[" << idx << "] and expected value is bugger than " << eps; double max;
cv::minMaxLoc(diff, 0, &max);
FAIL() << " Difference (=" << max << ") between argument \""
<< node.name() << "[" << idx << "]\" and expected value is bugger than " << eps;
}
} }
} }
else else
...@@ -302,7 +306,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) ...@@ -302,7 +306,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps)
if (valnode.isNone()) if (valnode.isNone())
{ {
ASSERT_LE((size_t)26, array.total() * (size_t)array.channels()) ASSERT_LE((size_t)26, array.total() * (size_t)array.channels())
<< " Argument " << node.name() << " has unexpected number of elements"; << " Argument \"" << node.name() << "\" has unexpected number of elements";
verify(node, array.getMat(), eps, "Argument " + node.name()); verify(node, array.getMat(), eps, "Argument " + node.name());
} }
else else
...@@ -312,13 +316,17 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) ...@@ -312,13 +316,17 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps)
cv::Mat actual = array.getMat(); cv::Mat actual = array.getMat();
ASSERT_EQ(expected.size(), actual.size()) ASSERT_EQ(expected.size(), actual.size())
<< " Argument " << node.name() << " has unexpected size"; << " Argument \"" << node.name() << "\" has unexpected size";
cv::Mat diff; cv::Mat diff;
cv::absdiff(expected, actual, diff); cv::absdiff(expected, actual, diff);
if (!cv::checkRange(diff, true, 0, 0, eps)) if (!cv::checkRange(diff, true, 0, 0, eps))
FAIL() << " Difference between argument " << node.name() {
<< " and expected value is bugger than " << eps; double max;
cv::minMaxLoc(diff, 0, &max);
FAIL() << " Difference (=" << max << ") between argument \"" << node.name()
<< "\" and expected value is bugger than " << eps;
}
} }
} }
} }
...@@ -378,12 +386,14 @@ performance_metrics::performance_metrics() ...@@ -378,12 +386,14 @@ performance_metrics::performance_metrics()
* ::perf::TestBase * ::perf::TestBase
\*****************************************************************************************/ \*****************************************************************************************/
int64 TestBase::timeLimitDefault = 0; int64 TestBase::timeLimitDefault = 0;
unsigned int TestBase::iterationsLimitDefault = (unsigned int)(-1);
int64 TestBase::_timeadjustment = 0; int64 TestBase::_timeadjustment = 0;
const char *command_line_keys = const char *command_line_keys =
{ {
"{ |perf_max_outliers |8 |percent of allowed outliers}" "{ |perf_max_outliers |8 |percent of allowed outliers}"
"{ |perf_min_samples |10 |minimal required numer of samples}" "{ |perf_min_samples |10 |minimal required numer of samples}"
"{ |perf_force_samples |100 |force set maximum number of samples for all tests}"
"{ |perf_seed |809564 |seed for random numbers generator}" "{ |perf_seed |809564 |seed for random numbers generator}"
"{ |perf_tbb_nthreads |-1 |if TBB is enabled, the number of TBB threads}" "{ |perf_tbb_nthreads |-1 |if TBB is enabled, the number of TBB threads}"
#if ANDROID #if ANDROID
...@@ -399,6 +409,7 @@ const char *command_line_keys = ...@@ -399,6 +409,7 @@ const char *command_line_keys =
double param_max_outliers; double param_max_outliers;
double param_max_deviation; double param_max_deviation;
unsigned int param_min_samples; unsigned int param_min_samples;
unsigned int perf_force_samples;
uint64 param_seed; uint64 param_seed;
double param_time_limit; double param_time_limit;
int param_tbb_nthreads; int param_tbb_nthreads;
...@@ -429,6 +440,7 @@ void TestBase::Init(int argc, const char* const argv[]) ...@@ -429,6 +440,7 @@ void TestBase::Init(int argc, const char* const argv[])
param_max_deviation = std::max(0., args.get<double>("perf_max_deviation")); param_max_deviation = std::max(0., args.get<double>("perf_max_deviation"));
param_seed = args.get<uint64>("perf_seed"); param_seed = args.get<uint64>("perf_seed");
param_time_limit = std::max(0., args.get<double>("perf_time_limit")); param_time_limit = std::max(0., args.get<double>("perf_time_limit"));
perf_force_samples = args.get<unsigned int>("perf_force_samples");
param_tbb_nthreads = args.get<int>("perf_tbb_nthreads"); param_tbb_nthreads = args.get<int>("perf_tbb_nthreads");
#if ANDROID #if ANDROID
...@@ -443,6 +455,7 @@ void TestBase::Init(int argc, const char* const argv[]) ...@@ -443,6 +455,7 @@ void TestBase::Init(int argc, const char* const argv[])
} }
timeLimitDefault = param_time_limit == 0.0 ? 1 : (int64)(param_time_limit * cv::getTickFrequency()); timeLimitDefault = param_time_limit == 0.0 ? 1 : (int64)(param_time_limit * cv::getTickFrequency());
iterationsLimitDefault = perf_force_samples == 0 ? (unsigned)(-1) : perf_force_samples;
_timeadjustment = _calibrate(); _timeadjustment = _calibrate();
} }
...@@ -785,7 +798,7 @@ void TestBase::SetUp() ...@@ -785,7 +798,7 @@ void TestBase::SetUp()
#endif #endif
lastTime = 0; lastTime = 0;
totalTime = 0; totalTime = 0;
nIters = (unsigned int)-1; nIters = iterationsLimitDefault;
currentIter = (unsigned int)-1; currentIter = (unsigned int)-1;
timeLimit = timeLimitDefault; timeLimit = timeLimitDefault;
times.clear(); times.clear();
...@@ -878,11 +891,11 @@ void TestBase::RunPerfTestBody() ...@@ -878,11 +891,11 @@ void TestBase::RunPerfTestBody()
/*****************************************************************************************\ /*****************************************************************************************\
* ::perf::TestBase::_declareHelper * ::perf::TestBase::_declareHelper
\*****************************************************************************************/ \*****************************************************************************************/
TestBase::_declareHelper& TestBase::_declareHelper::iterations(int n) TestBase::_declareHelper& TestBase::_declareHelper::iterations(unsigned int n)
{ {
test->times.clear(); test->times.clear();
test->times.reserve(n); test->times.reserve(n);
test->nIters = n; test->nIters = std::min(n, TestBase::iterationsLimitDefault);
test->currentIter = (unsigned int)-1; test->currentIter = (unsigned int)-1;
return *this; return *this;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment