如何发现 Mac OS X 上的“逻辑”核心数量?

发布于 2024-08-11 05:16:56 字数 424 浏览 4 评论 0原文

当您运行 Mac OS X 时,如何从命令行得知计算机上有多少个内核?在 Linux 上,我使用:

x=$(awk '/^processor/ {++n} END {print n+1}' /proc/cpuinfo)

它并不完美,但已经很接近了。这是为了提供给 make,这就是为什么它给出的结果比实际数字高 1。我知道上面的代码可以用 Perl 编写得更密集,或者可以使用 grep、wc 和 cut 编写,但我认为上面的代码是简洁性和可读性之间的一个很好的权衡。

非常晚的编辑:只是为了澄清:我问有多少逻辑核心可用,因为这对应于我想要make 产卵。 jkp 的答案经过 Chris Lloyd 的进一步完善,正是我所需要的。 YMMV。

How can you tell, from the command line, how many cores are on the machine when you're running Mac OS X? On Linux, I use:

x=$(awk '/^processor/ {++n} END {print n+1}' /proc/cpuinfo)

It's not perfect, but it's close. This is intended to get fed to make, which is why it gives a result 1 higher than the actual number. And I know the above code can be written denser in Perl or can be written using grep, wc, and cut, but I decided the above was a good tradeoff between conciseness and readability.

VERY LATE EDIT: Just to clarify: I'm asking how many logical cores are available, because this corresponds with how many simultaneous jobs I want make to spawn. jkp's answer, further refined by Chris Lloyd, was exactly what I needed. YMMV.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

九局 2024-08-18 05:16:56

您可以使用 sysctl 实用程序来执行此操作:

sysctl -n hw.ncpu

You can do this using the sysctl utility:

sysctl -n hw.ncpu
静谧幽蓝 2024-08-18 05:16:56

更简单:

sysctl -n hw.ncpu

Even easier:

sysctl -n hw.ncpu
场罚期间 2024-08-18 05:16:56

这应该是跨平台的。至少对于 Linux 和 Mac OS X 来说是这样。

python -c 'import multiprocessing as mp; print(mp.cpu_count())'

虽然有点慢,但是可以用。

This should be cross platform. At least for Linux and Mac OS X.

python -c 'import multiprocessing as mp; print(mp.cpu_count())'

A little bit slow but works.

终止放荡 2024-08-18 05:16:56

getconf 同时适用于 Mac OS X 和 Linux,以防万一您需要它与这两个系统兼容:

$ getconf _NPROCESSORS_ONLN
12

getconf works both in Mac OS X and Linux, just in case you need it to be compatible with both systems:

$ getconf _NPROCESSORS_ONLN
12
装纯掩盖桑 2024-08-18 05:16:56

system_profiler SPHardwareDataType 显示我有 1 个处理器和 4 个内核。

[~] system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro9,1
      Processor Name: Intel Core i7
      Processor Speed: 2.6 GHz
      Number of Processors: 1
      Total Number of Cores: 4

      <snip>

[~] 

然而,sysctl 不同意:

[~] sysctl -n hw.logicalcpu
8
[~] sysctl -n hw.physicalcpu
4
[~] 

但 sysctl 看起来是正确的,因为当我运行一个应该占用所有 CPU 插槽的程序时,我发现该程序占用了接近 800% 的 CPU 时间(在 top 中):

PID   COMMAND      %CPU  
4306  top          5.6   
4304  java         745.7 
4296  locationd    0.0  

system_profiler SPHardwareDataType shows I have 1 processor and 4 cores.

[~] system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro9,1
      Processor Name: Intel Core i7
      Processor Speed: 2.6 GHz
      Number of Processors: 1
      Total Number of Cores: 4

      <snip>

[~] 

However, sysctl disagrees:

[~] sysctl -n hw.logicalcpu
8
[~] sysctl -n hw.physicalcpu
4
[~] 

But sysctl appears correct, as when I run a program that should take up all CPU slots, I see this program taking close to 800% of CPU time (in top):

PID   COMMAND      %CPU  
4306  top          5.6   
4304  java         745.7 
4296  locationd    0.0  
夏尔 2024-08-18 05:16:56

要在 C 中执行此操作,您可以使用 sysctl(3) 系列函数:

int count;
size_t count_len = sizeof(count);
sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0);
fprintf(stderr,"you have %i cpu cores", count);

