本文记录使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 构建 Coremark 的完整过程,包括环境、构建链路、关键日志、常见问题与解决方案、产物验证与重建方法,便于复现与运维。
📖 Coremark 简介
Coremark 是一个简单而标准的 CPU 性能基准测试程序,由 EEMBC(Embedded Microprocessor Benchmark Consortium)开发。它通过执行一系列常见的算法操作来评估处理器的性能,包括链表操作、矩阵操作、状态机操作等,是嵌入式系统和移动设备性能评估的重要工具。
🎯 Coremark 的作用与重要性
Coremark 是 CPU 性能基准测试的标准工具,提供了:
- 标准化测试:提供统一的性能评估标准,便于不同设备之间的性能对比
- 简单易用:测试程序简单,易于理解和部署
- 多线程支持:支持单线程和多线程测试,评估并行处理能力
- 可移植性:跨平台支持,可在不同架构上运行
- 性能指标:提供 Coremark 分数,用于量化 CPU 性能
🔧 Coremark 核心特性
1. 测试算法
Coremark 包含四种核心算法:
- 链表操作:测试内存访问和指针操作性能
- 矩阵操作:测试数学计算和内存访问模式
- 状态机操作:测试分支预测和条件判断性能
- CRC 计算:测试位操作和循环性能
2. 测试模式
- 单线程模式:评估单核性能
- 多线程模式:评估多核并行处理能力(支持 PThread)
3. 输出指标
- Coremark 分数:主要性能指标,分数越高性能越好
- 迭代次数:执行的测试迭代次数
- 编译器信息:使用的编译器和编译选项
- 平台信息:运行平台的相关信息
🚀 构建入口与环境
- 📝 执行命令 :
OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh - 🔧 入口脚本 :
create-hnp.sh- 检查必需的环境变量
OHOS_ARCH和OHOS_ABI - 导出
LC_CTYPE、TOOL_HOME、OHOS_SDK_HOME - 执行
make -C build-hnp
- 检查必需的环境变量
- 📦 顶层构建 :
build-hnp/MakefilePKGS变量定义需要构建的包列表(包含coremark)- 通过
check-pkgs机制自动检测PKGS变化并触发重新构建 - 自动合并
external-hnp目录下的外部 HNP 包 base.hnp依赖所有包的.stamp和外部 HNP 包- 总目标
all: copy,打包base.hnp并拷贝到entry/hnp/$(OHOS_ABI)
⚙️ Coremark 包的构建配置
- 📁 包目录 :
build-hnp/coremark/Makefile- 继承通用规则:
include ../utils/Makefrag - 源地址:
SOURCE_URL = https://github.com/eembc/coremark/archive/refs/heads/main.zip - 版本:最新 main 分支
- 继承通用规则:
- 🔧 构建策略 :
- 绕过上游 Makefile 的
make compile目标(避免CC变量扩展问题) - 直接调用交叉编译器编译源码
- 绕过上游 Makefile 的
- ⚙️ 编译参数 :
- 单线程版本 :
-O3- 最高优化级别-Imacos -Iposix -I.- 包含路径-DFLAGS_STR='"-O3 -static "'- 编译选项字符串(用于运行时显示)-DITERATIONS=0- 迭代次数(0 表示自动计算)-static- 静态链接
- 多线程版本(20 线程) :
-DMULTITHREAD=20- 线程数-DUSE_PTHREAD- 使用 PThread-pthread- PThread 链接选项- 其他参数与单线程版本相同
- 单线程版本 :
- 🔨 构建流程 :
- 下载源码包(GitHub main.zip)
- 解包并进入源码目录
- 编译单线程版本
coremark.exe - 复制到
sysroot/bin/coremark.exe - 编译多线程版本
coremark.exe - 复制到
sysroot/bin/coremark_p20c.exe
- 🔧 通用工具链与路径 :
build-hnp/utils/MakefragCC/CXX/LD/AR/RANLIB/...均指向 OHOS SDK 的 LLVM 工具链- 下载支持多镜像回退:
wget→curl,主镜像失败时自动尝试备用镜像
📋 关键日志与过程节点
- 📥 下载与解包 :
- 从 GitHub 下载
main.zip(最新源码) - 完成解包并进入
temp/coremark-main目录 - 下载规则支持多镜像回退:
wget→curl,自动尝试备用镜像
- 从 GitHub 下载
- ⚙️ 编译阶段 :
- 使用交叉编译器直接编译源码
- 单线程版本:编译生成
coremark.exe(825K) - 多线程版本:编译生成
coremark_p20c.exe(827K) - 两个版本都使用静态链接,便于部署
- 📦 安装与打包 :
- 复制到
sysroot/bin/ - 合并外部 HNP 包(如果存在)
- 最终执行
zip -r base.hnp sysroot并拷贝到entry/hnp/arm64-v8a/
- 复制到
✅ 产物验证
📦 检查打包文件
bash
ls build-hnp/base.hnp # 应存在
ls entry/hnp/arm64-v8a/*.hnp # 应包含 base.hnp 与 base-public.hnp
🔍 检查二进制文件
bash
# 检查 coremark 程序
ls -lh build-hnp/sysroot/bin/coremark*
file build-hnp/sysroot/bin/coremark.exe
file build-hnp/sysroot/bin/coremark_p20c.exe
# 验证文件是否存在
test -f build-hnp/sysroot/bin/coremark.exe && echo "coremark.exe: OK" || echo "coremark.exe: MISSING"
test -f build-hnp/sysroot/bin/coremark_p20c.exe && echo "coremark_p20c.exe: OK" || echo "coremark_p20c.exe: MISSING"
✅ 构建验证结果:
- ✅ 单线程版本已成功安装:
coremark.exe(825K) - ✅ 多线程版本已成功安装:
coremark_p20c.exe(827K) - ✅ 文件类型:ELF 64-bit LSB executable, ARM aarch64, statically linked
- ✅ 静态链接,无需外部依赖
💻 终端中执行的示例命令
🔧 Coremark 基本使用
1. 运行单线程测试
bash
# 运行单线程 Coremark 测试
./coremark.exe

输出示例:
2K performance run parameters for coremark.
CoreMark Size : 666
Total ticks : 10000
Total time (secs): 10.000000
Iterations/Sec : 1000.000000
Iterations : 10000
Compiler version : Clang 15.0.0
Compiler flags : -O3 -static
Memory location : Please put data memory location here
(e.g. code in flash, data on heap etc)
seedcrc : 0xe9f5
[0]crclist : 0xe714
[0]crcmatrix : 0x1fd7
[0]crcstate : 0x8e3a
[0]crcfinal : 0x33ff
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 1000.000000 / Clang 15.0.0 -O3 -static / Heap
2. 运行多线程测试
bash
# 运行 20 线程 Coremark 测试
./coremark_p20c.exe

输出示例:
2K performance run parameters for coremark.
CoreMark Size : 666
Total ticks : 10000
Total time (secs): 10.000000
Iterations/Sec : 20000.000000
Iterations : 200000
Compiler version : Clang 15.0.0
Compiler flags : -O3 -DMULTITHREAD=20 -DUSE_PTHREAD -pthread -static
Memory location : Please put data memory location here
(e.g. code in flash, data on heap etc)
seedcrc : 0xe9f5
[0]crclist : 0xe714
[0]crcmatrix : 0x1fd7
[0]crcstate : 0x8e3a
[0]crcfinal : 0x33ff
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 20000.000000 / Clang 15.0.0 -O3 -DMULTITHREAD=20 -DUSE_PTHREAD -pthread -static / Heap / 20:PThreads
3. 性能对比测试
bash
# 运行单线程测试并保存结果
./coremark.exe > single_thread_result.txt
# 运行多线程测试并保存结果
./coremark_p20c.exe > multi_thread_result.txt
# 比较结果
diff single_thread_result.txt multi_thread_result.txt

4. 批量测试脚本
bash
#!/bin/bash
# Coremark 批量测试脚本
echo "=== Coremark 性能测试 ==="
echo ""
echo "--- 单线程测试 ---"
./coremark.exe | grep "CoreMark 1.0"
echo ""
echo "--- 多线程测试(20 线程)---"
./coremark_p20c.exe | grep "CoreMark 1.0"
echo ""
echo "=== 测试完成 ==="
5. 提取 Coremark 分数
bash
# 提取单线程分数
./coremark.exe | grep "CoreMark 1.0" | awk '{print $3}'
# 提取多线程分数
./coremark_p20c.exe | grep "CoreMark 1.0" | awk '{print $3}'
# 保存分数到文件
echo "Single Thread: $(./coremark.exe | grep 'CoreMark 1.0' | awk '{print $3}')" > scores.txt
echo "Multi Thread (20): $(./coremark_p20c.exe | grep 'CoreMark 1.0' | awk '{print $3}')" >> scores.txt
cat scores.txt
6. 验证测试结果
bash
# 检查 CRC 校验值
./coremark.exe | grep -E "(crclist|crcmatrix|crcstate|crcfinal)"
# 验证测试是否通过
./coremark.exe | grep "Correct operation validated"
7. 性能监控
bash
# 使用 time 命令测量执行时间
time ./coremark.exe
# 使用 top 监控资源使用(在另一个终端)
# top -p $(pgrep coremark)
# 使用 perf 分析性能(如果可用)
# perf stat ./coremark.exe
🧪 功能验证脚本
bash
#!/bin/bash
# Coremark 工具验证脚本
COREMARK_BIN="build-hnp/sysroot/bin"
echo "=== Coremark 工具验证 ==="
# 检查单线程版本
if [ -f "$COREMARK_BIN/coremark.exe" ]; then
echo "✓ coremark.exe: 存在"
file "$COREMARK_BIN/coremark.exe"
echo "文件大小: $(ls -lh "$COREMARK_BIN/coremark.exe" | awk '{print $5}')"
else
echo "✗ coremark.exe: 缺失"
fi
echo ""
# 检查多线程版本
if [ -f "$COREMARK_BIN/coremark_p20c.exe" ]; then
echo "✓ coremark_p20c.exe: 存在"
file "$COREMARK_BIN/coremark_p20c.exe"
echo "文件大小: $(ls -lh "$COREMARK_BIN/coremark_p20c.exe" | awk '{print $5}')"
else
echo "✗ coremark_p20c.exe: 缺失"
fi
echo ""
echo "=== 测试运行(如果可执行)==="
echo "注意:这些是交叉编译的二进制文件,需要在目标设备上运行"
🐛 常见问题与解决方案
❌ 问题 1:上游 make compile 失败
- 🔍 症状 :使用上游 Makefile 的
make compile目标时失败,出现 "File name too long" 错误 - 🔎 原因 :上游 Makefile 的
CC变量在本环境下被异常扩展为整段PATH,导致命令行以 PATH 字符串开头 - ✅ 解决方法 :
- 绕过上游 Makefile,直接调用交叉编译器编译源码
- 在
build-hnp/coremark/Makefile中直接使用$(CC)编译 - 位置:
build-hnp/coremark/Makefile:8-15
❌ 问题 2:静态链接失败
- 🔍 症状:编译时出现静态链接错误,找不到静态库
- 🔎 原因:交叉工具链可能缺少静态库或静态库路径不正确
- ✅ 解决方法 :
- 确认交叉工具链具备静态库(
libc.a、libpthread.a等) - 如果静态链接受限,可以移除
-static选项,改为共享链接 - 在设备端提供所需的共享库(
libc.so、libpthread.so等) - 位置:
build-hnp/coremark/Makefile:9,13
- 确认交叉工具链具备静态库(
❌ 问题 3:SDK 环境变量未设置
-
🔍 症状 :直接调用重建目标时出现
CC未设置的错误 -
🔎 原因 :
CC变量依赖于OHOS_SDK_HOME环境变量 -
✅ 解决方法:
-
使用
create-hnp.sh脚本执行构建(自动设置环境变量) -
或手动设置环境变量:
bashOHOS_SDK_HOME=/path/to/sdk OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a make -C build-hnp rebuild-coremark -
位置:
create-hnp.sh
-
❌ 问题 4:FLAGS_STR 字符串转义问题
- 🔍 症状:运行时显示的编译选项不正确
- 🔎 原因 :
FLAGS_STR宏定义的字符串转义不正确 - ✅ 解决方法 :
- 确保
FLAGS_STR使用正确的引号和转义:-DFLAGS_STR='"-O3 -static "' - 注意单引号和双引号的嵌套使用
- 位置:
build-hnp/coremark/Makefile:9,13
- 确保
❌ 问题 5:多线程版本编译失败
- 🔍 症状:多线程版本编译时出现 PThread 相关错误
- 🔎 原因:缺少 PThread 库或链接选项不正确
- ✅ 解决方法 :
- 确保添加
-pthread链接选项 - 确保定义了
-DUSE_PTHREAD和-DMULTITHREAD=20 - 检查交叉工具链是否支持 PThread
- 位置:
build-hnp/coremark/Makefile:13
- 确保添加
🔄 重建与扩展
-
🔧 重建单包:
bashmake -C build-hnp rebuild-coremark # 触发子包重新编译并刷新 .stamp -
🧹 清理:
bashmake -C build-hnp clean # 清理 sysroot、所有 .stamp 和 PKGS_MARKER -
📦 扩展:Coremark 是 CPU 性能基准测试的标准工具,可以根据需要调整线程数或编译选项
-
🔄 自动重建机制:
- 修改
PKGS后,check-pkgs会自动检测变化并触发重新构建 - 新增外部 HNP 包到
external-hnp目录后,会自动合并到base.hnp
- 修改
💡 实践建议
- 🔧 性能测试:使用 Coremark 进行 CPU 性能基准测试,对比不同设备的性能
- 🛡️ 静态链接:使用静态链接可以避免依赖问题,便于在设备端部署
- 📦 多线程测试:使用多线程版本可以评估多核处理器的并行处理能力
- 🔗 结果记录:保存测试结果用于性能对比和分析
📝 结论与建议
- ✅ 本次已在 aarch64 环境下完成 Coremark 的交叉编译与打包,单线程和多线程版本已安装到
sysroot/bin并纳入 HNP 包。 - 💡 为保证构建稳定 :
- 固定可靠的上游镜像,避免下载阶段随机失败(已实现自动回退机制)
- 绕过上游 Makefile 的问题,直接调用交叉编译器,确保稳定构建
- 使用静态链接提升可移植性,适合在设备端快速开展性能基准测试
- 通过绕过上游构建目标并直接使用交叉编译器,稳定产出单线程与多线程版本
- 利用
check-pkgs机制自动检测包列表变化,无需手动清理
📚 以上为 Coremark 构建的深度解读与实践记录。