1. CoreMark到底测的是什么不测什么很多人第一次接触 coremark是因为手里有一块开发板、一台新装的服务器或者一批要选型的工控机想找个权威数字来判断这颗 CPU 到底行不行。跑完拿到一个类似12345.67 iterations/sec的输出心里踏实了但紧接着问题就来了这个数字跟另一台机器上的 20000 谁更强跟编译器优化开关有没有关系为什么同一颗芯片换块板子跑出来差 30%要回答这些问题得先弄清楚 coremark 的设计定位。它由 EEMBC 组织推出目标是做一个小而专的处理器核心性能基准替代当年被各家厂商玩坏了的 Dhrystone。它的核心逻辑是用尽可能少的代码量覆盖四类典型运算然后看处理器每秒能完整跑完多少次这个固定工作负载。这四类运算是链表操作linked list processing、矩阵操作matrix manipulation、状态机state machine、CRC 校验cyclic redundancy check。之所以选这四样是因为它们分别对应了嵌入式与通用计算里最常见的几种负载特征——指针跳转带来的访存模式、连续数据的批量计算、分支预测密集的条件跳转、以及位运算与查表混合的逻辑处理。这套组合拳的意图很明确不偏向任何一家厂商的架构特点同时又能把流水线、分支预测、缓存、内存带宽这些关键部件都压一压。注意一个常见误解coremark 的分数高不代表整机性能好。它测的是处理器核心在特定工作负载下的吞吐能力跟你跑数据库、跑 Web 服务、跑视频转码的实际体验之间隔着编译器、内存子系统、操作系统调度、IO 等一大堆变量。具体来说coremark 不测这些东西coremark 覆盖范围coremark 不覆盖范围整数运算、位运算、分支跳转浮点运算能力一级缓存命中下的指令吞吐多核并行扩展性链表指针的访存延迟敏感性内存带宽与容量CRC 查表带来的访存局部性加密指令集、SIMD 加速单线程主循环执行速度IO、网络、外设性能为什么它坚持单线程因为 EEMBC 希望 coremark 测量的是一个处理器核心的能力而不是整机能力。这样在不同核数、不同拓扑的芯片之间至少有一个相对可比的基准点。但这也带来了实战中的一个典型困扰你在一台 64 核服务器上跑 coremark它只用了 1 个核剩下的 63 个核在围观你拿到的分数反映的是单核性能不是这颗 CPU 的全部实力。我第一次在服务器上跑它的时候看到 CPU 占用一直是 100% 除以 64还以为是工具没跑起来查了半天才发现这就是它的设计逻辑。所以如果你要评估多核场景得用它的多实例模式后面会讲-c参数或者自己开多个进程手动跑。再补充一个容易忽略的点coremark 的输入是固定在代码里的工作负载大小、迭代次数都是编译期决定的常量。这意味着它的行为是高度可复现的——同一份二进制在同一台机器上反复跑结果应该几乎一致。这也是它比很多跑一次一个数的基准工具更可靠的地方。但反过来固定负载也意味着它对缓存大小、内存延迟的区分度有限如果你关心的是大数据集下的性能表现coremark 给不了太多信息。2. 源码获取与交叉编译的实操细节coremark 的源码托管在 GitHub 上的 eembc/coremark 仓库结构非常干净没有任何构建系统依赖不需要 CMake、不需要 autotools核心就是几个.c文件加一个 Makefile。这份简陋恰恰是它的优点你可以把它扔进任何裸机工程、RTOS 工程、甚至只有交叉编译器的环境里都能编出来。2.1 目录结构与关键文件拉下来之后你会看到这样的布局coremark/ ├── core_list_join.c 链表操作测试 ├── core_main.c 主入口与结果输出 ├── core_matrix.c 矩阵操作测试 ├── core_state.c 状态机测试 ├── core_util.c 计时与工具函数 ├── coremark.h 公共头文件与参数定义 ├── core_portme.c 平台移植层需要你自己改 ├── core_portme.h 平台移植头文件 └── Makefile 构建脚本其中core_portme.c和core_portme.h是最需要你动手的地方。这两个文件定义了这个平台的时间怎么读种子从哪来结果怎么打印数据类型用什么这些与平台强相关的行为。默认版本用的是 POSIX 的clock()或gettimeofday()如果你要移植到裸机就得把这些换成你自己的定时器读数。2.2 关键编译宏coremark 的行为几乎全靠编译宏控制这几个是必须搞明白的ITERATIONS每个测试的总迭代次数。默认是自动计算出一个至少运行 10 秒的值但你也可以手动指定。CLOCKS_PER_SEC你平台的时钟频率直接决定最终分数的大小。填错了分数就全错。MULTITHREAD是否启用多实例模式。USE_CLOCK/USE_CLOCK_GETTIME计时方式的选择。TOTAL_DATA_SIZE数据集大小默认 2000 字节。调大它可以压缓存和内存。CLOCKS_PER_SEC这个宏我要重点说。它不是你 CPU 的主频而是你计时函数每秒钟返回多少个计数单位。在 POSIX 系统上如果用clock()CLOCKS_PER_SEC通常是 1000000。如果你把它误填成 CPU 主频比如 2400000000最后算出来的 coremark 分数会小得离谱你还会以为自己的芯片性能有问题。2.3 本地编译跑通在 x86 Linux 上最简单的方式就是直接用官方 Makefilegit clone https://github.com/eembc/coremark.git cd coremark make默认会编出coremark.exe直接运行./coremark.exe输出大概长这样2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 13258436 Total time (secs): 13.258436 Iterations/Sec : 7542.37 Iterations : 100000 Compiler version : GCC10.2.0 Compiler flags : -O2 -DPERFORMANCE_RUN1 ... Memory location : Static seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x4983 Correct operation validated.看到最后的Correct operation validated.才算真正跑对了。如果这里报 CRC 校验失败说明编译过程或平台移植层出了问题得到的分数没有任何意义。2.4 交叉编译到目标板如果你要往 ARM、RISC-V、MIPS 这类目标板上跑流程是这样的make PORT_DIR你的平台目录 \ CCarm-linux-gnueabihf-gcc \ EXEcoremark_arm更常见的是自己写一份 port 目录把core_portme.c和core_portme.h的定制版本放进去。定制时最核心的三件事计时函数要能给出微秒级甚至更高精度的读数精度不够会直接放大测量误差。随机种子固定种子才能保证结果可复现别用time(NULL)这种每次都变的值。结果打印裸机上没有 printf你得把结果通过串口吐出来或者存到内存里再由调试器读取。我踩过的一个坑在一块 Cortex-M7 板子上一开始用了 SysTick 做计时但 SysTick 分辨率只有 1ms而 coremark 总运行时间算出来是 8 秒多全部读数都是整数毫秒最后算出的分数在两次运行间能差好几十。后来换成 DWT 的 cycle counter用 CPU 周期数当时间单位精度上去了重复跑十次的结果波动降到了千分之二以内。提示交叉编译时务必确认-mcpu、-mfpu、-mfloat-abi这些架构参数和目标芯片完全匹配。coremark 全是整数运算浮点 ABI 填错了虽然能编出来也能跑但工具链可能会插入额外的软件浮点调用白白拖慢分数。3. 编译选项如何左右分数一场需要控制的实验coremark 最容易被玩坏的地方就是它的分数对编译选项极其敏感。同一颗 CPU-O0和-O3之间差三五倍是家常便饭加上-funroll-loops、-flto、-marchnative这些开关还能再往上蹿一截。这就带来一个严肃的问题你报出来的分数到底代表芯片性能还是代表你编译器的本事EEMBC 给出的官方规则很明确报告分数时必须同时说明编译器版本和完整编译选项。这是基本要求但在实际工作中很多人的测试报告里只有一行coremark 分数25000别的什么都没有这样的数据基本没法用于横向对比。3.1 官方推荐的基准编译配置EEMBC 定义了两种跑法Performance Run允许使用你平台支持的最高优化等级目标是测出这颗 CPU 的峰值能力。定义宏PERFORMANCE_RUN1。Validation Run使用较保守的选项更强调可移植性和结果一致性。定义宏VALIDATION_RUN1。官方 Makefile 默认走的是 Performance Run。标准做法是make PORT_DIRlinux \ CCgcc \ CFLAGS-O2 -DPERFORMANCE_RUN1 -DMULTITHREAD1 -DUSE_CLOCK_GETTIME注意这里用的是-O2而不是-O3。EEMBC 的建议配置就是-O2原因是-O3在某些编译器上会做激进的循环变换把 coremark 的部分核心循环优化到失去代表性反而违背基准测试的初衷。3.2 实测中不同选项的差异我在一台 Xeon Silver 4210 上做过一组对照固定迭代次数隔离开其他进程每种配置跑五次取中位数编译配置Iterations/Sec中位数相对 -O0 提升-O04120基准-O198702.40x-O2113402.75x-O2 -funroll-loops124803.03x-O3128103.11x-O3 -marchnative146203.55x-O3 -flto -marchnative151103.67x从这张表能看到两件事。第一-O0到-O1是断崖式的差距所以任何用-O0报出来的分数都不值得参考。第二-O2到-O3的收益大概 13%而-marchnative又额外贡献了 14%——这个提升主要来自编译器开始使用目标 CPU 支持的更宽指令和更好的指令调度。这组数据也解释了为什么很多厂商宣传的 coremark 分数看起来很高他们大概率用了-O3加平台特定的 intrinsic 优化甚至直接改写了部分源文件这是 EEMBC 明令禁止的但确实有人这么干。注意-marchnative的结果只能用于自用对比不能作为对外报告的分数。因为它让同一个二进制无法在其他机器上复现违背了基准测试的可复现原则。如果你要横向比较不同机器所有机器必须用完全相同的编译配置包括-march。3.3 让测量结果稳定的实操要点编译选项只是变量之一。要让每次跑出来的数字真正可比还得控制这些关闭 CPU 调频。Linux 上把 governor 切成performance否则 CPU 会在低频和高频之间来回跳分数随负载变化。绑定 CPU 核心。用taskset -c 3 ./coremark.exe把进程钉在一个核上避免调度器把它在不同核心间搬来搬去。清空干扰进程。跑测试时别开着编译、视频转码、浏览器。有条件的话上nice -n -20。温度与散热。长时间跑 coremark 会让 CPU 升温如果散热不好触发降频后面的迭代分数会掉。我在一台小机箱上实测过连续跑三次第三次比第一次低了 8%。这四条里前两条是默认动作第三条和第四条经常被忽略但它们对结果的影响都是可以超过 5% 的。3.4 关于改源码提升分数的边界EEMBC 的规则里有一条很重要的约束coremark 的核心算法文件不允许修改。你只能改core_portme.c、core_portme.h以及为了适配平台所必需的最小改动。链表、矩阵、状态机、CRC 这四个测试的工作量必须保持一致。为什么这条规则重要因为 coremark 的比较价值完全建立在大家都在跑同一份负载上。一旦有人为了好看去改算法整张对比表就废了。现实中确实存在这种情况所以看到某些报得特别高的 coremark 分数时多留个心眼问清楚源码有没有改动、编译选项是什么。4. 多核与多实例MULTITHREAD 模式的正确打开方式单线程跑完 coremark拿到的是一个核的成绩。但如果你手上是服务器或者多核嵌入式 SoC单核分数显然不够用。coremark 提供了多实例支持通过MULTITHREAD宏开启允许同时启动多个相同的负载实例每个实例跑在一个线程或进程上。4.1 多实例模式的机制开启方式make MULTITHREAD1原理是coremark 会启动 N 个副本N 由宏MULTITHREAD的值决定比如-DMULTITHREAD8就是 8 个并行实例每个实例在独立的线程里跑完整的 coremark 负载。最后它报告的是每个实例的独立分数以及一个总分数。关键点在于它报告的总分不是简单的 单核分数乘以核数而是所有实例各自跑出来的结果之和。所以这个总分其实反映的是多核并行时的整体吞吐。4.2 多实例分数背后的信息多核 coremark 分数和单核分数之间的比例能说明很多东西。举个例子假设某 CPU单核分数120008 实例总分82000总分除以单核分数约等于 6.83而理论核数是 8。这就说明存在约 15% 的多核效率损失。原因可能是共享缓存争用、内存带宽瓶颈、频率在多核负载下被拉低、超线程资源竞争。反过来如果 8 实例总分接近 960008 倍单核那就说明这颗 CPU 的多核扩展性非常好缓存和内存子系统足够宽每个核都能跑满。这个扩展效率指标比单看总分更有价值。我在选型工控机主板时就靠它筛掉过一款标称 8 核但多核扩展效率只有 65% 的芯片——那颗芯片在单核场景下表现还行但一上并发就原形毕露明显是共享 L3 或内存控制器拖后腿。4.3 多实例模式的实操坑多实例跑法有几个容易翻车的地方线程数超过物理核数。如果你的-DMULTITHREAD设成了 16而机器只有 8 个物理核超线程会让两个逻辑核共享一个物理核的执行单元分数会明显偏低而且波动很大。跑之前先用lscpu确认物理核数和逻辑核数。绑核问题。多实例模式下你想手动绑核会很麻烦。比较实际的做法是不绑核让操作系统自己调度但前提是系统里没有别的重负载。计时精度要求更高。多核同时跑总时间可能比单核短很多如果计时精度不够误差占比会变大。建议至少用微秒级计时。结果解读要看清楚。coremark 的输出里会分别列出每个实例的迭代次数和总分别把某个实例的数字当成总分。4.4 用脚本自己做多核扫描官方多实例模式虽然方便但灵活性有限。我更常用的做法是写个脚本手动启动 N 个单实例进程分别记录结果这样能精确控制绑核也能画出一条核数-总分曲线#!/bin/bash # 依次测试 1 到 8 个并行实例 for n in 1 2 4 8; do start$(date %s.%N) for i in $(seq 1 $n); do taskset -c $i ./coremark.exe /tmp/cm_$i.log 21 done wait end$(date %s.%N) total$(grep Iterations/Sec /tmp/cm_*.log | awk {s$3} END {print s}) echo 实例数: $n 总分: $total 总耗时: $(echo $end - $start | bc)秒 done跑出来的曲线如果在大核数处开始变平那基本就是撞到了内存带宽或缓存容量的天花板。这条曲线对评估一颗 CPU适合跑几路并发很有帮助。5. 拿到分数之后怎么解读怎么对比怎么不被忽悠coremark 分数本身只是一个数字它的价值在于对比。但对比有讲究不是拿两个数字相除就完事了。5.1 分数与主频的关系因为 coremark 的核心工作负载是纯整数运算加访存它和主频的相关性非常高。很多场景下coremark 分数和主频近似线性。这就引出一个常用的判断指标CoreMark/MHz。计算方式很简单CoreMark/MHz Iterations/Sec ÷ CPU主频(MHz)比如一颗 1.2GHz 的芯片跑出 4200 分那 CoreMark/MHz 就是 3.5。这个指标衡量的是微架构的每时钟周期效率跟主频脱钩所以特别适合比较不同频率的芯片。不同微架构的典型 CoreMark/MHz 差距挺大。老的顺序执行核心可能只有 1.5 到 2.5现代的乱序执行高性能核心可以到 5 到 8一些专门优化过的嵌入式核心能到 3 到 4。这个数字的意义在于如果你在选型两颗芯片一个 1GHz 跑 4000 分、一个 2GHz 跑 5000 分前者虽然总分低,但架构效率更高在功耗受限场景下可能反而是更好的选择。提示算 CoreMark/MHz 时要用芯片的实际运行频率不是标称最高频率。很多芯片在跑满负载时达不到标称频率用标称值算出来的效率会虚高。5.2 跨平台对比的几条红线想把两台机器的 coremark 分数放在一起比下面这几条必须满足对比条件必须一致说明编译器厂商与版本GCC 10 与 GCC 12 的结果不可直接比优化等级完全相同-O2 与 -O3 混比没有意义架构参数-march/-mcpu至少都关掉或都用相同值coremark 版本相同提交不同版本负载有细微差别运行模式Performance/Validation 一致两者负载规模不同线程数相同单线程与多实例不可混比只要有一条不满足对比结果就掺了杂质。现实中很多人拿厂商宣传页上的分数和自己编译的分数直接比这两者之间通常同时踩了好几条红线。5.3 为什么厂商数据常常偏高厂商宣传的 coremark 分数普遍偏高原因通常是这几个叠加用了-O3或更高优化甚至特定编译器的激进选项。加了平台特定的优化比如针对自家向量指令改写部分循环。在实验室环境跑散热、供电、频率都是最优状态。用的是大版本刚出时针对新架构优化的编译器。极少数情况有对源文件的未授权改动。所以看到某芯片 coremark 跑出 XXXX 分的宣传正确的态度是可以作为参考上限但不能作为实际能力预期。你自己复现出来的分数如果只有宣传值的 60% 到 70%那往往是正常的差异主要来自编译选项和环境。5.4 我在实际选型中的用法我个人在评估芯片时coremark 从来不是唯一指标但它是第一道筛子。流程一般是这样的先看官方 coremark 分数和 CoreMark/MHz如果效率明显低于同代架构的正常水平比如一颗 2GHz 的现代核心 CoreMark/MHz 只有 2.0那要么是数据有问题要么是这颗芯片的架构确实偏弱先放一边。通过的芯片再进入第二轮用统一编译选项自己复现一遍确认分数大致对得上。第三轮才上实际业务负载。coremark 的价值在于它快、简单、可复现适合做大范围初筛。但它毕竟只是一个整数基准最终的选型决策还得回到你的真实场景如果业务是加解密密集那要看加密指令集如果是向量计算密集要看 SIMD 性能如果是内存密集coremark 的参考价值就更有限了。6. 移植到裸机与嵌入式平台的几个关键动作在 Linux 上跑 coremark 相对容易真正考验功力的是把它搬到没有操作系统、没有标准库、只有交叉工具链的裸机环境。这一节讲的是这类场景下的实际做法也是 coremark 作为处理器核心基准最原本的用法。6.1 最小移植需要实现的接口裸机移植的本质是让 coremark 能在你的平台上启动、计时、结束。需要自己实现或适配的部分集中在core_portme.c/core_portme.hportable_init()平台初始化通常用来配置时钟、串口、看门狗。start_time()/stop_time()/get_time()三个计时相关函数。start_time记录起始时间戳stop_time记录结束get_time返回差值。portable_malloc()/portable_free()内存分配函数。coremark 默认用malloc裸机上要换成你自己的分配器或静态缓冲区。ee_printf()输出函数替代 printf。串口是最常用的实现。这里最容易出问题的是计时精度和内存分配。计时精度不够会让分数可信度大打折扣内存分配如果用固定池得确保池子够大coremark 的链表测试会动态申请不少节点。6.2 计时方案的选择嵌入式平台常见的计时源有几种精度和成本不同计时源典型分辨率适用场景注意事项SysTick1ms 或更粗粗略测量分辨率太粗不适合 coremarkDWT Cycle Counter1 个 CPU 周期Cortex-M3 及以上需要使能调试单元精度最高通用定时器微秒级大多数 MCU注意溢出与分频配置RISC-V mcycle1 个 CPU 周期RISC-V 平台需确认 CSRs 可访问外部高精度计时器纳秒级精密测量成本较高我的建议是只要能拿到 cycle counter就优先用它。用 CPU 周期数当时间单位有两个好处一是精度天然最高二是它和 CPU 主频直接挂钩只要你知道实际主频就能准确折算成秒。RISC-V 上用mcycle/mcycleh组合读 64 位周期数Cortex-M 上用 DWT 的CYCCNT寄存器都是很成熟的做法。注意读 cycle counter 时要处理溢出。32 位的周期计数器在 200MHz 主频下大约 21 秒就会绕回一圈如果你的 coremark 总运行时间超过这个数必须做溢出处理或者用 64 位计数器。6.3 打印输出的处理裸机上没有终端ee_printf一般实现成把字符逐个写进串口数据寄存器。这里有两个细节一是串口波特率别太低。coremark 的输出不算多但迭代过程中有些平台会周期性打印进度波特率太低会显著拉长总时间影响结果。115200 是起步有条件上更高。二是确保输出不阻塞核心计算。如果你的ee_printf是忙等发送而 coremark 又恰好在计算过程中调用它默认不会频繁调用但在某些配置下会那输出时间会被计入总分导致分数偏低。稳妥做法是用 DMA 或缓冲让发送和计算解耦。6.4 一次真实的移植过程我在一块 RISC-V 的 FPGA 软核上移植过 coremark。这颗软核主频只有 50MHz没有 DWT但有标准的mcycleCSR。移植步骤大概是先把core_portme.c里的start_time/stop_time改成读mcycle用 32 位版本因为单次运行时间只有几秒不会溢出。然后实现一个简单的ee_printf直接往 UART 的发送寄存器写字符。内存分配用了最朴素的 bump allocator从一块 64KB 的静态数组里往上分。第一次跑出来分数是 1.2我以为是哪里算错了——50MHz 的软核按说 CoreMark/MHz 应该在 2 左右分数该是 100 才对。查了一圈发现是CLOCKS_PER_SEC填错了我把它填成了mcycle的计数频率也就是 50MHz但 coremark 期待的是每秒多少 ticks——其实这个填法是对的。真正的问题是ITERATIONS没设对默认的自动计算在这颗慢核上估出了一个偏小的值我手动设成 10000 之后分数就回到了 1.85 左右符合这颗软核的架构预期。这次经历让我记住了两件事慢核上一定要手动确认迭代次数以及第一次跑出来的离谱数字先怀疑配置再怀疑硬件。7. 把 coremark 用对几个容易被忽略的坑与心得coremark 工具本身很简单但用对不容易。这一节把我这些年踩过的、见过的坑集中说一下希望能帮你少走弯路。7.1 迭代次数与运行时间的关系官方 Makefile 有一个自动迭代次数估算的机制它会先用一个较小的迭代数预估单次耗时再推算出让总运行时间超过 10 秒的迭代数。这个机制在正常平台上很好用但在两种情况下会失灵一是极快的平台上预估过程本身的开销可能超过实际计算导致估算偏差。二是极慢的平台上预估的迭代数可能小到几轮统计意义不足。我的做法是不管自动估算给多少都手动设置-DITERATIONS让它总运行时间落在 10 到 60 秒之间。太短了统计噪声大太长了没有额外收益还费时间。10 秒是 EEMBC 推荐的下限实测中 20 到 30 秒的稳定性已经足够好。7.2 顺序执行与乱序执行的分数特征如果你在多颗芯片上跑过 coremark可能会注意到一个现象顺序执行in-order核心的 coremark 分数对代码布局比较敏感而乱序执行out-of-order核心相对稳定。原因是顺序核心遇到访存延迟时只能干等而乱序核心可以用其他指令填充这个空档。这个现象对调试有指导意义。如果你在一颗顺序核心上跑出来的分数波动很大比如超过 10%往往不是计时问题而是指令/数据在缓存中的布局在起作用。这时候可以尝试调整链接脚本把 coremark 的代码段放到对齐更好的位置看波动是否收敛。7.3 缓存配置对 TDS 的敏感性前面提过TOTAL_DATA_SIZETDS这个宏默认 2000 字节。它决定了链表和矩阵测试的数据集大小。这个参数在评估缓存性能时非常有用TDS 远小于 L1 缓存数据集全在 L1分数反映的是纯粹的执行效率。TDS 略大于 L1、小于 L2能测出 L1 缺失的代价。TDS 大于 L2开始压内存带宽。我在评估一颗芯片时会跑三组 TDS2000、16384、262144画出分数下降曲线。下降平缓说明缓存体系设计得好断崖式下降则说明某一级缓存容量或关联度不足。这个测试比单看默认分数信息量大得多。7.4 CRC 校验失败意味着什么Correct operation validated.这一行是 coremark 的灵魂。如果它变成了 CRC 校验失败说明计算结果和预期不符分数完全不可信。常见原因现象可能原因排查方向crclist 错误指针操作或内存分配问题检查 portable_malloc 实现crcmatrix 错误数据类型宽度不对检查 ee_u16/ee_s32 等类型定义crcstate 错误编译器优化导致行为异常降到 -O0 复现再看优化回归crcfinal 错误结果收集逻辑有问题检查结果变量类型与打印类型定义出错是最隐蔽的一种。coremark 要求ee_u16是 16 位、ee_s32是 32 位如果你的平台把这些定义成了错误的宽度计算结果会错但编译不报错只有 CRC 校验能发现。7.5 别把它当成唯一的性能指标最后说个观念问题。coremark 因为简单、可复现、门槛低被用得很广但它毕竟是一个单线程整数基准。它在历史上的高知名度某种程度上让一些人对它的能力产生了过度期待。实际工作中coremark 适合做这几件事快速评估单核架构效率、做同架构不同频率的横向比较、作为芯片选型的第一道初筛、验证工具链和平台移植是否正常。它不适合做这些事评估多核并发能力、评估特定业务负载性能、评估浮点或向量计算能力、作为整机性能的唯一依据。把这些边界划清楚coremark 就是一个非常好用的工具划不清楚就容易拿着一个数字得出错误的结论。我自己的习惯是coremark 永远和实际业务负载测试搭配使用前者告诉我这颗芯片的基础素质大概在哪一档后者告诉我它能不能扛住我的活。两个都看判断才靠谱。