众所周知,在Linux中禁用逻辑CPU的方法基本上是echo > 0 /sys/devices/system/cpu/cpu<number>/online
。这样,您只是告诉操作系统忽略给定的(<number>
)CPU。
我的问题更进一步,是否有可能不仅忽略它而是以编程方式将其关闭?我希望CPU不接收任何功率,以使其能耗为零。
我知道可以从BIOS中禁用核心(并非总是如此),但我想知道是否可以在某个程序中执行此操作。
答案 0 :(得分:13)
执行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.c
:smp_ops.play_dead = native_play_dead,
arch/x86/kernel/smpboot.c
:native_play_dead()
- &gt; play_dead_common()
- &gt; local_irq_disable()
在此之前,CPUFREQ还会在禁用CPU之前将CPU设置为最低功耗级别,尽管这似乎并非绝对必要。
intel_pstate_stop_cpu
- &gt; intel_cpufreq_stop_cpu
- &gt; intel_pstate_set_min_pstate
- &gt; intel_pstate_set_pstate
- &gt; wrmsrl_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate));
在Intel X86上似乎没有官方的方法来禁用实际的时钟和电压调节器。即使有,它也将专用于主板,因此您最接近的赌注可能是调查BIOS,如coreboot。 嗯,除了研究内核资源外,我意识到我对英特尔一无所知。
答案 1 :(得分:0)
AFAIK目前没有系统调用或库函数。甚至ioctl实现。因此,除了创建新的模块/系统调用之外,还有两种我能想到的方法:
使用ASM asm(<assembly code>);
,其中汇编代码是特定于体系结构的asm代码,用于修改cpu标志。
系统调用c(man 3 system
)。假设你只是想通过c。
答案 2 :(得分:0)
您可以使用cpufreq
这样的州长来最接近这一点。让Linux排除CPU和省电模式将确保核心以最低频率运行。
答案 3 :(得分:0)
您还可以在内核启动时将 CPU 与调度程序隔离。
将 isolcpus=0,1,2
添加到内核启动参数。
https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/re46.html
答案 4 :(得分:0)
在 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 内核会检查英特尔的 Comet Lake 和更新的“首选”(更节能)内核,并开始停放不首选的内核。 这不是一个严格的停放,因此在高负载时内核可以在非常低的负载下使用这些内核。
以防万一您正在寻找替代品
答案 5 :(得分:0)
我知道这是一个老问题,但禁用 CPU 的一种方法是通过 grub 配置。
如果您在 GRUB_CMDLINE_LINUX
中添加到 /etc/default/grub
的末尾(假设您使用的是标准 Linux dist,如果您使用的是设备,则 grub 配置的位置可能不同),例如:< /p>
GRUB_CMDLINE_LINUX=".......Current config here **maxcpus**=2"
然后通过运行重新制作您的 grub 配置
grub2-mkconfig -o /boot/grub2/grub.cfg
(或 grub-mkconfig -o /boot/grub2/grub.cfg
,取决于您的安装)。某些发行版可能需要 nr_cpus
而不是 maxcpus
。
只是一些额外的信息:
如果您正在运行具有多个物理 CPU 的服务器,那么禁用一个 CPU 很可能会禁用链接到该 CPU 的内存集,因此它可能会影响服务器的性能
以这种方式禁用 CPU,不会影响您的类型 1 管理程序访问 CPU(这是基于 xen 管理程序,我相信它也适用于 vmware,如果有人能提供确认会很棒) .根据 virtualbox 设置,它可能会限制您可以分配给 VM 的 CPU 数量,除非您正在运行半虚拟化。
但是,我不确定您是否会节省电量,如今大多数服务器甚至台式机都已经很好地控制了电源,让当前负载不需要的任何设备进入睡眠状态。我担心的是通过减少 CPU(核心)的数量,然后您将只将负载转移到剩余的 CPU 上,并且由于需要安排处理器时间,并且可能有指令排队,以及数量较少的影响可用于中断的内核数量(例如:网络流量),可能会对功耗产生负面影响。