用于代替计算核心的“hw.logiccpu”的有趣值是(来自 内核源代码中的此注释):

  • hw.ncpu:本次启动可用的最大处理器数量。

    使用该值来调整每个处理器静态数组的大小;即处理器负载统计。

  • hw.activecpu:当前可用于执行线程的处理器数量。

    使用此数字来确定要在 SMP 感知应用程序中创建的线程数。

    当电源管理模式更改时,此数字可能会更改。

  • hw.physicalcpu:当前电源管理模式下可用的物理处理器数量。

  • hw.physicalcpu_max:本次启动可用的物理处理器的最大数量。

  • hw.logiccpu:当前电源管理模式下可用的逻辑处理器数量。

  • hw.ticalcpu_max:本次启动可用的逻辑处理器的最大数量。

To do this in C you can use the sysctl(3) family of functions:

int count;
size_t count_len = sizeof(count);
sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0);
fprintf(stderr,"you have %i cpu cores", count);

Interesting values to use in place of "hw.logicalcpu", which counts cores, are (from this comment in the kernel source):

  • hw.ncpu: The maximum number of processors that could be available this boot.

    Use this value for sizing of static per processor arrays; i.e. processor load statistics.

  • hw.activecpu: The number of processors currently available for executing threads.

    Use this number to determine the number threads to create in SMP aware applications.

    This number can change when power management modes are changed.

  • hw.physicalcpu: The number of physical processors available in the current power management mode.

  • hw.physicalcpu_max: The maximum number of physical processors that could be available this boot.

  • hw.logicalcpu: The number of logical processors available in the current power management mode.

  • hw.logicalcpu_max: The maximum number of logical processors that could be available this boot.

月寒剑心 2024-08-18 05:16:56
$ system_profiler | grep 'Total Number Of Cores'
$ system_profiler | grep 'Total Number Of Cores'
所谓喜欢 2024-08-18 05:16:56

使用system_profiler | grep“核心”命令。

我有一个:

MacBook Pro Retina,2012 年中。

处理器:2.6 GHz Intel Core i7

user$ system_profiler | grep "Cores"
      Total Number of Cores: 4

user$ sysctl -n hw.ncpu
8

根据 Wikipedia,(http:// en.wikipedia.org/wiki/Intel_Core#Core_i7)没有具有 8 个物理核心的 Core i7,因此超线程的想法一定是这种情况。忽略 sysctl 并使用 system_profiler 值来确保准确性。真正的问题是您是否可以在不中断其他进程的情况下有效地运行具有 4 个核心的应用程序(长时间的编译作业?)。

运行具有 4 个内核的并行编译器似乎不会显着影响常规操作系统操作。因此,也许将其视为 8 核也不是那么糟糕。

Use the system_profiler | grep "Cores" command.

I have a:

MacBook Pro Retina, Mid 2012.

Processor: 2.6 GHz Intel Core i7

user$ system_profiler | grep "Cores"
      Total Number of Cores: 4

user$ sysctl -n hw.ncpu
8

According to Wikipedia, (http://en.wikipedia.org/wiki/Intel_Core#Core_i7) there is no Core i7 with 8 physical cores so the Hyperthreading idea must be the case. Ignore sysctl and use the system_profiler value for accuracy. The real question is whether or not you can efficiently run applications with 4 cores (long compile jobs?) without interrupting other processes.

Running a compiler parallelized with 4 cores doesn't appear to dramatically affect regular OS operations. So perhaps treating it as 8 cores is not so bad.

满身野味 2024-08-18 05:16:56

正如 jkp 在评论中所说,这并没有显示实际的物理核心数量。要获取物理核心的数量,您可以使用以下命令:

system_profiler SPHardwareDataType

As jkp said in a comment, that doesn't show the actual number of physical cores. to get the number of physical cores you can use the following command:

system_profiler SPHardwareDataType
吃→可爱长大的 2024-08-18 05:16:56

原始问题中没有指定(尽管我在评论中看到 OP 帖子说这不是一个选项),但 macOS 上的许多开发人员都安装了 Homebrew 包管理器。

对于未来偶然发现这个问题的开发人员来说,只要存在安装 Homebrew 的假设(或要求)(例如,在公司的工程组织中),nproc 就是常见的 GNU 二进制文件之一它包含在 coreutils 包中。

brew install coreutils

如果您希望编写一次脚本(适用于 Linux + macOS)而不是两次,或者避免使用 if 块来检测操作系统以了解是否调用 nprocsysctl -n hw.logiccpu 相比,这可能是更好的选择。

It wasn't specified in the original question (although I saw OP post in comments that this wasn't an option), but many developers on macOS have the Homebrew package manager installed.

For future developers who stumble upon this question, as long as the assumption (or requirement) of Homebrew being installed exists (e.g., in an engineering organization in a company), nproc is one of the common GNU binaries that is included in the coreutils package.

brew install coreutils

If you have scripts that you would prefer to write once (for Linux + macOS) instead of twice, or to avoid having if blocks where you need to detect the OS to know whether or not to call nproc vs sysctl -n hw.logicalcpu, this may be a better option.

完美的未来在梦里 2024-08-18 05:16:56

以下命令为您提供有关 CPU 的所有信息

$ sysctl -a | sort | grep cpu

The following command gives you all information about your CPU

$ sysctl -a | sort | grep cpu
囍孤女 2024-08-18 05:16:56

对上面 2 个好的回复的评论:

1)关于 jkp 接受的回复(和评论):hw.ncpu 显然已被弃用,有利于 hw.logiccpu (https://ghc.haskell.org/trac/ghc/ticket/8594)

2) 关于 Karl Ehr 的 2014 年更新:在我的计算机上(使用 2.5 ghz 英特尔酷睿 i7),sysctl -a | grep machdep.cpu | grep machdep.cpu | grep per_package 返回不同的数字:

