去年我在折腾一台新配置的电脑时遇到一个很典型的问题:跑一个单线程为主的工程计算程序,风扇直接起飞,但任务管理器里总 CPU 占用率却只有 30% 左右。后面我用工具把每个逻辑核心的占用摊开一看,当场就乐了——八个 E 核(能效核)忙得快冒烟,六个 P 核(性能核)几乎在旁边“看戏”。这种“CPU 大核闲着、程序死活不跑上去”的情况,在大小核混合架构普及之后真的太常见了。问题通常不是程序不行,而是系统调度器没有把任务放对位置。
这篇文章不聊虚的,只聊 CPU 亲和性(CPU affinity)这件事:它到底是什么、为什么能解决“大核闲置”、Linux 和 Windows 上分别怎么操作、绑核之后怎么验证有效,以及哪些场景千万别盲目绑核。我的话放在前头:绑核不是万能药,但它确实是让关键程序优先用上高性能核心最直接的手段。
1. 大核闲着、小核狂奔:先把脉再开药
1.1 大小核混合架构下,“你以为的 CPU”和“调度器眼里的 CPU”不是一回事
从 Intel 12 代 Alder Lake 开始,x86 桌面和移动端也全面转向了类似 ARM big.LITTLE 的大小核混合架构:一组性能核(P-Core,大核)负责高负载和低延迟场景,一组能效核(E-Core,小核)负责后台任务和省电场景。P 核单线程能力强、缓存和频率上限高,E 核面积小、能效比好,适合一堆不太吃单核性能的任务并行跑。
但这里有个容易被忽略的点:操作系统的调度器并不会自动把“你觉得重要的程序”放到“你觉得快的核心”上。操作系统调度器看到的不是一个一个带标签的物理核心,而是一组逻辑处理器编号组成的调度域。现代调度器确实会参考核心的算力差,但它的首要目标是“系统整体吞吐量高 + 功耗可控 + 延迟可接受”,不是“让某个程序跑得最快”。所以在默认的平衡策略下,一个后台服务、一个刚启动还没有来得及被判定为“前台高优先级”的程序,完全可能被丢到 E 核集群上一直跑。
举个例子:某些游戏平台或启动器带起来的游戏主程序,从启动器子进程继承的优先级和调度分类并不高;系统先把它塞进空闲的 E 核,等之后负载上来了,调度器再把它往 P 核迁移。可如果这个程序自己不配合,或者系统调度迁移发生得太晚,你就会看到“总占用率不高但卡成 PPT”的诡异现象。
1.2 调度器默认策略是把省电放在性能前面
Intel 在 Windows 11 里提供了 Thread Director,理论上能让调度器识别 P/E 核并优化线程放置;Windows 10 对大小核架构基本没有这套精细识别,效果主要靠更新补丁和厂商驱动兜底。Linux 这边,近年内核也在逐步完善混合架构的调度支持,但前提是你的发行版内核版本、固件、驱动都足够新,而且电源管理策略默认可能还是偏向节能。
现实是:在 Windows 10 上,很多 Alder Lake/Raptor Lake 用户不装厂商调度补丁,或者用了笔记本默认的“平衡”电源模式,P 核经常处于低负载甚至几乎空转的状态,E 核却被塞满了各种线程。在 Linux 上,不少桌面发行版默认的 CPU 调频器是 schedutil 或 conservative,它们会优先压低频率和选择低容量核心,对混合架构的利用率并不理想。
所以当你发现“大核闲着”时,先别急着怪程序或硬件。第一步是确认你的系统有没有正确识别核心类型,第二步是确认电源/性能模式,第三步才是考虑用亲和性手动干预。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. CPU 亲和性其实只做一件小事:明确告诉调度器“我允许它去哪”
2.1 亲和性掩码与 CPU 编号的换算
CPU 亲和性,说人话就是:给一个进程或线程设一个“允许跑的核心白名单”。调度器在做任务分配的时候,只会从白名单里挑 CPU,白名单之外的核心即便空着也不会让这个进程跑上去。
这个“白名单”在系统底层是一把二进制的掩码。每个逻辑 CPU 占一个 bit,bit 为 1 表示允许,bit 为 0 表示禁止。比如一台只有 4 个逻辑 CPU 的机器,你想让进程跑在第 0 号和第 2 号核心上,掩码的二进制就是 0101,从右往左数分别是 bit0、bit1、bit2、bit3,对应十六进制就是 0x5。但在 Linux 下其实不用自己算得这么痛苦,taskset 支持直接写 0-3,8-11 这样的列表形式,系统会帮你
