arduino-esp32 的 CoreMark 性能基准测试:移植实现、运行方式与 CI 结果采集详解

📅 发布时间:2026/9/14 3:21:36
arduino-esp32 的 CoreMark 性能基准测试:移植实现、运行方式与 CI 结果采集详解
arduino-esp32 的 CoreMark 性能基准测试移植实现、运行方式与 CI 结果采集详解【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本篇围绕 tests/performance/coremark/README.md 展开讲解 arduino-esp32 官方性能测试套件中的 CoreMark 基准它如何被移植到 Arduino 的 FreeRTOS 环境中运行、为什么必须绑定真实硬件、看门狗与时钟端口层是如何定制的以及 pytest 测试框架如何从串口输出中解析出 CoreMark 1.0 分数并生成 JSON 报告用于 CI 性能追踪。读完后你可以独立在目标板卡上运行该基准并理解从 sketch、端口层到结果解析脚本的完整调用链。一、套件定位CoreMark 1.0 分数与运行前提CoreMark 是嵌入式处理器行业的标准 CPU 基准用于产出一个单数值的性能得分CoreMark 1.0 iterations/sec。在 arduino-esp32 中该套件位于 tests/performance/coremark 目录是官方性能测试组的一部分——官方贡献文档将性能测试定义为用于检查核心和库的改动是否对性能产生重大影响的长时运行测试并点名 CoreMark 为其典型代表见 docs/en/contributing.rst 中 performance 小节。该套件的核心指标与测量范围如下继承自 README 的指标表指标单位平均 CoreMark 分数CoreMark 1.0 iterations/sec得分基于 3 次运行取平均对应 sketch 中的N_RUNS 3宏测量的是整体 CPU 性能工作负载覆盖三大算法链表处理list processing、矩阵运算matrix manipulation和状态机state machine。运行前提是明确的仅硬件策略硬件支持hardware-onlyWokwi 模拟器禁用wokwi: false——性能基准需要真实硬件才有意义QEMU禁用qemu: false。这一点可以直接在 ci.yml 中得到印证其全部内容就是两条平台开关platforms: qemu: false wokwi: false这与 docs/en/contributing.rst 中说明的运行脚本行为一致tests_run.sh的-WWokwi和-QQEMU开关对本套件不生效只有将板卡通过 USB 连接后走硬件串口才是有效路径。二、本地运行方式性能测试基于 pytest-embedded 框架驱动pytest.ini中注册了esp,arduino,wokwi,qemu四类 embedded services见 tests/pytest.ini。按 docs/en/contributing.rst Runtime Tests 章节的标准流程本地运行 coremark 套件分三步# 1. 安装测试依赖 pip install -U -r tests/requirements.txt # 2. 编译target 换成实际板型例如 esp32c3、esp32s3 ./.github/scripts/tests_build.sh -s coremark -t esp32c3 # 3. 连接板卡后运行 ./.github/scripts/tests_run.sh -s coremark -t esp32c3构建产物默认生成在~/.arduino/tests/target_chip/test_name/build.tmp运行后 pytest 会在测试目录下生成 XML 报告对于性能测试还会额外生成 JSON 结果文件下文第四节详述。需要说明的适用前提该流程要求 arduino-cli 环境可用且板卡处于可烧录状态由于wokwi: false/qemu: false本套件无法用模拟器得到有效结果。三、Sketch 层实现看门狗、多轮运行与自定义打印测试入口是 coremark.ino。它有三个为在 Arduino 环境里可靠跑完基准而做的设计1. 重配置任务看门狗避免基准运行期间被复位CoreMark 是 CPU 密集型任务单核长时间不响应 FreeRTOS 空闲钩子会触发默认的任务看门狗复位。sketch 在setup()中把任务看门狗超时改为 20 秒#define TWDT_TIMEOUT_S 20 ... esp_task_wdt_config_t config { .timeout_ms TWDT_TIMEOUT_S * 1000, .idle_core_mask 0, .trigger_panic false, }; esp_task_wdt_reconfigure(config);见 coremark.ino#L13-L36。README 中的 Notes 一节正是指这一行为。2. 固定 3 轮运行全部在 setup() 中完成#define N_RUNS 3 ... for (int i 0; i N_RUNS; i) { Serial.printf(Run %u\n, i); coremark_main(); Serial.flush(); }运行前还会打印Runs: %u与Cores: %u核心数取自CONFIG_SOC_CPU_CORES_NUM这两行是后续 pytest 解析的锚点loop()里直接vTaskDelete(NULL)因为基准是一次性任务见 coremark.ino#L22-L52。3. 实现 CoreMark 要求的两个可移植钩子extern C int coremark_main(void)C 写的 CoreMark 主体被重命名后声明供 C 的 Arduino 环境调用重命名 hack 见下文端口层ee_printfCoreMark 所有输出都走这个函数。sketch 提供了一个轻量实现逐字符解析格式串只支持 CoreMark 实际用到的s/f/d/u/x/c类型符并额外处理\n → \r\n全部路由到 ArduinoSerial115200 波特率见 coremark.ino#L55-L113Arduino_millisCoreMark 的计时函数barebones_clock()被桥接到 Arduino 的millis()见 core_portme.c#L49-L51。四、端口层core_portme.h/.c 中的关键配置CoreMark 的可移植性集中在core_portme.h与core_portme.c本套件的配置决定了测的是什么1main 重命名与运行模式core_portme.h#L5-L13#define main(ignore) coremark_main(void) #define PERFORMANCE_RUN 1 // 0 means auto-detect number of iterations for 10 second test #define ITERATIONS 0PERFORMANCE_RUN 1选中性能运行参数而不是验证运行参数ITERATIONS 0表示迭代次数自动确定core_main.c中会先跑 1 次迭代测时再按至少 1 秒为基准放大到约 10 秒的总运行时长core_main.c#L197-L213并强制不足 10 秒的结果视为无效core_main.c#L298-L301。这也是 20 秒看门狗超时的另一层原因——单轮基准本身就需要跑约 10 秒以上。2多线程按 SoC 核数启动 FreeRTOS 任务core_portme.h#L156-L162#define MULTITHREAD CONFIG_SOC_CPU_CORES_NUM #define PARALLEL_METHOD FreeRTOS即上下文数量等于该芯片的 CPU 核数如双核 SoC 为 2、单核 C6 类为 1并行方法标注为 FreeRTOS。真正的并行启动在 core_portme.c#L145-L166core_start_parallel()用xTaskCreatePinnedToCore()创建名为CoreMarkTask的任务栈 10000 字、优先级 20并通过next_core (next_core 1) % MULTITHREAD依次把各任务钉在轮流分配的核上core_stop_parallel()则自旋等待任务进入eDeleted状态后才继续。因此最终分数反映的是整机多核性能输出中也会有Parallel FreeRTOS : N一行佐证。3数据类型、计时与内存策略HAS_FLOAT 1有浮点、HAS_PRINTF 0打印由自定义ee_printf提供、MEM_STACK数据块放栈上MEM_LOCATION报告为STACKCORE_TICKS为ee_u32CLOCKS_PER_SEC 1000.0、TIMER_RES_DIVIDER 1即计时精度为毫秒core_portme.c#L58-L65性能模式种子值在 core_portme.c#L32-L36 固定为seed10x0, seed20x0, seed30x66。4端口自检portable_init()会检查ee_ptr_int是否为指针宽度、ee_u32是否为 4 字节不满足即打印错误退出core_portme.c#L118-L129这是 CoreMark 官方规定的移植正确性检查。五、三大算法与2K 性能运行参数的确定CoreMark 由三个算法构成在 coremark.h#L83-L88 中以位掩码定义#define ID_LIST (10) #define ID_MATRIX (11) #define ID_STATE (12) #define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE) #define NUM_ALGORITHMS 3分别对应 core_list_join.c链表创建、复制、搜索、删除、core_matrix.c矩阵乘加与 core_state.c数字解析状态机工具函数在 core_util.c。数据规模由 coremark.h#L26-L28 的TOTAL_DATA_SIZE 2*10002000 字节决定主流程会把总量平分给 3 个算法即每个算法 666 字节。结合种子 (0, 0, 0x66)core_main.c会算出 seedcrc 为0xe9f5命中已知用例known_id3打印 2K performance run parameters for coremark.core_main.c#L239-L263。有两点值得注意最终分数行的打印条件是known_id3只有命中 2K 性能参数组且 CRC 验证通过时才会输出CoreMark 1.0 : 分数 / 编译器版本 / ...core_main.c#L323-L338——这正是测试脚本要抓的那一行CRC 正确性校验三个算法各自有期望 CRC 表list_known_crc/matrix_known_crc/state_known_crccore_main.c#L35-L37任一不匹配都会计为错误保证报告出来的分数来自一次行为正确的运行。六、pytest 采集链路从串口正则到 JSON 报告README Notes 提到结果由 pytest harness 写入 JSON 报告文件用于 CI 性能追踪具体实现是 test_coremark.py握手dut.expect(rRuns: (\d))和dut.expect(rCores: (\d))分别解析出运行轮数与核数均断言大于 0逐轮取分循环runs次先expect(rRun (\d))校验轮次序号递增再expect(rCoreMark 1.0 : (\d)\.(\d))提取该轮分数断言0 score 10000超出即视为不可能分数累加后求平均并保留两位小数写 JSON 报告结果按规范格式落盘test_coremark.py#L42-L62results { test_name: coremark, runs: runs, settings: cores{}.format(cores), metrics: [{name: avg_score, value: avg_score}], } # 写入 tests/performance/coremark/target/result_coremarkN.json报告文件写入测试目录下的target子目录如tests/performance/coremark/esp32c3/result_coremark0.json若同名文件已存在则递增索引后缀。该 JSON 的metrics字段即 CI 侧做跨版本性能趋势对比的输入与官方文档中性能测试可在同目录检查生成的 JSON 文件的说明一致。七、关键配置速查配置项取值位置作用N_RUNS3coremark.ino#L17分数取 3 轮平均TWDT_TIMEOUT_S20 scoremark.ino#L14防止基准运行期间看门狗复位PERFORMANCE_RUN1core_portme.h#L10使用性能运行种子 (0, 0, 0x66)ITERATIONS0core_portme.h#L13自动确定迭代次数单轮约 10 秒MULTITHREADCONFIG_SOC_CPU_CORES_NUMcore_portme.h#L157每核一个 FreeRTOS 任务并行MEM_METHODMEM_STACKcore_portme.h#L137-L139数据块分配在栈上TOTAL_DATA_SIZE2000coremark.h#L27三算法共 2000 字节2K 性能组串口速率115200coremark.ino#L23结果输出通道模拟器平台qemu: false/wokwi: falseci.yml仅真实硬件有效八、小结coremark 套件的价值在于把一次完整、可审计的 CPU 性能测量做成了可重复流程sketch 层保证长任务不被看门狗打断、端口层按芯片核数并行并自动校准时长、CoreMark 官方 CRC 机制保证运行正确、pytest 脚本把分数标准化为可入库的 JSON 指标。如果你要评估某次核心改动对 arduino-esp32 各芯片ESP32 / C3 / S3 / C6 等CPU 性能的影响直接运行该套件并对比avg_score即为官方推荐的度量方式。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考