machdep.cpu.logic_per_package: 16

machdep.cpu.cores_per_package: 8

所需的值为:

machdep.cpu.core_count: 4

machdep.cpu.thread_count: 8

哪个匹配:

hw.physicalcpu: 4

硬件逻辑CPU:8

Comments for 2 good replies above:

1) re the accepted reply (and comments) by jkp: hw.ncpu is apparently deprecated in favor of hw.logicalcpu (https://ghc.haskell.org/trac/ghc/ticket/8594)

2) re the 2014 update by Karl Ehr: on my computer (with 2.5 ghz intel core i7),sysctl -a | grep machdep.cpu | grep per_package returns different numbers:

machdep.cpu.logical_per_package: 16

machdep.cpu.cores_per_package: 8

The desired values are:

machdep.cpu.core_count: 4

machdep.cpu.thread_count: 8

Which match:

hw.physicalcpu: 4

hw.logicalcpu: 8

猫卆 2024-08-18 05:16:56

澄清

当提出这个问题时,OP并没有说他想要逻辑核心的数量,而不是实际 核心数量,因此这个答案在逻辑上(无双关语)是通过获取实际 真实物理核心数量的方法来回答的,而不是操作系统尝试获取的数量通过超线程巫毒进行虚拟化。

更新以处理 YOSEMITE 中的缺陷

由于奇怪的 bug,我做了一个小修改。 (如果您忽略 STDERR,旧版本仍然可以很好地工作,这就是所有修改为您所做的。)


此处给出的所有其他答案要么

  1. 给出不正确的信息
  2. ,要么给出不正确的信息,因为命令实现中的错误运行
  3. 速度慢得令人难以置信(采取一分钟即可完成),或者
  4. 提供了太多数据,因此对于交互式使用可能有用,但如果您想以编程方式使用数据(例如,作为像 bundle install --jobs 3 这样的命令,您希望代替 3 的数字比您拥有的核心数少 1,或者至少不是超过核心数量)

可靠、正确、相当快速地获取核心数量且无需额外信息甚至答案周围额外字符的方法是:

system_profiler SPHardwareDataType 2> /dev/null | grep 'Total Number of Cores' | cut -d: -f2 | tr -d ' '

CLARIFICATION

When this question was asked the OP did not say that he wanted the number of LOGICAL cores rather than the actual number of cores, so this answer logically (no pun intended) answers with a way to get the actual number of real physical cores, not the number that the OS tries to virtualize through hyperthreading voodoo.

UPDATE TO HANDLE FLAW IN YOSEMITE

Due to a weird bug in OS X Yosemite (and possibly newer versions, such as the upcoming El Capitan), I've made a small modification. (The old version still worked perfectly well if you just ignore STDERR, which is all the modification does for you.)


