如何使用 C 获取 Linux 中的 CPU 数量?

2024-11-07 08:55:00
admin
原创
276
摘要:问题描述:是否有 API 可以获取 Linux 中可用的 CPU 数量?我的意思是,无需使用 /proc/cpuinfo 或任何其他 sys-node 文件...我发现这个使用 sched.h 的实现:int GetCPUCount() { cpu_set_t cs; CPU_ZERO(&cs);...

问题描述:

是否有 API 可以获取 Linux 中可用的 CPU 数量?我的意思是,无需使用 /proc/cpuinfo 或任何其他 sys-node 文件...

我发现这个使用 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 < 64; i++)
 {
  if (CPU_ISSET(i, &cs))
   count++;
  else
   break;
 }
 return count;
}

但是,使用通用库难道没有更高级别的东西吗?


解决方案 1:

#include <unistd.h>
long number_of_processors = sysconf(_SC_NPROCESSORS_ONLN);

解决方案 2:

#include <stdio.h>
#include <sys/sysinfo.h>

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

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

解决方案 3:

该代码(取自此处)应该可以在 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:
%s
", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
  if (nprocs_max < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs configured:
%s
", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  printf ("%ld of %ld processors online
",nprocs, nprocs_max);
  exit (EXIT_SUCCESS);
#else
  fprintf(stderr, "Could not determine number of CPUs");
  exit (EXIT_FAILURE);
#endif
}

解决方案 4:

sched_affinity()您在开头提到的版本仍然比/proc/cpuinfoand/or更好,_SC_NPROCESSORS_ONLN因为它只计算给定进程可用的 CPU(某些 CPU 可能被sched_setaffinity()外部进程调用禁用)。唯一的变化是使用CPU_COUNT()而不是CPU_ISSET在循环中执行。

解决方案 5:

使用/proc/cpuinfo是最干净、最便携的解决方案。如果打开失败,您可以简单地假设 1 个 CPU 或 2 个 CPU。依赖于了解 CPU 数量以实现微优化以外的目的(例如选择要运行的理想线程数)的代码几乎肯定会做一些愚蠢的事情。

_SC_NPROCESSORS_ONLN解决方案依赖于非标准(glibc 特定)扩展,该扩展的依赖性比(所有 Linux 系统都有,但有些系统有非 glibc 库或缺少的旧版本 glibc )sysconf要大得多。/proc`/proc`_SC_NPROCESSORS_ONLN

解决方案 6:

没有任何答案涉及sysconf(...)get_nprocs()正确遵守受 CPU 亲和性限制的任务处理器数量。

您需要类似这样的方法来获取可用于任务的处理器数量:

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>

int nprocs()
{
  cpu_set_t cs;
  CPU_ZERO(&cs);
  sched_getaffinity(0, sizeof(cs), &cs);
  return CPU_COUNT(&cs);
}

int main()
{
  printf("procs=%d
", nprocs());
  return 0;
}

解决方案 7:

就我个人而言,对于最近的 Intel CPU(不是一般的 x86,只是 Intel),我使用EAX=0Bh cpuid叶子。有关当前插槽(又称包)中内核的信息的详细信息,请参阅Wikipedia 。在多插槽系统上,这可能是系统范围内物理/逻辑内核数量的一半或四分之一。Intel 有一份关于枚举 CPU 的白皮书,其中详细说明了在多插槽系统的情况下要检查的内容。此代码不会执行此操作,它只检查一个子叶子(ECX=1)。

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
Threads: %d
Actual thread: %d
",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
Threads: %d
HyperThreading: %s
",ncores,nthreads,ht?"Yes":"No");

return 0;
}

输出:

Cores: 4
Threads: 8
HyperThreading: Yes

解决方案 8:

在 Linux(Ubuntu)上:

#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <sched.h>
int GetCPUCount()
{
 cpu_set_t cs;
 sched_getaffinity(0, sizeof(cs), &cs);
 return CPU_COUNT_S(sizeof(cs), &cs);
}

(假设当前进程具有默认的 CPU 亲和性。)

解决方案 9:

另一种方法是扫描 sys 文件系统下的 cpu* 目录:

#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).
", 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
", cpu_count);
   return 0;
}
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用