mirror of
https://github.com/opencv/opencv.git
synced 2025-07-31 09:57:28 +08:00
Merge pull request #16457 from ganesh-k13:bugfix/getCPUCount-fix
* Fixed getCPUCount Minor new line changes Android fix | efficient linux checks Android fix 2 Fixed cpu logic for non linux platforms Android fix 3 Android fix 4 * No v1 case handle | Refactor long lines * Refined Cgroups logic | Combine Android and Linux * Fixed directives * Added support for --cpus | Fixed minor bug in Andriod | Change file read logic * Added macro checks for apple errors * Fixed macro to include android * Addressed review comments * Fixed android macro * Refined return values * Fixed apple warning * Addressed review comments * Fixed whitespace * Android Fix try 1 * Android Fix try 2 * Android Fix try 3 * Removed unwanted endif * Android Fix try 4 * Android Fix try 5 * Macro Restructure * core: updates to CPUs detection (minor)
This commit is contained in:
parent
f48c84eaee
commit
09df7810d1
@ -58,13 +58,20 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fstream>
|
||||
#if defined __ANDROID__
|
||||
#include <sys/sysconf.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sched.h>
|
||||
#elif defined __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined CV_CXX11
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#ifdef _OPENMP
|
||||
#define HAVE_OPENMP
|
||||
#endif
|
||||
@ -739,19 +746,40 @@ int cv::getThreadNum(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
static inline int getNumberOfCPUsImpl()
|
||||
|
||||
#if defined __linux__ || defined __GLIBC__ || defined __EMSCRIPTEN__ || defined __HAIKU__ || defined __ANDROID__
|
||||
#define CV_CPU_GROUPS_1
|
||||
#endif
|
||||
|
||||
#if defined __linux__ || defined __ANDROID__
|
||||
#define CV_HAVE_CGROUPS 1
|
||||
#endif
|
||||
|
||||
#if defined CV_CPU_GROUPS_1
|
||||
static inline
|
||||
std::string getFileContents(const char *filename)
|
||||
{
|
||||
FILE* cpuPossible = fopen("/sys/devices/system/cpu/possible", "r");
|
||||
if(!cpuPossible)
|
||||
return 1;
|
||||
std::ifstream ifs(filename);
|
||||
if (!ifs.is_open())
|
||||
return std::string();
|
||||
|
||||
char buf[2000]; //big enough for 1000 CPUs in worst possible configuration
|
||||
char* pbuf = fgets(buf, sizeof(buf), cpuPossible);
|
||||
fclose(cpuPossible);
|
||||
if(!pbuf)
|
||||
return 1;
|
||||
std::string content( (std::istreambuf_iterator<char>(ifs) ),
|
||||
(std::istreambuf_iterator<char>() ) );
|
||||
|
||||
if (ifs.fail())
|
||||
return std::string();
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static inline
|
||||
int getNumberOfCPUsImpl(const char *filename)
|
||||
{
|
||||
std::string file_contents = getFileContents(filename);
|
||||
if(file_contents.empty())
|
||||
return 0;
|
||||
|
||||
char *pbuf = const_cast<char*>(file_contents.c_str());
|
||||
//parse string of form "0-1,3,5-7,10,13-15"
|
||||
int cpusAvailable = 0;
|
||||
|
||||
@ -775,12 +803,63 @@ static inline int getNumberOfCPUsImpl()
|
||||
}
|
||||
|
||||
}
|
||||
return cpusAvailable ? cpusAvailable : 1;
|
||||
return cpusAvailable;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined CV_HAVE_CGROUPS
|
||||
static inline
|
||||
unsigned getNumberOfCPUsCFS()
|
||||
{
|
||||
int cfs_quota = 0;
|
||||
{
|
||||
std::ifstream ss_period("/sys/fs/cgroup/cpu/cpu.cfs_quota_us", std::ios::in | std::ios::binary);
|
||||
ss_period >> cfs_quota;
|
||||
|
||||
if (ss_period.fail() || cfs_quota < 1) /* cfs_quota must not be 0 or negative */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cfs_period = 0;
|
||||
{
|
||||
std::ifstream ss_quota("/sys/fs/cgroup/cpu/cpu.cfs_period_us", std::ios::in | std::ios::binary);
|
||||
ss_quota >> cfs_period;
|
||||
|
||||
if (ss_quota.fail() || cfs_period < 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (unsigned)max(1, cfs_quota/cfs_period);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> static inline
|
||||
T minNonZero(const T& val_1, const T& val_2)
|
||||
{
|
||||
if ((val_1 != 0) && (val_2 != 0))
|
||||
return std::min(val_1, val_2);
|
||||
return (val_1 != 0) ? val_1 : val_2;
|
||||
}
|
||||
|
||||
int cv::getNumberOfCPUs(void)
|
||||
{
|
||||
/*
|
||||
* Logic here is to try different methods of getting CPU counts and return
|
||||
* the minimum most value as it has high probablity of being right and safe.
|
||||
* Return 1 if we get 0 or not found on all methods.
|
||||
*/
|
||||
#if defined CV_CXX11
|
||||
/*
|
||||
* Check for this standard C++11 way, we do not return directly because
|
||||
* running in a docker or K8s environment will mean this is the host
|
||||
* machines config not the containers or pods and as per docs this value
|
||||
* must be "considered only a hint".
|
||||
*/
|
||||
unsigned ncpus = std::thread::hardware_concurrency(); /* If the value is not well defined or not computable, returns 0 */
|
||||
#else
|
||||
unsigned ncpus = 0; /* 0 means we have to find out some other way */
|
||||
#endif
|
||||
|
||||
#if defined _WIN32
|
||||
SYSTEM_INFO sysinfo;
|
||||
#if (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_X64) || defined(WINRT)) && _WIN32_WINNT >= 0x501
|
||||
@ -788,13 +867,37 @@ int cv::getNumberOfCPUs(void)
|
||||
#else
|
||||
GetSystemInfo( &sysinfo );
|
||||
#endif
|
||||
unsigned ncpus_sysinfo = sysinfo.dwNumberOfProcessors < 0 ? 1 : sysinfo.dwNumberOfProcessors; /* Just a fail safe */
|
||||
ncpus = minNonZero(ncpus, ncpus_sysinfo);
|
||||
|
||||
#elif defined CV_CPU_GROUPS_1
|
||||
|
||||
#if defined CV_HAVE_CGROUPS
|
||||
static unsigned ncpus_impl_cpuset = (unsigned)getNumberOfCPUsImpl("/sys/fs/cgroup/cpuset/cpuset.cpus");
|
||||
ncpus = minNonZero(ncpus, ncpus_impl_cpuset);
|
||||
|
||||
static unsigned ncpus_impl_cfs = getNumberOfCPUsCFS();
|
||||
ncpus = minNonZero(ncpus, ncpus_impl_cfs);
|
||||
#endif
|
||||
|
||||
static unsigned ncpus_impl_devices = (unsigned)getNumberOfCPUsImpl("/sys/devices/system/cpu/online");
|
||||
ncpus = minNonZero(ncpus, ncpus_impl_devices);
|
||||
|
||||
#if defined _GNU_SOURCE \
|
||||
&& !defined(__ANDROID__) // TODO: add check for modern Android NDK
|
||||
|
||||
cpu_set_t cpu_set;
|
||||
if (0 == sched_getaffinity(0, sizeof(cpu_set), &cpu_set))
|
||||
{
|
||||
unsigned cpu_count_cpu_set = CPU_COUNT(&cpu_set);
|
||||
ncpus = minNonZero(ncpus, cpu_count_cpu_set);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned cpu_count_sysconf = (unsigned)sysconf( _SC_NPROCESSORS_ONLN );
|
||||
ncpus = minNonZero(ncpus, cpu_count_sysconf);
|
||||
|
||||
return (int)sysinfo.dwNumberOfProcessors;
|
||||
#elif defined __ANDROID__
|
||||
static int ncpus = getNumberOfCPUsImpl();
|
||||
return ncpus;
|
||||
#elif defined __linux__ || defined __GLIBC__ || defined __HAIKU__ || defined __EMSCRIPTEN__
|
||||
return (int)sysconf( _SC_NPROCESSORS_ONLN );
|
||||
#elif defined __APPLE__
|
||||
int numCPU=0;
|
||||
int mib[4];
|
||||
@ -816,10 +919,9 @@ int cv::getNumberOfCPUs(void)
|
||||
numCPU = 1;
|
||||
}
|
||||
|
||||
return (int)numCPU;
|
||||
#else
|
||||
return 1;
|
||||
ncpus = minNonZero(ncpus, (unsigned)numCPU);
|
||||
#endif
|
||||
return ncpus != 0 ? ncpus : 1;
|
||||
}
|
||||
|
||||
const char* cv::currentParallelFramework() {
|
||||
|
Loading…
Reference in New Issue
Block a user