Every other answer given here either

  1. gives incorrect information
  2. gives no information, due to an error in the command implementation
  3. runs unbelievably slowly (taking the better part of a minute to complete), or
  4. gives too much data, and thus might be useful for interactive use, but is useless if you want to use the data programmatically (for instance, as input to a command like bundle install --jobs 3 where you want the number in place of 3 to be one less than the number of cores you've got, or at least not more than the number of cores)

The way to get just the number of cores, reliably, correctly, reasonably quickly, and without extra information or even extra characters around the answer, is this:

system_profiler SPHardwareDataType 2> /dev/null | grep 'Total Number of Cores' | cut -d: -f2 | tr -d ' '
丶情人眼里出诗心の 2024-08-18 05:16:56

在运行 Mavericks 的 MacBook Pro 上,sysctl -a | grep hw.cpu 只会返回一些神秘的细节。 machdep.cpu 部分显示了更多详细且易于访问的信息,即:

sysctl -a | grep machdep.cpu

特别是,对于具有 HyperThreading (HT) 的处理器,您将看到枚举的 CPU 总数计数 (logic_per_package) 是物理核心计数 (cores_per_package) 的两倍。

sysctl -a | grep machdep.cpu  | grep per_package

On a MacBook Pro running Mavericks, sysctl -a | grep hw.cpu will only return some cryptic details. Much more detailed and accessible information is revealed in the machdep.cpu section, ie:

sysctl -a | grep machdep.cpu

In particular, for processors with HyperThreading (HT), you'll see the total enumerated CPU count (logical_per_package) as double that of the physical core count (cores_per_package).

sysctl -a | grep machdep.cpu  | grep per_package
风吹短裙飘 2024-08-18 05:16:56

跨平台解决方案:

nproc 2>/dev/null || sysctl -n hw.logicalcpu

Cross-platform solution:

nproc 2>/dev/null || sysctl -n hw.logicalcpu
吐个泡泡 2024-08-18 05:16:56

这可以通过更便携的方式来完成:

$ nproc --all
32

与 macOS 和 Linux 兼容。

This can be done in a more portable way:

$ nproc --all
32

Compatible with macOS and Linux.

怀里藏娇 2024-08-18 05:16:56

为了跟进 @alfwatt 的回答,我继续使用 sysctlnametomib 来获取 MIB 值对于所有这些条目(此处为 macOS 13.6)。

根据手册页:

sysctl 函数的运行时间大约是通过 sysctlbyname 函数发出的相同请求的三分之一

因此,我认为采取这条路线是值得的。以下是每个相应字符串值的 MIB 值:

条目名称MIB(管理信息库)
hw.ncpuint mib[2] = {6, 3};
hw.activecpuint mib[2] = {6, 25};
hw.physicalcpuint mib[2] = {6, 104 };
hw.physicalcpu_maxint mib[2] = {6, 105};
hw.logiccpuint mib [2] = {6, 106};
hw.logiccpu_maxint mib[2] = {6, 107};

以下是如何使用它们(< em>我将使用第一个作为示例):

int mib[2]      = {6, 3};      // MIB
u_int mib_size  = 2;           // it's not actually the size; it's the count
int ret_value   = 0;           // where the returned value will be stored
size_t ret_size = sizeof(int); // size of the area of the return value

int sc = sysctl(mib, mib_size, &ret_value, &ret_size, NULL, 0);

// if sc != -1, we're good:
printf("the value is: %d\n", ret_value);

To follow up on @alfwatt's answer, I went ahead and used sysctlnametomib to get the MIB values for all of these entries (macOS 13.6 here).

According to the man page:

the sysctl function runs in about a third the time as the same request made via the sysctlbyname function

So, I think it's worthwhile to take this route. Here are the MIB values for each corresponding string value:

Entry NameMIB (Management Information Base)
hw.ncpuint mib[2] = {6, 3};
hw.activecpuint mib[2] = {6, 25};
hw.physicalcpuint mib[2] = {6, 104};
hw.physicalcpu_maxint mib[2] = {6, 105};
hw.logicalcpuint mib[2] = {6, 106};
hw.logicalcpu_maxint mib[2] = {6, 107};

Here's how you use them (I'll use the first one as an example):

int mib[2]      = {6, 3};      // MIB
u_int mib_size  = 2;           // it's not actually the size; it's the count
int ret_value   = 0;           // where the returned value will be stored
size_t ret_size = sizeof(int); // size of the area of the return value

int sc = sysctl(mib, mib_size, &ret_value, &ret_size, NULL, 0);

// if sc != -1, we're good:
printf("the value is: %d\n", ret_value);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文