
1. CoreMark 到底在测什么它凭什么成为通用标尺机器拿到手第一件事永远是摸底。CPU 性能测试工具 coremark 就是我在摸一颗 CPU 底细时最常掏出来的东西它体量小、依赖少、跑起来快、结果横向可比编译一次就能在 x86 服务器、ARM 开发板甚至裸机 MCU 上给出一个能直接对比的数字。它测的是处理器在整数运算、指针跳转、分支预测和内存访问这几条路径上的综合吞吐能力最终输出一个iterations/sec的分数和CoreMark/MHz的效率值。适合谁用做嵌入式选型的、做服务器采购比价的、折腾交叉编译工具链的、验证内核调频与调度策略的都能从它身上拿到有用信息。新手也能跑因为它几乎没有依赖项源码一解压一条 make 命令就能出结果不需要你去装什么庞大的框架。但我不建议把它当成万能尺子。CoreMark 是一个高度标准化、刻意收敛了测试面的微基准它的价值在于可比而不是全面。你要是拿它去预测一台服务器跑数据库能扛多少 QPS那基本等于用体重秤去量身高数字是有的但没什么意义。搞清楚它能干什么、不能干什么比会敲那几条命令重要得多。1.1 从 Dhrystone 的尴尬说起早年间大家测 CPU 都跑 Dhrystone那东西是 1984 年写出来的代码量小得可怜整个测试循环几乎能完整塞进一级指令缓存里。这带来一个很尴尬的后果测试过程压根没怎么访问内存测出来的其实是指令发射能力而已。更麻烦的是编译器太聪明了Dhrystone 里那个著名的Proc_1到Proc_5调用链稍微激进一点的优化就会把它整体内联甚至直接算成常量最后你测的是编译器的常量折叠能力而不是 CPU。这个问题在 GCC 进入-O3时代后彻底暴露同一颗芯片换个编译器版本能差出百分之三四十DMIPS 分数开始变得不可信。EEMBC 在 2010 年前后推出 CoreMark核心诉求就是代码量做大一点让数据集超出缓存同时把编译器优化空间压到最小让分数更多地反映硬件本身。这就是为什么 CoreMark 的数据集默认配了 2000 字节的堆块并且迭代次数少的时候还会被强行拉高——它的设计思路从一开始就是为了避免 Dhrystone 那种跑得太快以致于没测到东西的窘境。1.2 四类负载拆开看它到底考了什么CoreMark 的源码里主要工作负载集中在四个文件里我按自己的理解拆一遍。core_list_join.c负责链表操作在链表里查找节点、把节点摘出来、按顺序插回去、再做一次归并排序。这一段考的是指针解引用、随机内存访问和分支预测。链表节点在内存里是散着放的缓存命中率天然不高所以这一段对缓存大小和预取器行为很敏感。core_matrix.c做整数矩阵乘法与加法考的是循环嵌套下的访存局部性和整数乘加吞吐。注意它是整数运算不是浮点所以不要拿它的结果去推测芯片的浮点峰值。core_state.c是一个状态机把输入流的每个字节拿去查表并做状态转移考的是查表访问和分支跳转。core_util.c里装的是 CRC 校验默认 CRC16也可以切 CRCc 或 CRC32这一段是典型的位运算密集型负载对移位、异或这类指令的吞吐比较敏感。四段合起来覆盖了整数、指针、分支、访存四类压力刻意避开了浮点和 SIMD。这意味着它给的是一个通用整数性能的画像。1.3 和主流测试工具的横向对比不同工具定位完全不同我把常被拿来一起说的几个整理成一张表方便选型时对号入座。工具负载特征主要用途是否适合跨架构对比跑一轮耗时CoreMark整数、指针、分支、访存嵌入式与通用 CPU 整数性能适合标准统一10 秒到几分钟Dhrystone短小、可入缓存历史遗留的 DMIPS参考价值下降秒级Whetstone浮点为主浮点运算能力一般秒级UnixBench系统调用、进程、文件、shell整机综合分差受发行版影响大十几分钟到几十分钟SPEC CPU真实应用编译的负载服务器级权威基准适合但成本极高数小时Linpack稠密线性代数高算力集群排名仅浮点场景分钟到小时7-Zip 内置基准压缩算法快速看单核/多核整数性能一般十几秒我的实际做法是CoreMark 负责快速摸底和交叉验证SPEC CPU 或真实业务压测负责最终决策。CoreMark 给出的数字如果和后来的真实压测趋势不一致那通常说明你的业务瓶颈不在整数运算上比如卡在 IO 或者内存带宽这时候该换工具而不是怀疑 CoreMark。另外要提醒一句CoreMark 分数受编译器版本和优化选项影响仍然存在所以跨平台比较的前提是两边用的是同一套工具链版本和同一组编译参数这一点后面会展开讲。1.4 什么时候该用它什么时候赶紧换我的判断标准很简单。要做 CPU 架构本身的能力对比、要验证频率调节策略是否生效、要确认交叉编译工具链有没有把代码编废、要在没有操作系统的裸板上给出一个性能参考值——这些场景 CoreMark 都很合适因为它足够轻、可控、可复现。反过来要评估数据库、Web 服务、AI 推理、视频转码这类真实业务的承载能力CoreMark 帮不上忙。它不是压力测试工具不能用来做稳定性验证也不该用来判断一颗 CPU 会不会过热降频。想要压出温度上限那是另外一套玩法得配合持续负载工具加上温度采集后面我会讲到怎么和 CoreMark 搭配起来看。2. 拿到源码先别急着 make目录结构与编译体系拆解很多人拿到 CoreMark 压缩包第一反应是解压、进目录、敲 make跑出一堆数字就完事。这么做能出结果但一旦要交叉编译、要改迭代次数、要跑多线程就会立刻卡住。我建议先花十分钟把目录结构和几个关键宏看清楚后面能省掉大量试错时间。CoreMark 的工程组织方式其实相当克制核心文件就那么几个理解了它整个构建逻辑就通了。2.1 仓库里都有什么解压之后你会看到根目录下两类东西一类是核心测试代码一类是平台适配目录。核心代码包括core_main.c、core_list_join.c、core_matrix.c、core_state.c、core_util.c加上头文件coremark.h。这几个文件是跨平台通用的改了它们分数就不具备对比意义了所以原则上不要动。平台适配目录则是每个目标平台一份常见的有linux/、barebones/、simple/里面放着core_portme.h和core_portme.c。这两个文件是移植的关键core_portme.h决定数据类型定义、时钟函数声明、编译选项字符串core_portme.c负责实现计时、串口输出、启动和收尾这些和硬件强相关的行为。在 Linux 上跑直接用linux/目录就行因为它直接调用clock_gettime拿纳秒级时间戳输出走标准 printf。到了裸机环境你就得自己在barebones/里把这两个函数填上。2.2 三个最容易踩坑的宏第一个是ITERATIONS控制迭代次数。它的取值直接决定测试跑多久也直接决定分数是否可信。默认值偏小在快机器上可能一秒就跑完了这个时长下缓存预热和调度抖动的影响会被放大测出来的分数波动很大。第二个是TOTAL_DATA_SIZE默认 2000 字节代表算法使用的数据块大小。这个值要卡在目标芯片的 L2 缓存以内并且明显小于 L3目的是让测试重点落在核心计算上而不是内存带宽上。如果你把它改到几十兆测出来的就变成内存子系统性能了那就偏离了 CoreMark 的本意。第三个是MEM_METHOD可选MEM_STATIC、MEM_STACK、MEM_MALLOC。它会改变数据块的分配方式进而影响访存模式和最终分数。跨平台对比时两边必须选同一个值否则分数不可比这是我踩过的一个坑曾经拿MEM_STATIC的分数去比别人的MEM_MALLOC白折腾半天。2.3 编译命令逐条拆开讲在 Linux 上最省事的命令是cd coremark make PORT_DIRlinux这条命令会编译出一个coremark.exe。注意它虽然叫 exe在 Linux 上就是个普通的 ELF 可执行文件不要被后缀误导。如果你想指定编译器和并行编译可以这样make PORT_DIRlinux CCgcc XCFLAGS-O2 -DMEM_METHODMEM_STATIC -j8XCFLAGS会作为额外编译参数传进去同时 Makefile 会把一部分参数拼进FLAGS_STR最终打印在结果里。这个细节很重要因为报告里会显示编译选项字符串任何人都能据此判断你的分数是不是在合规条件下跑出来的。多线程版本这样编make PORT_DIRlinux XCFLAGS-DMULTITHREAD4 -DUSE_PTHREAD1 -O2MULTITHREAD4表示开 4 个线程USE_PTHREAD1表示用 pthread 实现也可以换成-DUSE_FORK1用进程方式。两者在 Linux 上结果接近但 fork 方式进程创建开销大一些线程数多的时候差异会更明显。3. 实操在三种平台上跑出可复现的分数命令会敲不等于结果可信。我见过太多人拿着一个漂移了百分之二十的分数去下结论最后选型选错。这一节我把 x86、ARM 交叉编译、多核这三种典型场景的完整流程走一遍重点放在怎么让分数稳定可复现而不是怎么把程序跑起来。3.1 在 x86 服务器或 PC 上跑第一组分数编译完成后标准运行命令长这样./coremark.exe 0x0 0x0 0x66 20000 7 1 2000这几个参数我逐个解释。前三个是随机种子分别对应运算种子、列表种子和状态机种子一般保持默认第四个是迭代次数我这里写了 20000实际取值要看你的机器速度目标是让运行时间落在 10 秒到 30 秒这个区间第五个是数据集尺寸档位7 是官方常用值第六个是校验类型1 代表 CRC162 是 CRCc3 是 CRC32第七个是内存块大小需要和编译时的TOTAL_DATA_SIZE对齐。运行结束你会看到类似这样的输出CoreMark Size : 666 Total ticks : 15234 Total time (secs): 15.234000 Iterations/Sec : 1312.35 Iterations : 20000 Compiler version : GCC 11.4.0 Compiler flags : -O2 ... Memory location : Static seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x4983 Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 1312.35 / GCC 11.4.0 -O2 ... / Static看到Correct operation validated这一行才算数如果出现校验失败说明编译过程中有东西被优化掉了或者内存分配出了问题这个分数直接作废必须先排查。第一次跑出来先别急着记我一般会连续跑五遍把五次的Iterations/Sec抄下来算一下极差。如果极差超过百分之三就说明环境不够干净得先治理再测。常见的干扰源有后台服务抢核、温度墙触发降频、CPU 处于节能调频档、NUMA 跨节点访存。逐个排掉以后分数才会收敛到一个稳定区间。3.2 交叉编译到 ARM 开发板barebones 移植要不要做给 ARM 开发板跑 CoreMark 有两条路。如果板子跑的是完整 Linux那直接在板上装 gcc 编译或者用交叉编译工具链编好再传过去都行命令是make PORT_DIRlinux CCarm-linux-gnueabihf-gcc注意这里只是换编译器PORT_DIR还是linux因为操作系统是 Linux计时和输出函数不用改。编完把可执行文件拷到板子上跑就行。如果板子是裸机或者极简 RTOS那就得用barebones/并且自己填移植函数。需要实现的核心是两个一个是计时函数要用定时器实现保证能返回毫秒或微秒级的累计时间另一个是输出函数把结果通过串口打出来。这里有个高频坑——很多人用主频估算来当计时结果测出来的分数完全不可信因为主频本身可能有偏差、可能被动态调节。必须用真实的硬件定时器来计时这是硬要求。移植时还要注意core_portme.h里typedef的数据类型宽度必须和你的架构匹配。ARM 上int是 32 位这没问题但如果目标是小端 8 位单片机就需要仔细核对ee_u32、ee_s16这些类型的实际宽度宽度错了 CRC 校验就会失败这是排查起来最费时的一类问题。3.3 定频、绑核、关睿频让分数真正可复现这是整个流程里最容易被忽视、但对结果影响最大的一环。默认状态下现代 CPU 会根据负载动态调频还可能开睿频你测到的分数里有相当一部分是频率策略的贡献而不是架构能力的差异。先把调频策略锁到性能模式sudo cpupower frequency-set -g performance然后确认一下当前频率cpupower frequency-info对于使用 intel_pstate 驱动的机器还要考虑关掉睿频让全核频率一致echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo接着是绑核避免测试线程被调度到其他核心上也避免被其他进程干扰taskset -c 2 ./coremark.exe 0x0 0x0 0x66 20000 7 1 2000如果要做多核对比就明确绑定到指定的核心集合比如taskset -c 0-3同时保证别的同时发生否则结果没法解释。还有一个细节关掉不需要的后台服务。我在一台跑着监控 agent、日志采集、定时任务的机器上测过同一份代码同一颗 CPU清掉后台后分数提高了将近百分之八。这个差距足以让你误判两颗 CPU 的优劣所以测试环境一定要保持干净。3.4 多核怎么测分数为什么不能简单乘多线程版本编译完之后MULTITHREADN里填的 N 就是线程数。跑出来的Iterations/Sec是总吞吐直接和单线程分数比就能看出多核扩展效率。这里有个常见误解很多人拿单核分数乘以核数当成理论多核分数然后看到实际值只有理论的百分之七十就开始怀疑人生。实际上多核跑不满是正常的瓶颈可能在共享缓存带宽、内存控制器、环形总线或者频率下降。四核跑到单核的三点二倍、十六核跑到单核的十倍左右都是正常范围。真正值得关注的是同一架构在不同线程数下的扩展曲线这条曲线比单个数字有信息量得多。需要特别说明的是CoreMark/MHz这个指标只对单核有意义。多核场景下总吞吐除以频率得到的值会受到核间干扰影响拿来横向比较会误导人。多核看总吞吐单核看效率这条边界要分清。4. 结果怎么读从 iterations/sec 到 CoreMark/MHz数字出来了怎么读才算读懂了我见过两种极端一种是把Iterations/Sec直接当成性能分到处比另一种是看到机器 A 分数比机器 B 高就断定 A 更强。这两种做法都会出问题。这一节我把几个关键数字的含义和计算方式讲清楚顺便说说怎么做多次采样让结论站得住。4.1 三个输出数字分别代表什么Total time (secs)是实际运行的墙钟时间这个数字最重要的用途是判断你的迭代次数选得合不合适。低于 10 秒就偏短建议加大迭代次数重跑。Iterations/Sec是核心指标等于总迭代次数除以总时间。它反映的是单位时间内完成的工作量是横向比较的主数字。CoreMark/MHz是效率指标等于Iterations/Sec除以 CPU 实际运行频率单位 MHz。它剔除了频率的影响反映的是每兆赫兹能跑出多少分本质上是 IPC 加指令效率的综合体现。现代高性能乱序核心这个值通常在 3 到 5 之间一些精简架构会低到 1 到 2 的区间。看到明显高于 5 的数字就要留个心眼了可能是频率统计有误也可能是编译选项用了不合规的激进参数。4.2 迭代次数怎么定一次完整的计算过程我拿一台实测机器举例把迭代次数的确定过程走一遍。第一次试探性运行用默认迭代次数 1000结果跑出Total time是 0.87 秒Iterations/Sec约 1149。这个时间太短分数不具备参考性。目标是让运行时间落在 15 秒左右那么需要的迭代次数约等于目标迭代次数 当前每秒迭代数 × 目标时间 1149 × 15 ≈ 17235向上取整到一个整数用 20000 再跑一次得到Total time约 17.4 秒落在合理区间于是固定用 20000 作为这台机器上的迭代次数。换机器时重新做一遍这个计算不要直接沿用别的机器的值。为什么一定要卡在 10 秒以上因为 CoreMark 在启动阶段要做内存初始化、数据预热前期若干次迭代的缓存状态和稳态不一样。运行时间太短这段暖机过程在总时间里的占比就大分数会被系统性地拉低或者拉高。10 秒到 30 秒这个区间既能摊薄暖机影响又不至于让单次测试耗时太长方便做多次采样。4.3 CoreMark/MHz 才是跨平台比较的正确姿势假设你要比较两颗 CPU。A 是 2.5 GHz单核跑出 9000 分B 是 3.6 GHz单核跑出 10800 分。单看总分 B 赢但换算一下效率A: 9000 / 2500 ≈ 3.60 CoreMark/MHz B: 10800 / 3600 ≈ 3.00 CoreMark/MHz结论完全反过来了A 的每赫兹效率更高架构更能打只是主频低。这个例子说明为什么跨平台比较必须换算到CoreMark/MHz尤其是当你在两颗主频差异明显的 CPU 之间做选型时。顺便说一句这也解释了为什么看服务器 CPU 天梯图时不能只看总分排名很多榜单会同时列出效率值那个才是架构水平的体现。频率从哪来不能靠标称值要用实测值。可以读/proc/cpuinfo里的当前频率或者用cpupower frequency-info看实时频率。如果开了睿频实测频率会是浮动的这时候就要借助前面说的锁频手段把它固定下来否则算出来的效率值没有意义。4.4 多次采样与异常值处理单次结果不具备决策价值。我的习惯是同一配置下连续跑至少五次记录每次的Iterations/Sec。处理方式上先看离散程度。如果最大值和最小值相差在百分之二以内直接取平均值就行。如果差距在百分之二到百分之五之间建议取中位数并且检查一下是不是有偶发的后台干扰。如果差距超过百分之五不要急着取平均先去找干扰源把环境治理干净再重测。举个我实际遇到的例子。某台机器五次跑出来分别是 1284、1291、1278、1103、1288。前四个和后一个对比第五个明显偏低。查了半天发现是某个定时任务恰好在那一轮触发了磁盘写入抢占了 IO 和部分 CPU。把任务挪走之后五次结果都落在 1280 到 1292 之间这才是一个可信的数据集。处理这类异常值的原则是找不到原因的偏差不要轻易剔除找到原因的偏差必须重跑。4.5 校验值必须对这是底线输出里那几行crclist、crcmatrix、crcstate、crcfinal是自校验结果它们对应四类负载的输出校验和。这些值在同一个 CoreMark 版本下是固定不变的只要编译和运行过程没有出问题跨平台跨架构都应该得到相同的值。如果校验失败分数一律作废不管它看起来多漂亮。常见原因有三类编译器做了超出预期的激进优化把某些计算直接折叠掉了数据类型的宽度定义不对导致运算结果溢出或截断内存分配出问题指针越界覆盖了数据。排查顺序上先确认编译选项没有超过官方允许的范围再核对core_portme.h里的类型定义最后检查内存分配方式。5. 踩坑实录常见报错与分数异常速查这一节是我这些年攒下来的问题清单。CoreMark 本身很简洁出问题的位置相对集中整理成表以后排查效率会高很多。我按现象、原因、处理三段式列出来遇到问题可以直接对号入座。现象可能原因处理方式编译报错找不到 clock_gettime需要链接实时库在链接参数里加 -lrt运行后没有校验通过提示编译优化过度或类型宽度不匹配降低优化等级核对 core_portme.h 类型定义校验值和其他平台不一致架构字节序或类型宽度差异检查端序设置和整型宽度分数波动超过百分之五后台进程、调频、温度降频锁频、绑核、清后台、检查温度运行时间不足一秒迭代次数太小按 10 秒法则重新计算迭代次数并重编多核分数远低于预期内存带宽瓶颈或频率下降检查扩展曲线降低线程数对比定位瓶颈barebones 移植后分数异常高计时函数不准或用了主频估算改用硬件定时器实现计时交叉编译后运行崩溃工具链与目标 ABI 不匹配确认软浮点或硬浮点参数是否一致结果里内存位置显示异常MEM_METHOD 配置与编译不一致统一编译与运行时的内存分配方式表格只是索引有几个坑我想展开讲讲因为它们的迷惑性比较强。第一个是优化等级的选择。官方允许的优化级别是不超过-O2用-O3或者-Ofast跑出来的分数虽然好看但不具备可比性别人会认为你在作弊。我建议你就老老实实用-O2这个级别下分数已经能很好地反映硬件能力了追求那个虚高的数字没有任何意义。如果你想看-O3的差距可以单独跑一组做参考但报告的时候要明确标注编译参数让别人知道这个数字的语境。第二个是温度。很多人测嵌入式板子的时候发现跑着跑着分数往下降测完一摸芯片烫手这就是过热降频。CoreMark 官方定位不是稳定性测试工具它跑的时间短未必能触发热保护但在散热条件差的板子上完全有可能。想知道温度可以在 Linux 上读cat /sys/class/thermal/thermal_zone0/temp输出单位通常是千分之一摄氏度比如 65000 就是 65 摄氏度。配合sensors命令能看到更直观的温度曲线。我个人经验是如果测试过程中温度爬升超过二十摄氏度那么这次分数就要打个问号需要考虑加散热或者缩短单次测试时长。第三个是虚拟化环境。在云主机或者虚拟机里跑 CoreMark结果受 vCPU 超卖和宿主调度的强烈影响。同一台虚机在不同时间段跑分数可能差出百分之十几。这种情况下我的做法是加大迭代次数、连续多跑几轮取中位数同时留意虚拟化带来的 steal time可以通过top里的st列或者vmstat观察。如果 steal time 一直不低那这台虚机的分数只能当参考不能用来做精确选型。6. 把这个小工具用进真实工作流CoreMark 跑通了分数也稳定了接下来才是它真正发挥价值的地方。单独一个数字躺在那里没什么用把它接到你的实际决策链条里它才是一个称手的工具。我在下面几个场景里反复用到它效果都不错。6.1 服务器选型时和 CPU 天梯图交叉验证采购服务器时天梯图和厂商规格书只能作为初筛依据最终还是要拿实物或者同型号机器实测。我的流程是先用天梯图圈定几个候选型号然后每台机器上跑同一套 CoreMark 配置用CoreMark/MHz对比架构效率用多核总分对比理论峰值。这里要注意区分场景。如果你的业务是单线程敏感型那重点看单核分数和效率值如果业务可以并行扩展那重点看多核总吞吐和扩展曲线的斜率。两套指标指向不同的结论是很正常的关键在于先想清楚业务的瓶颈特征再决定看哪个数字。另外别忘了把温度和功耗一起记下来同样分数的两颗 CPU谁更省电谁散热压力小长期运营成本差别不小。6.2 把分数和温度、功耗放一起看能效单纯的性能分数没有考虑代价。我习惯在跑 CoreMark 的同时采一条温度曲线和一条功耗曲线最后算出一个粗略的能效对比。温度采集用前面说的 thermal zone 文件或者 sensors采样间隔设成 1 秒测试前先记录基线温度测试过程中记录峰值温度和稳态温度。功耗如果机器没有带功率计可以看带外管理口或者用支持功率读数的插座。判断能效时我一般看两个比值一是单位功耗能跑出多少分二是分数达到稳态时的温度比环境温度高多少。两颗 CPU 分数接近但其中一颗温度明显更高那就意味着它在同样散热条件下更容易触发降频长期高负载下的实际表现会更差。这类信息是规格书上看不出来的只能实测。6.3 验证工具链和内核调频策略是否生效这是我觉得 CoreMark 最有意思的用法。它足够敏感能把你做的配置改动反映到分数上。比如你换了交叉编译工具链的版本想确认优化能力有没有变化跑一遍 CoreMark 对比CoreMark/MHz就知道了。又比如你在调内核的调频策略从powersave切到performance跑一遍看看分数提升了多少这个提升幅度就是策略带来的实际收益。再比如你调了 CPU 智能核心调度相关的参数想知道对单线程性能有没有影响CoreMark 单线程跑法正好适合做这个对照。做这类对照实验的关键是控制变量。每次只改一个条件其他条件完全不变连续跑五遍取中位数这样得到的差异才归因清晰。同时改好几个参数然后看到分数变了你也不知道是谁的功劳。6.4 别把 CoreMark 当压力测试用最后得说一个我反复纠正的误区。经常有人问 CPU 压力测试怎么开然后就想到跑 CoreMark 跑一晚上。CoreMark 的设计初衷不是压力测试它的负载特征偏整数计算对缓存和内存子系统的压力有限长时间跑也未必能把所有核心的功耗拉满。想测稳定性得用能持续打满所有执行单元、同时压内存带宽的负载组合而且必须配合温度监控否则你压出问题来了都不知道是热还是电的原因。CoreMark 的正确定位是性能标尺不是压力源。把这两个角色混在一起用两边都做不好。我个人在实际操作中的体会是CoreMark 这类工具最大的价值不在于它给出的那个数字而在于它逼着你去把测试环境治理干净。锁频、绑核、清后台、控温度、多次采样这些动作做下来你对这台机器的脾气的了解程度会超过任何一份规格书。我通常会在做完这一整套之后顺手把 CPU 使用过高的排查思路也理一遍看看哪些后台服务在悄悄吃资源很多时候顺手就清掉了一批长期占着 CPU 又没什么用的东西。分数测准了机器也顺带收拾干净了这笔买卖不亏。