Как узнать количество процессоров в Linux, использующих C? - PullRequest
50 голосов
/ 03 января 2011

Существует ли API для определения количества процессоров, доступных в Linux? Я имею в виду, без использования / proc / cpuinfo или любого другого файла sys-узла ...

Я нашел эту реализацию, используя sched.h:

int GetCPUCount()
{
 cpu_set_t cs;
 CPU_ZERO(&cs);
 sched_getaffinity(0, sizeof(cs), &cs);

 int count = 0;
 for (int i = 0; i < 8; i++)
 {
  if (CPU_ISSET(i, &cs))
   count++;
 }
 return count;
}

Но разве нет ничего более высокого уровня с использованием обычных библиотек?

Ответы [ 7 ]

74 голосов
/ 03 января 2011
#include <unistd.h>
long number_of_processors = sysconf(_SC_NPROCESSORS_ONLN);
20 голосов
/ 03 января 2011

Этот код (взят из здесь ) должен работать как на Windows, так и на * NIX платформах.

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


int main() {
  long nprocs = -1;
  long nprocs_max = -1;
#ifdef _WIN32
#ifndef _SC_NPROCESSORS_ONLN
SYSTEM_INFO info;
GetSystemInfo(&info);
#define sysconf(a) info.dwNumberOfProcessors
#define _SC_NPROCESSORS_ONLN
#endif
#endif
#ifdef _SC_NPROCESSORS_ONLN
  nprocs = sysconf(_SC_NPROCESSORS_ONLN);
  if (nprocs < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
  if (nprocs_max < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs configured:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  printf ("%ld of %ld processors online\n",nprocs, nprocs_max);
  exit (EXIT_SUCCESS);
#else
  fprintf(stderr, "Could not determine number of CPUs");
  exit (EXIT_FAILURE);
#endif
}
17 голосов
/ 28 ноября 2017
#include <stdio.h>
#include <sys/sysinfo.h>

int main(int argc, char *argv[])
{
    printf("This system has %d processors configured and "
        "%d processors available.\n",
        get_nprocs_conf(), get_nprocs());
    return 0;
}

https://linux.die.net/man/3/get_nprocs

13 голосов
/ 03 января 2011

Использование /proc/cpuinfo - самое чистое и самое портативное решение. В случае неудачного открытия, вы можете просто взять 1 процессор или 2 процессора. Код, который зависит от знания числа процессоров для целей, отличных от микрооптимизации (например, выбор идеального числа потоков для выполнения), почти наверняка делает что-то глупое.

Решение _SC_NPROCESSORS_ONLN зависит от нестандартного (специфичного для glibc) расширения sysconf, которое является гораздо большей зависимостью, чем /proc (все системы Linux имеют /proc, но некоторые имеют не-glibc libcs или более старые версии glibc, в которых отсутствует _SC_NPROCESSORS_ONLN).

10 голосов
/ 25 октября 2013
Версия

sched_affinity(), которую вы упоминаете в начале, все еще лучше, чем /proc/cpuinfo и / или _SC_NPROCESSORS_ONLN, поскольку она учитывает только доступные ЦПУ для данного процесса (некоторые могут быть отключены с помощью sched_setaffinity(), вызванным внешним процессом),Единственное изменение будет использовать CPU_COUNT() вместо CPU_ISSET в цикле.

1 голос
/ 22 марта 2019

Лично для последних процессоров Intel я использую это:

int main()
{
unsigned int eax=11,ebx=0,ecx=1,edx=0;

asm volatile("cpuid"
        : "=a" (eax),
          "=b" (ebx),
          "=c" (ecx),
          "=d" (edx)
        : "0" (eax), "2" (ecx)
        : );

printf("Cores: %d\nThreads: %d\nActual thread: %d\n",eax,ebx,edx);
}

Вывод:

Cores: 4
Threads: 8
Actual thread: 1

Или, более кратко:

#include <stdio.h>

int main()
{
unsigned int ncores=0,nthreads=0,ht=0;

asm volatile("cpuid": "=a" (ncores), "=b" (nthreads) : "a" (0xb), "c" (0x1) : );

ht=(ncores!=nthreads);

printf("Cores: %d\nThreads: %d\nHyperThreading: %s\n",ncores,nthreads,ht?"Yes":"No");

return 0;
}

Выход:

Cores: 4
Threads: 8
HyperThreading: Yes
0 голосов
/ 21 февраля 2017

Другой метод сканирования каталогов cpu * в файловой системе sys:

#include<stdio.h>
#include <dirent.h>
#include <errno.h>
#define LINUX_SYS_CPU_DIRECTORY "/sys/devices/system/cpu"

int main() {
   int cpu_count = 0;
   DIR *sys_cpu_dir = opendir(LINUX_SYS_CPU_DIRECTORY);
   if (sys_cpu_dir == NULL) {
       int err = errno;
       printf("Cannot open %s directory, error (%d).\n", LINUX_SYS_CPU_DIRECTORY, strerror(err));
       return -1;
   }
   const struct dirent *cpu_dir;
   while((cpu_dir = readdir(sys_cpu_dir)) != NULL) {
       if (fnmatch("cpu[0-9]*", cpu_dir->d_name, 0) != 0)
       {
          /* Skip the file which does not represent a CPU */
          continue;
       }
       cpu_count++;
   }
   printf("CPU count: %d\n", cpu_count);
   return 0;
}
...