coremark¶
CoreMark is a CPU benchmark provided by EEMBC. apps/coremark/ uses CMake FetchContent to automatically fetch the upstream source and builds for both Big/Little cores with no custom source files — only a CMakeLists.txt.
Prerequisites¶
- K230 SDK must be built (toolchain extracted)
- SDK placed at
k230_sdk/in the repository root - Host OS: x86_64 Linux
- CMake 3.16 or later
- Internet connection (only for the initial FetchContent download)
Building the SDK
For K230 SDK build instructions, see SDK Build.
Design¶
Why the posix/ port¶
The upstream CoreMark posix/ port operates with the following settings:
USE_CLOCK=0,HAS_TIME_H=1→ usesclock_gettime(CLOCK_REALTIME)for timingSEED_METHOD=SEED_ARG→ seed configurable via command-line arguments (auto-detect when no arguments)MEM_METHOD=MEM_MALLOC→ standard heap allocation
This is the same approach used by the K230 SDK's CoreMark implementation (k230_sdk/src/big/unittest/testcases/coremark/). It works with both musl (RT-Smart) and glibc (Linux).
Why no custom source files are needed¶
CORETIMETYPEis only used withincore_portme.c(core_main.cusesCORE_TICKS=clock_t)- The posix port's
core_portme.cis nearly identical to the K230 SDK implementation - Configuration differences (ITERATIONS, etc.) can be handled via runtime arguments or CMake
-D - Only
FLAGS_STRneeds to be defined from CMake (upstream Makefile also passes it via-D)
-O2 override¶
The RT-Smart toolchain sets -O0, which is meaningless for benchmarking. Since GCC uses the last -O flag, appending -O2 after the toolchain's -O0 effectively enables -O2. The Linux toolchain already uses -O2, so this has no effect there.
Timing accuracy¶
RT-Smart's clock_gettime(CLOCK_REALTIME) is tick-based (RT_TICK_PER_SECOND=1000) with a resolution of 1ms. Since CoreMark runs for approximately 10 seconds, the measurement error at 1ms resolution is about 0.01% — more than sufficient.
-lrt is not needed — both musl and modern glibc include clock_gettime in libc.
CMakeLists.txt¶
apps/coremark/CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(coremark C)
# --- Fetch upstream CoreMark source ---
include(FetchContent)
FetchContent_Declare(
coremark_src
GIT_REPOSITORY https://github.com/eembc/coremark.git
GIT_TAG main
GIT_SHALLOW TRUE
)
FetchContent_GetProperties(coremark_src)
if(NOT coremark_src_POPULATED)
FetchContent_Populate(coremark_src)
endif()
# --- Build the CoreMark benchmark ---
add_executable(coremark
${coremark_src_SOURCE_DIR}/core_list_join.c
${coremark_src_SOURCE_DIR}/core_main.c
${coremark_src_SOURCE_DIR}/core_matrix.c
${coremark_src_SOURCE_DIR}/core_state.c
${coremark_src_SOURCE_DIR}/core_util.c
${coremark_src_SOURCE_DIR}/posix/core_portme.c
)
target_include_directories(coremark PRIVATE
${coremark_src_SOURCE_DIR}
${coremark_src_SOURCE_DIR}/posix
)
# Benchmark-meaningful optimization
# (-O2 overrides RT-Smart toolchain's -O0; GCC uses the last -O flag)
target_compile_options(coremark PRIVATE -O2)
# Suppress -Werror from RT-Smart toolchain for upstream code
target_compile_options(coremark PRIVATE -Wno-error)
# FLAGS_STR: required by posix/core_portme.h for benchmark report output
target_compile_definitions(coremark PRIVATE "FLAGS_STR=\"-O2\"")
# RT-Smart SDK includes (set by bigcore toolchain, absent for littlecore)
if(RTT_INCLUDE)
target_include_directories(coremark PRIVATE ${RTT_INCLUDE})
endif()
FetchContent automatically downloads the CoreMark source at build time, so no manual source placement is needed. It builds the 5 core files plus posix/core_portme.c from the sources extracted into coremark_src_SOURCE_DIR.
Build Steps¶
Run from the repository root directory.
Verify the generated ELF¶
Expected output:
Transferring and Running on K230¶
The CMake deploy / run targets handle transfer and execution in one command (see CMake Targets for details):
cmake --build build/coremark --target deploy # build + SCP transfer
cmake --build build/coremark --target run # run via serial (Ctrl+C to disconnect)
Manual operation via SCP + minicom
Transfer via SCP¶
About /sharefs/
The correct destination is /sharefs/coremark, not /root/sharefs/coremark.
/sharefs/ is a vfat partition (/dev/mmcblk1p4) directly accessible from the bigcore.
It is also accessible from the Linux smallcore under the same path.
Run on the K230 bigcore (msh)¶
msh /> /sharefs/coremark
2K performance run parameters for coremark.
CoreMark Size : 666
Total ticks : 13603
Total time (secs): 13.603000
Iterations/Sec : 4410.791737
Iterations : 60000
Compiler version : GCC12.0.1 20220505 (prerelease)
Compiler flags : -O2
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 : 0xbd59
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 4410.791737 / GCC12.0.1 20220505 (prerelease) -O2 / Heap
Serial Connection¶
- Smallcore (Linux):
/dev/ttyACM0at 115200 bps - Bigcore (RT-Smart msh):
/dev/ttyACM1at 115200 bps
The CMake deploy / run targets handle transfer and execution in one command (see CMake Targets for details):
cmake --build build/coremark_linux --target deploy # build + SCP transfer
cmake --build build/coremark_linux --target run # run via serial (Ctrl+C to disconnect)
Manual operation via SCP + minicom
Transfer via SCP¶
Run on the K230 littlecore (Linux shell)¶
[root@canmv ~]# /root/coremark
2K performance run parameters for coremark.
CoreMark Size : 666
Total ticks : 12005
Total time (secs): 12.005000
Iterations/Sec : 2498.958767
Iterations : 30000
Compiler version : GCC10.2.0
Compiler flags : -O2
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 : 0x5275
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 2498.958767 / GCC10.2.0 -O2 / Heap
Serial Connection¶
- Smallcore (Linux):
/dev/ttyACM0at 115200 bps - Bigcore (RT-Smart msh):
/dev/ttyACM1at 115200 bps
Runtime Options¶
CoreMark runs with default settings (auto-detect ITERATIONS, auto-select SEED) when executed without arguments.
| Argument | Description | Default |
|---|---|---|
| seed1, seed2, seed3 | Benchmark input seeds | Auto-selected (validation/performance/profile) |
| iterations | Number of iterations | Auto (minimum value for ~10 seconds execution) |
Example: run with 50000 iterations:
CMake Targets¶
Configuration¶
cmake -B build/coremark -S apps/coremark \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/cmake/toolchain-k230-rtsmart.cmake"
Target List¶
| Target | Command | Description |
|---|---|---|
| (default) | cmake --build build/coremark |
Build C binary |
deploy |
cmake --build build/coremark --target deploy |
Build + SCP transfer to K230 /sharefs/ |
run |
cmake --build build/coremark --target run |
Run via bigcore serial (Ctrl+C to disconnect) |
Configuration¶
cmake -B build/coremark_linux -S apps/coremark \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/cmake/toolchain-k230-linux.cmake"
Target List¶
| Target | Command | Description |
|---|---|---|
| (default) | cmake --build build/coremark_linux |
Build C binary |
deploy |
cmake --build build/coremark_linux --target deploy |
Build + SCP transfer to K230 /root/ |
run |
cmake --build build/coremark_linux --target run |
Run via littlecore serial (Ctrl+C to disconnect) |
K230 Connection Settings¶
Customize connection parameters via CMake cache variables:
| Variable | Default | Description |
|---|---|---|
K230_IP |
(empty = auto-detect) | Littlecore IP address |
K230_USER |
root |
SSH user |
K230_SERIAL |
bigcore: /dev/ttyACM1, littlecore: /dev/ttyACM0 |
Serial port (for run) |
K230_SERIAL_LC |
/dev/ttyACM0 |
Littlecore serial (for IP auto-detect) |
K230_BAUD |
115200 |
Baud rate |
Future Extensions¶
Multi-threaded support¶
To run CoreMark in multi-threaded mode:
- Copy the upstream
posix/core_portme.ctoapps/coremark/src/core_portme.c - Change the source path in CMakeLists.txt to
src/core_portme.c - Add
-DMULTITHREAD=4 -DUSE_PTHREAD=1in CMake and addpthreadtotarget_link_libraries