mirror of
https://github.com/facebook/zstd.git
synced 2025-07-29 11:21:22 +03:00
Add option to use logical cores for default threads
This commit is contained in:
137
programs/util.c
137
programs/util.c
@ -1103,7 +1103,7 @@ FileNamesTable* UTIL_createFNT_fromROTable(const char** filenames, size_t nbFile
|
||||
|
||||
|
||||
/*-****************************************
|
||||
* count the number of physical cores
|
||||
* count the number of cores
|
||||
******************************************/
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
@ -1112,10 +1112,26 @@ FileNamesTable* UTIL_createFNT_fromROTable(const char** filenames, size_t nbFile
|
||||
|
||||
typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
|
||||
|
||||
int UTIL_countPhysicalCores(void)
|
||||
DWORD CountSetBits(ULONG_PTR bitMask)
|
||||
{
|
||||
static int numPhysicalCores = 0;
|
||||
if (numPhysicalCores != 0) return numPhysicalCores;
|
||||
DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
|
||||
DWORD bitSetCount = 0;
|
||||
ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i <= LSHIFT; ++i)
|
||||
{
|
||||
bitSetCount += ((bitMask & bitTest)?1:0);
|
||||
bitTest/=2;
|
||||
}
|
||||
|
||||
return bitSetCount;
|
||||
}
|
||||
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
static int numCores = 0;
|
||||
if (numCores != 0) return numCores;
|
||||
|
||||
{ LPFN_GLPI glpi;
|
||||
BOOL done = FALSE;
|
||||
@ -1161,7 +1177,10 @@ int UTIL_countPhysicalCores(void)
|
||||
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) {
|
||||
|
||||
if (ptr->Relationship == RelationProcessorCore) {
|
||||
numPhysicalCores++;
|
||||
if (logical)
|
||||
numCores += CountSetBits(ptr->ProcessorMask);
|
||||
else
|
||||
numCores++;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
@ -1170,17 +1189,17 @@ int UTIL_countPhysicalCores(void)
|
||||
|
||||
free(buffer);
|
||||
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
|
||||
failed:
|
||||
/* try to fall back on GetSystemInfo */
|
||||
{ SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
numPhysicalCores = sysinfo.dwNumberOfProcessors;
|
||||
if (numPhysicalCores == 0) numPhysicalCores = 1; /* just in case */
|
||||
numCores = sysinfo.dwNumberOfProcessors;
|
||||
if (numCores == 0) numCores = 1; /* just in case */
|
||||
}
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
@ -1189,24 +1208,24 @@ failed:
|
||||
|
||||
/* Use apple-provided syscall
|
||||
* see: man 3 sysctl */
|
||||
int UTIL_countPhysicalCores(void)
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
static S32 numPhysicalCores = 0; /* apple specifies int32_t */
|
||||
if (numPhysicalCores != 0) return numPhysicalCores;
|
||||
static S32 numCores = 0; /* apple specifies int32_t */
|
||||
if (numCores != 0) return numCores;
|
||||
|
||||
{ size_t size = sizeof(S32);
|
||||
int const ret = sysctlbyname("hw.physicalcpu", &numPhysicalCores, &size, NULL, 0);
|
||||
int const ret = sysctlbyname(logical ? "hw.logicalcpu" : "hw.physicalcpu", &numCores, &size, NULL, 0);
|
||||
if (ret != 0) {
|
||||
if (errno == ENOENT) {
|
||||
/* entry not present, fall back on 1 */
|
||||
numPhysicalCores = 1;
|
||||
numCores = 1;
|
||||
} else {
|
||||
perror("zstd: can't get number of physical cpus");
|
||||
perror("zstd: can't get number of cpus");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1215,16 +1234,16 @@ int UTIL_countPhysicalCores(void)
|
||||
/* parse /proc/cpuinfo
|
||||
* siblings / cpu cores should give hyperthreading ratio
|
||||
* otherwise fall back on sysconf */
|
||||
int UTIL_countPhysicalCores(void)
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
static int numPhysicalCores = 0;
|
||||
static int numCores = 0;
|
||||
|
||||
if (numPhysicalCores != 0) return numPhysicalCores;
|
||||
if (numCores != 0) return numCores;
|
||||
|
||||
numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numPhysicalCores == -1) {
|
||||
numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numCores == -1) {
|
||||
/* value not queryable, fall back on 1 */
|
||||
return numPhysicalCores = 1;
|
||||
return numCores = 1;
|
||||
}
|
||||
|
||||
/* try to determine if there's hyperthreading */
|
||||
@ -1238,7 +1257,7 @@ int UTIL_countPhysicalCores(void)
|
||||
|
||||
if (cpuinfo == NULL) {
|
||||
/* fall back on the sysconf value */
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
|
||||
/* assume the cpu cores/siblings values will be constant across all
|
||||
@ -1271,13 +1290,13 @@ int UTIL_countPhysicalCores(void)
|
||||
ratio = siblings / cpu_cores;
|
||||
}
|
||||
|
||||
if (ratio && numPhysicalCores > ratio) {
|
||||
numPhysicalCores = numPhysicalCores / ratio;
|
||||
if (ratio && numCores > ratio && !logical) {
|
||||
numCores = numCores / ratio;
|
||||
}
|
||||
|
||||
failed:
|
||||
fclose(cpuinfo);
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1288,52 +1307,70 @@ failed:
|
||||
|
||||
/* Use physical core sysctl when available
|
||||
* see: man 4 smp, man 3 sysctl */
|
||||
int UTIL_countPhysicalCores(void)
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
static int numPhysicalCores = 0; /* freebsd sysctl is native int sized */
|
||||
if (numPhysicalCores != 0) return numPhysicalCores;
|
||||
static int numCores = 0; /* freebsd sysctl is native int sized */
|
||||
#if __FreeBSD_version >= 1300008
|
||||
static int perCore = 1;
|
||||
#endif
|
||||
if (numCores != 0) return numCores;
|
||||
|
||||
#if __FreeBSD_version >= 1300008
|
||||
{ size_t size = sizeof(numPhysicalCores);
|
||||
int ret = sysctlbyname("kern.smp.cores", &numPhysicalCores, &size, NULL, 0);
|
||||
if (ret == 0) return numPhysicalCores;
|
||||
{ size_t size = sizeof(numCores);
|
||||
int ret = sysctlbyname("kern.smp.cores", &numCores, &size, NULL, 0);
|
||||
if (ret == 0) {
|
||||
if (logical) {
|
||||
ret = sysctlbyname("kern.smp.threads_per_core", &perCore, &size, NULL, 0);
|
||||
/* default to physical cores if logical cannot be read */
|
||||
if (ret == 0)
|
||||
numCores *= perCore;
|
||||
}
|
||||
|
||||
return numCores;
|
||||
}
|
||||
if (errno != ENOENT) {
|
||||
perror("zstd: can't get number of physical cpus");
|
||||
perror("zstd: can't get number of cpus");
|
||||
exit(1);
|
||||
}
|
||||
/* sysctl not present, fall through to older sysconf method */
|
||||
}
|
||||
#else
|
||||
/* suppress unused parameter warning */
|
||||
(void) logical;
|
||||
#endif
|
||||
|
||||
numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numPhysicalCores == -1) {
|
||||
numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numCores == -1) {
|
||||
/* value not queryable, fall back on 1 */
|
||||
numPhysicalCores = 1;
|
||||
numCores = 1;
|
||||
}
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
|
||||
|
||||
/* Use POSIX sysconf
|
||||
* see: man 3 sysconf */
|
||||
int UTIL_countPhysicalCores(void)
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
static int numPhysicalCores = 0;
|
||||
/* suppress unused parameter warning */
|
||||
(void) logical;
|
||||
|
||||
if (numPhysicalCores != 0) return numPhysicalCores;
|
||||
static int numCores = 0;
|
||||
|
||||
numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numPhysicalCores == -1) {
|
||||
if (numCores != 0) return numCores;
|
||||
|
||||
numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (numCores == -1) {
|
||||
/* value not queryable, fall back on 1 */
|
||||
return numPhysicalCores = 1;
|
||||
return numCores = 1;
|
||||
}
|
||||
return numPhysicalCores;
|
||||
return numCores;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int UTIL_countPhysicalCores(void)
|
||||
int UTIL_countCores(int logical)
|
||||
{
|
||||
/* assume 1 */
|
||||
return 1;
|
||||
@ -1341,6 +1378,16 @@ int UTIL_countPhysicalCores(void)
|
||||
|
||||
#endif
|
||||
|
||||
int UTIL_countPhysicalCores(void)
|
||||
{
|
||||
return UTIL_countCores(0);
|
||||
}
|
||||
|
||||
int UTIL_countLogicalCores(void)
|
||||
{
|
||||
return UTIL_countCores(1);
|
||||
}
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user