Use std::chrono::steady_clock in getTickCount#22217
Conversation
std::chrono::steady_clock in getTickCount()std::chrono::steady_clock in getTickCount()
std::chrono::steady_clock in getTickCount()std::chrono::steady_clock in getTickCount
Add conditional compilation directives to enable uses of std::chrono on supported compilers. Use std::chrono::steady_clock as a source to retrieve current tick count and clock frequency. Fixes opencv#6902.
c334f4c to
db70676
Compare
|
I am particularly concerned about possible name clashes with macros. In the patch, I store the result of |
11de6af to
fa613e3
Compare
|
One job failed due to a non-existent repository, |
|
To merge this patch we need to ensure that there is no unwanted performance regression against the existed code. |
|
@alalek, unfortunately I don't an macOS X system, and my Linux system is quite atypical. May I ask whether the benchmarks should be carried out myself, or by your build farm? |
Benchmark 1: WindowsCodeThe following benchmark code utilizes macros to switch among different implementations of #include <chrono>
#include <cstdint>
#include <iostream>
#if defined(BENCH_IS_WINDOWS)
#include <windows.h>
#elif defined(BENCH_IS_MACH)
#include <mach/mach_time.h>
#elif defined(BENCH_IS_UNIX)
#include <time.h>
#else
#include <sys/time.h>
#endif
#define RUN_COUNT 10000000
std::int64_t getTickCount()
{
#if defined(BENCH_IS_CXX11)
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
return (std::int64_t)now.time_since_epoch().count();
#elif defined(BENCH_IS_WINDOWS)
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return (std::int64_t)counter.QuadPart;
#elif defined(BENCH_IS_MACH)
return (std::int64_t)mach_absolute_time();
#elif defined(BENCH_IS_UNIX)
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
return (std::int64_t)tp.tv_sec * 1000000000 + tp.tv_nsec;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (std::int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
#endif
}
int main(int, char **)
{
volatile std::int64_t tmp = 0;
std::cout << "Defined macros: ";
#if defined(BENCH_IS_CXX11)
std::cout << "BENCH_IS_CXX11 ";
#elif defined(BENCH_IS_WINDOWS)
std::cout << "BENCH_IS_WINDOWS ";
#elif defined(BENCH_IS_MACH)
std::cout << "BENCH_IS_MACH ";
#elif defined(BENCH_IS_UNIX)
std::cout << "BENCH_IS_UNIX ";
#else
std::cout << "<none> ";
#endif
std::cout << '\n';
auto before = std::chrono::steady_clock::now();
for (size_t i = 0; i < RUN_COUNT; i++)
{
tmp = getTickCount();
}
auto after = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(after - before);
std::cout << "Total time (ns): " << duration.count()
<< ", Avg time (ns): " << duration.count() / RUN_COUNT
<< '\n';
return 0;
}
Environment
Compiling commands: g++ -std=c++11 -DBENCH_IS_UNIX -O0 -o bench_unix.exe .\bench_getTickCount.cpp
g++ -std=c++11 -DBENCH_IS_CXX11 -O0 -o bench_cxx11.exe .\bench_getTickCount.cpp
g++ -std=c++11 -DBENCH_IS_WINDOWS -O0 -o bench_windows.exe .\bench_getTickCount.cpp
g++ -std=c++11 -O0 -o bench_default.exe .\bench_getTickCount.cppResult
The italicized column is the default implementation originally used on such platform; bold column is the fastest. Raw: Benchmark 2: (Embedded) LinuxEnvironment
Compilation commands: g++ -std=c++11 -DBENCH_IS_UNIX -O0 -o bench_unix ./bench_getTickCount.cpp
g++ -std=c++11 -DBENCH_IS_CXX11 -O0 -o bench_cxx11 ./bench_getTickCount.cpp
g++ -std=c++11 -O0 -o bench_default ./bench_getTickCount.cpp
g++ -std=c++11 -DBENCH_IS_UNIX -O3 -o bench_unix_opt ./bench_getTickCount.cpp
g++ -std=c++11 -DBENCH_IS_CXX11 -O3 -o bench_cxx11_opt ./bench_getTickCount.cpp
g++ -std=c++11 -O3 -o bench_default_opt ./bench_getTickCount.cppResult
Raw: |
This PR enables the use of
std::chrono::steady_clockon supported compilers as a source to retrieve the current tick count and clock frequency in a cross-platform way.Resolves #6902.
Pull Request Readiness Checklist
Patch to opencv_extra has the same branch name.