25

在 Linux 中禁用逻辑 CPU 的方法是众所周知的,基本上使用echo 0 > /sys/devices/system/cpu/cpu<number>/online. 这样,您只是告诉操作系统忽略给定的 ( <number>) CPU。

我的问题更进一步,是否不仅可以忽略它,还可以以编程方式将其关闭?我希望那个 CPU 不接收任何功率,以使其能耗为零。

我知道可以从 BIOS 禁用内核(并非总是如此),但我想知道是否可以在某个程序中执行此操作。

4

6 回答 6

17

当你这样做时echo 0 > /sys/devices/system/cpu/cpu<number>/online,接下来会发生什么取决于特定的 CPU。在 ARM 嵌入式系统上,内核通常会禁用驱动特定内核 PLL 的时钟,因此您可以有效地得到您想要的。

在 Intel X86 系统上,您只能禁用中断并调用hlt指令(Linux 内核会这样做)。这有效地将 CPU 置于省电状态,直到它被另一个 CPU 应用户请求唤醒。/sys/class/power_supply/BAT{0,1}/current_now如果您有一台笔记本电脑,您可以通过读取电源(或uevent所有值,如电压)或使用“powertop”实用程序来验证当您禁用内核时功耗确实下降了。

例如,这是在 Linux 内核中为 Intel CPU 禁用 CPU 内核的调用链。 https://github.com/torvalds/linux/blob/master/drivers/cpufreq/intel_pstate.c

arch/x86/kernel/smp.csmp_ops.play_dead = native_play_dead,

arch/x86/kernel/smpboot.cnative_play_dead()-> play_dead_common()->local_irq_disable()

在此之前,CPUFREQ 还会在禁用它之前将 CPU 设置为最低功耗级别,尽管这似乎并不是绝对必要的。

intel_pstate_stop_cpu-> intel_cpufreq_stop_cpu-> intel_pstate_set_min_pstate-> intel_pstate_set_pstate->wrmsrl_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate));

在 Intel X86 上似乎没有禁用实际时钟和电压调节器的官方方法。即使有,它也将特定于主板,因此您最接近的赌注可能是查看 BIOS,例如 coreboot。嗯,我意识到除了查看内核源代码之外,我对英特尔一无所知。

于 2017-07-12T22:51:02.510 回答
1

在 Windows 10 中,可以使用新的电源管理命令 CPMINCORES CPMAXCORES。

Powercfg -setacvalueindex scheme_current sub_processor CPMAXCORES 50
Powercfg -setacvalueindex scheme_current sub_processor CPMINCORES 25
Powercfg -setactive scheme_current

这里 50% 的核心被分配用于所需的深度睡眠,25% 被禁止停放。在需要提高时钟速率的数值模拟中表现非常出色(英特尔提升 15%)

您无法选择要停放的内核,但 Windows 10 内核会检查 Intel 的 Comet Lake 和更新的“首选”(更节能)内核,并开始停放那些不首选的内核。这不是一个严格的停放,所以在高负载时内核可以以非常低的负载使用这些内核。

以防万一您正在寻找替代品

于 2021-05-20T01:37:34.313 回答
0

您可以通过使用像cpufreq. 使 Linux 排除 CPU 和省电模式将确保内核以最低频率运行。

于 2017-07-11T11:55:28.543 回答
0

您还可以在内核启动时将 cpus 与调度程序隔离开来。

添加isolcpus=0,1,2到内核启动参数。

https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/re46.html

于 2021-05-05T14:07:18.280 回答
0

我知道这是一个老问题,但禁用 CPU 的一种方法是通过 grub 配置。

如果您添加到 end of GRUB_CMDLINE_LINUXin /etc/default/grub(假设您使用的是标准 Linux dist,如果您使用的是设备,则 grub 配置的位置可能不同),例如:

GRUB_CMDLINE_LINUX=".......Current config here **maxcpus**=2"

grub2-mkconfig -o /boot/grub2/grub.cfg然后通过运行(或grub-mkconfig -o /boot/grub2/grub.cfg取决于您的安装)重新制作您的 grub 配置 。一些发行版可能需要nr_cpus而不是maxcpus.

只是一些额外的信息:

  • 如果您正在运行具有多个物理 CPU 的服务器,那么禁用一个 CPU 很可能会禁用链接到该 CPU 的内存集,因此它可能会影响服务器的性能

  • 以这种方式禁用 CPU,不会影响您的 1 类管理程序访问 CPU(这是基于 xen 管理程序的,我相信它也适用于 vmware,如果有人可以提供确认会很棒)。根据 virtualbox 设置,它可能会限制您可以分配给 VM 的 CPU 数量,除非您正在运行准虚拟化。

  • 但是,我不确定您是否会节省电量,如今大多数服务器甚至台式机都已经很好地控制了电源,使当前负载不需要的任何设备进入睡眠状态。我担心的是通过减少 CPU(内核)的数量,然后您将只是将负载转移到剩余的 CPU 上,并且由于需要安排处理器时间,并且可能有指令排队,以及数量较少的影响可用于中断的内核(例如:网络流量),它可能对功耗产生负面影响。

于 2021-06-25T22:15:19.793 回答
-1

AFAIK 目前没有可用的系统调用或库函数。甚至 ioctl 实现。因此,除了创建新模块/系统调用之外,我还能想到两种方法:

  1. 使用 ASM asm(<assembly code>);,其中汇编代码是特定于体系结构的 asm 代码来修改 cpu 标志。

  2. c ( man 3 system) 中的系统调用。假设你只是想通过 c 来做。

于 2017-07-10T12:26:50.777 回答