简介:这是一款面向系统管理员、开发者与硬件爱好者的Windows CPU占用率模拟工具,能在浏览器中直接设置CPU负载比例与持续时间,用于服务器稳定性测试、硬件散热评估及开发调优等场景下制造可控压力。资源包非常轻量,整体仅34KB,共包含2个文件:一个HTML主页面负责提供操作界面,一个JS脚本负责执行负载逻辑,无需安装环境、解压即用,也方便携带分享。目前已有718人学习/下载。使用时通过直观的页面参数即可启动压测,达到设定时长或关闭浏览器后负载自动解除,不会残留后台进程;同时工具也提醒了长时间高负载可能导致过热,需在散热良好的设备上谨慎操作。整体来看,这是一款简单实用的压测小工具,既适合快速验证系统响应能力,也能帮助使用者更直观地理解CPU资源调度与占用机制。
1. 刷 CPU 使用率之前:先分清你是在压测还是在上演
“Windows刷CPU使用率工具”这个标题,我在不同场景下被问过两种完全相反的需求:一种是真的要把 CPU 拉满,比如跑散热测试、验证服务器在满载下的稳定性、或者给虚拟化平台做压力摸底;另一种是“让任务管理器里的占用率显得高一点”,比如验证监控告警阈值、给演示环境制造负载,或者避免电脑空闲被睡眠策略踢下线。这两类需求对应完全不同的工具选型,用错了翻车概率极大——用烤机软件去“表演占用率”,会把机器温度顶到降频甚至关机;用短占空比脚本去“压测稳定性”,又因为负载波形太碎,根本测不出散热和供电的极限。所以我先把结论放前面:没有一把通吃的 Windows CPU 占用率脚本,只有“真实负载工具”和“虚拟占用脚本”两条路线。这篇笔记把两条路线的原理、最小可用命令、参数边界和坑都过一遍,新手可以直接抄作业,熟手也能对照着查一下自己踩过的雷。
2. CPU 使用率是怎么算出来的:理解采样机制和工具选型逻辑
2.1 任务管理器里的百分比不是“测量值”,是采样计算值
很多人第一次写 CPU 占用脚本时会困惑:明明脚本在死循环里空转,任务管理器却显示 CPU 只有 25% 或 50%,而不是 100%。问题不出在脚本,出在对 Windows CPU 使用率计算机制的理解上。Windows 内核里的每个线程都有运行状态,性能计数器(Performance Counter)会统计每个处理器核心在单位时间内的空闲时间占比。任务管理器、性能监视器和第三方工具展示的 “% Processor Time”,本质上都是对“空闲时间采样”做一次换算:采样周期内该核心忙碌的时间除以采样周期总时长。
这个采样周期不是无限小的。任务管理器在 Win10/Win11 上默认更新间隔是 2 秒,手动改成“高”也才 0.5 秒。所以你写一个 10 毫秒忙、10 毫秒闲的空循环,任务管理器看到的结果可能已经是被窗口平均过的数值,这会造成一个经典假象:不同工具(任务管理器、资源监视器、Process Explorer)显示的占用率对不上。搞明白这一点之后再选工具就不会犯低级错误——真实压测场景需要的是“能真正吃满指令执行单元”的工具,虚拟占用场景需要的是“占空比可控且能被采样窗口准确识别”的脚本。
2.2 五类常见工具怎么选:烤机软件、压力工具、监控工具和自写脚本
从业者常用的 Windows CPU 占用工具可以分成几类,适合场景差异极大。我给你一张选型参考表,这表是按我自己的使用习惯整理的,不是说明书。
| 类别 | 工具/脚本代表 | 负载特征 | 适合场景 | 不适合场景 |
|---|---|---|---|---|
| 烤机/稳定性 | OCCT、AIDA64、Prime95 | 高密度计算,支持 AVX2/AVX512 指令 | 散热验证、稳定性测试 | 演示、监控告警测试(负载过猛) |
| 轻量压测 | CPUSTRES(Sysinternals) | 可控线程数、可控压力级别 | 快速拉高占用率、多线程调度测试 | 极端稳定测试(AVX 指令集不够激进) |
| 系统自带 | Windows 性能监视器、WinDiag | 实时采样、生成日志 | 基线采集、负载记录 | 不能自己产生负载 |
| 脚本虚拟占用 | PowerShell 循环 + Start-Sleep | 忙闲交替占空比 | 模拟指定百分比、告警演示 | 不能验证散热和供电 |
| 综合性 | Process Lasso、Bitsum | 常驻的 CPU 调度/限制工具 | 限制某个进程占用 | 不是主动压测工具 |
这里特别注意 CPUSTRES 和 OCCT 之间的“AVX 指令集”差异。CPUSTRES 的负载以普通浮点和整数运算为主,功耗和热量低于启用 AVX-512 后的 OCCT。同样是占用率 100%,AVX-512 负载下 CPU 的温度可能高出 15 到 20 度。如果你用 CPUSTRES 测出来机器温度才 60 度,就断言散热没问题,那大概率会翻车——游戏或视频导出这类真实高负载场景可能瞬间突破 85 度。所以选工具前先问自己一句:我要的“100%”是占用率数字,还是一个能让供电、散热、硅脂真正进入满载考验的发热源?
3. CPUSTRES 实战:把 Windows CPU 精准压到指定占用率的最小命令
3.1 用 cpuSTRES.exe 跑起来:命令行参数和首屏验证
如果你要的是“简单、快速、可重复”的压测工具,我一般会用 Sysinternals 的 CPUSTRES。它不是绿化工具需要挨个点,但也算轻量级压测里的首选了。下载后解压到固定目录,比如C:\tools\,然后在管理员权限的命令行里这样启动:
C:\tools\cpuSTRES.exe -t 8 -s 100 -r 120 -accepteula这条命令的含义:-t 8表示启动 8 个压力线程,如果你的 CPU 是 8 核 16 线程处理器,8 个线程只占物理核心,不会触发超线程叠加;-s 100表示压力级别为 100,这个值范围是 0 到 200,100 代表中高压力,一般对应任务管理器里 50% 到 70% 附近的占用;-r 120是运行 120 秒后自动退出,避免压测完忘记停止导致机器一直满负荷;-accepteula是接受 Sysinternals 许可证协议,避免首次运行弹窗。
启动后 GUI 面板会打开,你能在 “Active” 一列看到每个线程的实时状态。这里强调一下,-s 100不等于 CPU 占用率 100%,CPUSTRES 的压力级别是“线程内计算强度”,最终任务管理器显示的总占用还要看线程数、处理器频率墙以及你是否开启了 Hyper-V 或 VBS(基于虚拟化的安全)这类会占用调度资源的系统功能。如果你的目标是“跑满所有逻辑处理器”,线程数建议直接给到逻辑处理器总数,可以用 PowerShell 查询:
(Get-CimInstance Win32_Processor).NumberOfLogicalProcessors3.2 把“压到 70%”变成可重复执行的批处理脚本
很多做告警阈值验证的人会来找我,说想模拟一个“CPU 占用略高但不到告警线”的状态。直接跑满 100% 会触发热保护,跑得太低又触发不了告警逻辑。CPUSTRES 配合-s可以粗调,但更可控的做法是用 PowerShell 写一个简单的“忙闲占空比”脚本,这个脚本才是真正能做出精确百分比的东西。
# Set-PseudoCpuLoad.ps1 param( [int]$Percent = 50, # 目标占用率,仅对单线程生效 [int]$Duration = 30, # 持续时间(秒) [int]$Threads = 1 # 并发线程数 ) $jobs = @() 1..$Threads | ForEach-Object { $jobs += Start-Job -ScriptBlock { param($p, $d) $sw = [System.Diagnostics.Stopwatch]::StartNew() while ($sw.Elapsed.TotalSeconds -lt $d) { $cycle = [System.Diagnostics.Stopwatch]::StartNew() while ($cycle.Elapsed.TotalMilliseconds -lt $p) { # 空转循环,让本核心保持忙碌 } Start-Sleep -Milliseconds (100 - $p) $cycle.Stop() } } -ArgumentList $Percent, $Duration } Wait-Job $jobs | Out-Null $jobs | Remove-Job这段脚本的逻辑很简单:每个线程循环执行“忙碌 50 毫秒 + 空闲 50 毫秒”的占空比,当$Percent = 50时,理论占用率即为 50%。两个参数是关键:$Percent直接对应忙循环时长;$Duration控制整体执行时间。执行时注意,Start-Job对系统开销不小,线程数不要超过逻辑处理器总数,否则多个 Job 挤在同一核心上,调度器会强行分时,占用率和执行时间都会失真。
实测时你会发现一个现象:$Percent设为 10 时,任务管理器显示的占用率可能只有 5% 甚至更低;设为 90 时,可能稳定在 85% 左右。这背后是 Windows 线程调度器的时钟粒度和任务管理器 2 秒采样窗口在起作用。另外,脚本只在当前电源计划下有效——插电和用电池的处理器频率策略不同,同样占空比在两种电源模式下的实际百分比能差出 20%。所以我建议把脚本结合电源计划一起用,后面避坑部分会展开讲。
3.3 多线程与超线程:为什么 8 线程脚本跑不出 100%
如果把上面的脚本直接跑 16 线程,你会发现处理器占用率可能在 90% 上下晃动,始终顶不到 100%。常见原因是 Windows 处理器电源管理“处理器最大频率”默认被限制为 99% 或 100% 但伴随睿频策略。另一个原因是超线程:同一个物理核心上的两个逻辑处理器共享执行单元,都跑空转循环时不会简单叠加成两倍负载,而是共享同一份计算资源。这是正常现象,不代表脚本有问题。
遇到这种情况,先看性能监视器里\Processor(_Total)\% Processor Time的平均值而不是瞬时尖峰;如果平均值在 90% 以上,说明脚本的多线程控制已经生效。真正需要排查的是脚本有没有被 Windows 调度到同一个物理核心上,以及系统里有没有其他后台进程(比如 Windows Search、SysMain 服务)抢占了 CPU 时间片。多核压测有个更土但有效的验证方法:打开任务管理器“性能”选项卡,把 CPU 视图改到“逻辑处理器”,观察是否所有格子都在动。只要每个格子都有明显的忙闲节奏,基本可以确认脚本已经把处理器调动起来了。
4. 虚拟占用脚本:用 PowerShell 伪造 CPU 占用率的边界和更稳的写法
4.1 占空比为什么在 Windows 上不精确:时钟粒度是最大敌人
上一章给出的脚本在短周期(100 毫秒级)下并不稳,这一点必须单独拉出来说清楚。Windows 的默认系统时钟间隔大约是 15.6 毫秒,Start-Sleep的精度也被限制在这个量级附近。如果你让脚本“忙 5 毫秒 + 闲 5 毫秒”,实际执行时忙循环可能跑出 8 毫秒,闲 5 毫秒也可能变成 16 毫秒再加几毫秒误差——占空比早就不是 50% 了。更麻烦的是,Windows 在检测到高负载时可能动态调整时钟间隔,导致误差进一步放大。
我常用的规避方法是把占空比周期拉长到 200 毫秒以上。比如目标 50% 占用率,可以写“忙 100 毫秒、闲 100 毫秒”或“忙 150 毫秒、闲 150 毫秒”。周期拉长后,15.6 毫秒的时钟粒度只占周期的一小部分,误差占比被压到 8% 以下。这是纯经验值,不是某个库的官方参数,但对任务管理器这类采样间隔较长的监控工具来说已经足够稳定。
4.2 多进程方案比多线程 Job 更可靠:用 PowerShell 开 N 个进程
另一个导致“占空比脚本不准”的坑是 Start-Job 本身的开销和调度不确定性。每个 Job 都是一个独立的 PowerShell 进程,进程启动、初始化 runspace、垃圾回收都会占用额外的 CPU 时间,空转周期的纯洁性被破坏。所以我实际压测时很少用 Start-Job 控制多线程,而是直接启动多个 PowerShell 进程,每个进程单独执行一个忙闲循环,命令长这样:
powershell -ExecutionPolicy Bypass -File C:\scripts\SingleCpuLoad.ps1 -Percent 50 -Duration 60配合一个单独的“单核虚拟占用”脚本:
# SingleCpuLoad.ps1 param([int]$Percent = 50, [int]$Duration = 60) $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $busyMs = $Percent $idleMs = 100 - $Percent while ($stopwatch.Elapsed.TotalSeconds -lt $Duration) { $sw = [System.Diagnostics.Stopwatch]::StartNew() while ($sw.Elapsed.TotalMilliseconds -lt $busyMs) { } Start-Sleep -Milliseconds $idleMs }这个脚本每个实例只占用一个逻辑处理器。要想占满 8 核,就手动开 8 个进程。如何确认脚本有没有被调度到不同核心上?任务管理器“逻辑处理器”视图一眼就能看出来。这个多进程方案的稳定性远超 Start-Job,因为每个 PowerShell 进程是独立进程,Windows 调度器会均匀地把它分配到不同核心,不会出现多个线程挤一个核、另一个核心闲得发慌的情况。
注意,伪造占用率和真实负载之间有一条不可逾越的边界:PowerShell 空转循环不会触发 CPU 深度变频和供电极限。所以它只能用来骗过基于“占用率数字”的监控告警,不能用来测试散热。如果你拿它去替代烤机工具拉高温,很容易出现“占用率 100% 但温度只有 45 度,一跑游戏直接 90 度”的尴尬场景。做散热测试还是老老实实用 OCCT 这类支持 AVX 指令集的真实负载工具,虚拟占用脚本在意的是“数字像不像”,不是“负载实不实”。
4.3 把脚本做成服务:让占用率“开机自启”而不依赖人工
演示或监控验证场景中,往往需要占用率脚本在一台机器上长时间自动跑,而不是手动开一堆窗口。用Start-Process配合计划任务可以做到,但更省心的方案是注册成 Windows 服务。常见做法是使用NSSM(Non-Sucking Service Manager)把上面的 PowerShell 脚本包装成服务:
nssm install PseudoCpuLoad "powershell.exe" "-ExecutionPolicy Bypass -File C:\scripts\SingleCpuLoad.ps1 -Percent 30 -Duration 0" nssm set PseudoCpuLoad AppExit Default Restart nssm start PseudoCpuLoadDuration 0在脚本里应被解释为持续运行直到手动停止(在脚本加一层判断即可),AppExit Default Restart保证脚本意外退出后被服务自动拉起。这个方案很适合给那种“演示环境需要显示稳定 30% 占用率”的测试台用。注意服务账号建议用 Local System,或者确认运行账号有“调整内存配额”权限,否则脚本里的高频率循环可能被系统判定为异常行为,触发限制。这个坑我见过不止一次,测试环境还好,生产环境里服务账号权限不足会导致脚本频繁崩溃,最终占用率归零,告警也测不出来。
5. 避坑清单:从占用率数字到真相的几个排查点
5.1 现象一:占用率顶到 100%,温度却只有四十几度
原因:你用的压力工具负载强度不够,可能是普通整数运算而非 AVX/FMA 指令密集负载。CPUSTRES 和自写 PowerShell 脚本都属于这种“轻烤”工具,它们的 100% 占用率对应的发热量远低于 Prime95 或 OCCT 的 AVX 模式。解决:做散热验证时改用支持 AVX2/AVX512 的烤机工具,并在工具选项里手动启用 AVX。如果你坚持用轻量工具,至少加一个红外温枪或传感器读数做参考,不能只看“满不满足 100%”。
5.2 现象二:设置 50% 占用率,实际在 30% 到 70% 之间大幅波动
原因:占空比周期太短,Windows 时钟粒度 15.6 毫秒导致的误差被放大;加上任务管理器是 2 秒采样,看到的已经是多个周期的平均值。解决:把忙闲周期从 100 毫秒拉长到 200 毫秒或 500 毫秒。以 50% 占用为例,写“忙 200 毫秒 + 闲 200 毫秒”,误差占比可以压到 8% 以内,波动会小很多。记住这个经验值:短周期追求的是响应速度,长周期追求的是读数稳定。
5.3 现象三:插电与电池模式下,同样脚本结果相差 20%
原因:Windows 电源计划会自动调整处理器最大频率。插电时睿频放开,空闲时间占比小,占用率反而偏低;电池模式下频率被压低,空转循环占用更多时间片,占用率反而偏高。解决:压测前把电源计划统一到“高性能”,并在“处理器电源管理 > 最大处理器状态”里设为 100%。这不是玄学,是 Intel 和 AMD 平台一致的调度策略。做对比测试时一定要保证电源模式一致,否则数据没有可比性。
5.4 现象四:多核利用率不均匀,一个核心红了,其他核心绿着
原因:多线程脚本里的Start-Job或Start-Process没有显式绑定核心,Windows 调度器把多个轻量线程塞到了同一个物理核心上。解决:用Process Lasso或脚本里调用SetProcessAffinityMask接口,把每个进程绑定到指定核心。物理核心 0、2、4、6 和逻辑核心的具体编号可以通过Get-CimInstance Win32_Processor配合解析得到。注意,如果开了 Core Isolation(内存完整性),某些 CPU 亲和性设置可能不生效,要不要关看你的安全基线。
5.5 现象五:压测中途系统像死了一样,鼠标都动不了
原因:压测线程的优先级过高,占满了所有 CPU 时间片,连系统 UI 都没有余量执行。尤其是 CPUSTRES 的-s 200模式,会把系统拖到几乎无响应的状态。解决:保守做法是把压力级别控制在 170 以下,或者用任务计划设置压测超时后强制结束进程。真需要跑 200 级别,建议通过远程 PowerShell 启动压测,避免本地操作时卡死。另外一定记得设置-r参数,给压测一个自动退出的时间,别跑一夜没人管。
6. 让压测结果可验证:用性能计数器做采样,别信单点读数
6.1 用 Get-Counter 写一个 5 秒粒度的采样器
任务管理器的瞬时读数适合快速判断,不适合做“验证本次压测是否有效”的依据。我现在做压测,习惯性先启动一个性能计数器采样脚本,把 CPU 占用率历史拉出来看趋势。下面的 PowerShell 代码可以每 5 秒采集一次_Total和每个逻辑处理器的占用率,并落盘成 CSV:
# Sample-CpuUsage.ps1 $samples = @() for ($i = 0; $i -lt 120; $i++) { $total = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples[0].CookedValue $samples += [PSCustomObject]@{ Time = Get-Date -Format "HH:mm:ss" Total = [math]::Round($total, 1) } Start-Sleep -Seconds 5 } $samples | Export-Csv "C:\perf\cpu_$((Get-Date).ToString('yyyyMMdd_HHmmss')).csv" -NoTypeInformation这里的CookedValue是已经换算好的百分比数值,单位是 %;Export-Csv落盘后可以用 Excel 或 VSCode 直接画趋势线。我一般跑 10 分钟,拿到 120 个采样点后看两个指标:平均值和目标值的偏差是否在 5% 以内、是否有规律性的塌陷(比如每 20 秒掉到 0 一次,可能是有后台任务或服务在干扰)。
为什么要这么做?因为单次瞬时读数会骗人。比如任务管理器里盯着看 3 秒,可能正好看到高峰或低谷,就以偏概全判断压测效果不合格。采样落盘后你看到的是一条时间线,能分清“整体稳定但毛刺多”和“周期性掉零”这两种完全不同的状况。前者说明占空比脚本本身没问题,监控工具抖动而已;后者通常是第三方应用或系统服务抢占了时间片,比如 Windows Update、Defender 扫描。落盘还有一个好处:压测结束后把 CSV 存留作为测试报告附件,比给领导口说“跑满了”有说服力得多。
6.2 样本量的选择:至少 30 个采样点再下结论
关于采样点数,我给自己定的习惯是最少 30 个点、常规 120 个点。30 个点(在 5 秒间隔下是 2 分半钟)足够判断平均值是否稳定,但要发现周期性问题最好跑满 10 分钟。另外有个验证技巧:在同一台机器上,先用 CPUSTRES 压测跑 5 分钟采样,再用 PowerShell 虚拟占用脚本跑同样时间,两份 CSV 做对比。你会发现真实压测的采样线是一条“平滑的直线”,偶尔有极窄的抖动;而虚拟占用脚本的采样线会出现明显的周期性锯齿。锯齿本身不代表脚本失效,而是占空比周期的正常反应,但如果锯齿幅度超过 15%,就说明占空比周期太短或系统后台干扰太重,需要调参。
回头说自己吃过的亏:有次做服务器稳定性验收,我盯着任务管理器看了五分钟,确定 CPU 保持 100%,随后就签字通过了。三天后业务上线,凌晨 CPU 满载时机器直接重启,查日志发现散热模块在高负载下触发了过热保护。后来复盘,那次所谓的“100%”是默认频率下的普通指令负载,根本没把 AVX 频率下的功耗和温度测出来。从那以后我的所有压测都强制走两步:第一步确认采样的平均占用和目标一致,第二步用支持 AVX 的烤机负载确认温度和功耗曲线。这两步做完,才算真正完成“刷 CPU 使用率”的闭环。这套习惯对你也许繁琐,但值得照做——毕竟数字说谎的成本,在网络设备和硬件面前往往比我们想象的贵得多。希望帮到你。
本文还有配套的精品资源,点击获取