-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #216 from igrr/feature/coremark
feat(coremark): add coremark component and example
- Loading branch information
Showing
21 changed files
with
641 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ body: | |
- bdc_motor | ||
- cbor | ||
- coap | ||
- coremark | ||
- eigen | ||
- esp_encrypted_img | ||
- esp_jpeg | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ jobs: | |
cbor; | ||
ccomp_timer; | ||
coap; | ||
coremark; | ||
eigen; | ||
esp_delta_ota; | ||
esp_encrypted_img; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
set(srcs coremark/core_list_join.c | ||
coremark/core_main.c | ||
coremark/core_matrix.c | ||
coremark/core_state.c | ||
coremark/core_util.c | ||
port/core_portme.c | ||
) | ||
|
||
idf_component_register(SRCS ${srcs} | ||
PRIV_INCLUDE_DIRS port coremark | ||
LDFRAGMENTS linker.lf | ||
PRIV_REQUIRES esp_timer) | ||
|
||
# compile coremark component with -O3 flag (will override the optimization level which is set globally) | ||
# set "-fjump-tables" and "-ftree-switch-conversion" explicitly, since IDF build system disables them by default | ||
set(component_compile_options "-O3" "-fjump-tables" "-ftree-switch-conversion") | ||
target_compile_options(${COMPONENT_LIB} PRIVATE ${component_compile_options}) | ||
|
||
# Get the compilation options and store them as a target property | ||
set(compile_options_list "$<TARGET_PROPERTY:__idf_build_target,COMPILE_OPTIONS>;$<TARGET_PROPERTY:__idf_build_target,C_COMPILE_OPTIONS>;${component_compile_options}") | ||
set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILER_OPT "${compile_options_list}") | ||
|
||
# Generate core_portme.h file, expanding "COMPILER_OPT" and "COMPILER_VER" generator expressions | ||
target_include_directories(${COMPONENT_LIB} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) | ||
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/core_portme.h INPUT ${CMAKE_CURRENT_SOURCE_DIR}/port/core_portme.h.in TARGET ${COMPONENT_LIB}) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
[![Component Registry](https://components.espressif.com/components/espressif/coremark/badge.svg)](https://components.espressif.com/components/espressif/coremark) | ||
|
||
# Coremark for ESP-IDF | ||
|
||
This component is a port of [CoreMark® benchmark](https://github.com/eembc/coremark) to ESP-IDF. It handles compiling CoreMark source files, providing necessary functions to measure timestamps, and enables various compiler to get higher performance. | ||
|
||
# Using the benchmark | ||
|
||
If you want to run the benchmark and see the results, create a demo project from the provided example: | ||
|
||
```bash | ||
idf.py create-project-from-example "espressif/coremark:coremark_example" | ||
``` | ||
|
||
You can then build the project in `coremark_example` directory as usual. For example, to build the project for ESP32-C3: | ||
|
||
```bash | ||
cd coremark_example | ||
idf.py set-target esp32c3 | ||
idf.py build | ||
idf.py -p PORT flash monitor | ||
``` | ||
|
||
(where `PORT` is the name of the serial port) | ||
|
||
Refer to ESP-IDF Getting Started Guide for more information about compiling and running a project. | ||
|
||
# Using as a component | ||
|
||
You can also integrate CoreMark code into you project by adding dependency on `espressif/coremark` component: | ||
|
||
```bash | ||
idf.py add-dependency espressif/coremark | ||
``` | ||
|
||
CoreMark benchmark entry point is an `int main(void)` function, which you can call from your application. | ||
|
||
# Performance tweaks | ||
|
||
This example does the following things to improve the benchmark result: | ||
|
||
1. Enables `-O3` compiler flag for CoreMark source files. | ||
2. Adds `-fjump-tables -ftree-switch-conversion` compiler flags for CoreMark source files. This overrides `-fno-jump-tables -fno-tree-switch-conversion` flags which get set in ESP-IDF build system by default. | ||
3. Places CoreMark code into internal instruction RAM using [linker.lf](linker.lf) file. | ||
|
||
For general information about optimizing performance of ESP-IDF applications, see the ["Performance" chapter of the Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/performance/index.html). | ||
|
||
# Example output | ||
|
||
Running on ESP32-C3, we can obtain the following output: | ||
|
||
``` | ||
Running coremark... | ||
2K performance run parameters for coremark. | ||
CoreMark Size : 666 | ||
Total ticks : 14661 | ||
Total time (secs): 14.661000 | ||
Iterations/Sec : 409.249028 | ||
Iterations : 6000 | ||
Compiler version : GCC12.2.0 | ||
Compiler flags : -ffunction-sections -fdata-sections -gdwarf-4 -ggdb -nostartfiles -nostartfiles -Og -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -O3 -fjump-tables -ftree-switch-conversion | ||
Memory location : IRAM | ||
seedcrc : 0xe9f5 | ||
[0]crclist : 0xe714 | ||
[0]crcmatrix : 0x1fd7 | ||
[0]crcstate : 0x8e3a | ||
[0]crcfinal : 0xa14c | ||
Correct operation validated. See README.md for run and reporting rules. | ||
CoreMark 1.0 : 409.249028 / GCC12.2.0 -ffunction-sections -fdata-sections -gdwarf-4 -ggdb -nostartfiles -nostartfiles -Og -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -O3 -fjump-tables -ftree-switch-conversion / IRAM | ||
CPU frequency: 160 MHz | ||
``` | ||
|
||
# Legal | ||
|
||
CoreMark is a trademark of EEMBC and EEMBC is a registered trademark of the Embedded Microprocessor Benchmark Consortium. | ||
|
||
CoreMark source code is Copyright (c) 2009 EEMBC. The source code is distributed under Apache 2.0 license with additional restrictions with regards to the use of the benchmark. See [LICENSE.md](LICENSE.md) for more details. | ||
|
||
Any additional code in this component ("port layer") is Copyright (c) 2022-2023 Espressif Systems (Shanghai) Co. Ltd. and is licensed under Apache 2.0 license. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
set(COMPONENTS main) | ||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(coremark_example) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# CoreMark example | ||
|
||
This example can be used to run CoreMark benchmark on an Espressif chip. | ||
|
||
The example doesn't require any special hardware and can run on any development board. | ||
|
||
## Building and running | ||
|
||
Run the application as usual for an ESP-IDF project. For example, for ESP32-C3: | ||
``` | ||
idf.py set-target esp32c3 | ||
idf.py -p PORT flash monitor | ||
``` | ||
|
||
After launching, the benchmark takes a few seconds to run, please be patient. | ||
|
||
## Example output | ||
|
||
Running on ESP32-C3, we can obtain the following output: | ||
|
||
``` | ||
Running coremark... | ||
2K performance run parameters for coremark. | ||
CoreMark Size : 666 | ||
Total ticks : 14661 | ||
Total time (secs): 14.661000 | ||
Iterations/Sec : 409.249028 | ||
Iterations : 6000 | ||
Compiler version : GCC12.2.0 | ||
Compiler flags : -ffunction-sections -fdata-sections -gdwarf-4 -ggdb -nostartfiles -nostartfiles -Og -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -O3 -fjump-tables -ftree-switch-conversion | ||
Memory location : IRAM | ||
seedcrc : 0xe9f5 | ||
[0]crclist : 0xe714 | ||
[0]crcmatrix : 0x1fd7 | ||
[0]crcstate : 0x8e3a | ||
[0]crcfinal : 0xa14c | ||
Correct operation validated. See README.md for run and reporting rules. | ||
CoreMark 1.0 : 409.249028 / GCC12.2.0 -ffunction-sections -fdata-sections -gdwarf-4 -ggdb -nostartfiles -nostartfiles -Og -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -O3 -fjump-tables -ftree-switch-conversion / IRAM | ||
CPU frequency: 160 MHz | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
idf_component_register(SRCS coremark_example_main.c | ||
PRIV_REQUIRES coremark) |
34 changes: 34 additions & 0 deletions
34
coremark/examples/coremark_example/main/coremark_example_main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: CC0-1.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "sdkconfig.h" | ||
|
||
// In IDF v5.x, there is a common CPU frequency option for all targets | ||
#if defined(CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) | ||
#define CPU_FREQ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ | ||
|
||
// In IDF v4.x, CPU frequency options were target-specific | ||
#elif defined(CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) | ||
#define CPU_FREQ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ | ||
#elif defined(CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) | ||
#define CPU_FREQ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ | ||
#elif defined(CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ) | ||
#define CPU_FREQ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ | ||
#elif defined(CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ) | ||
#define CPU_FREQ CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ | ||
#endif | ||
|
||
// Entry point of coremark benchmark | ||
extern int main(void); | ||
|
||
void app_main(void) | ||
{ | ||
printf("Running coremark...\n"); | ||
main(); | ||
printf("CPU frequency: %d MHz\n", CPU_FREQ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
description: Coremark benchmark application | ||
dependencies: | ||
espressif/coremark: | ||
version: "*" | ||
override_path: '../../../' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# For IDF v5.x | ||
CONFIG_ESP_TASK_WDT_INIT=n | ||
# For IDF v4.x | ||
CONFIG_ESP_TASK_WDT=n |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y | ||
# for IDF v4.4.x compatibility | ||
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y |
3 changes: 3 additions & 0 deletions
3
coremark/examples/coremark_example/sdkconfig.defaults.esp32s2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y | ||
# for IDF v4.4.x compatibility | ||
CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y |
3 changes: 3 additions & 0 deletions
3
coremark/examples/coremark_example/sdkconfig.defaults.esp32s3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y | ||
# for IDF v4.4.x compatibility | ||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
version: "1.1.0" | ||
description: CoreMark Benchmark | ||
url: https://github.com/espressif/idf-extra-components/tree/master/coremark | ||
issues: https://github.com/espressif/idf-extra-components/issues | ||
repository: https://github.com/espressif/idf-extra-components.git | ||
documentation: https://www.eembc.org/coremark/ | ||
dependencies: | ||
idf: ">=4.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[mapping:coremark] | ||
archive: libcoremark.a | ||
entries: | ||
* (noflash) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2018 EEMBC | ||
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "coremark.h" | ||
#include "core_portme.h" | ||
#include "sdkconfig.h" | ||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include "esp_timer.h" | ||
|
||
#if VALIDATION_RUN | ||
volatile ee_s32 seed1_volatile = 0x3415; | ||
volatile ee_s32 seed2_volatile = 0x3415; | ||
volatile ee_s32 seed3_volatile = 0x66; | ||
#endif | ||
#if PERFORMANCE_RUN | ||
volatile ee_s32 seed1_volatile = 0x0; | ||
volatile ee_s32 seed2_volatile = 0x0; | ||
volatile ee_s32 seed3_volatile = 0x66; | ||
#endif | ||
#if PROFILE_RUN | ||
volatile ee_s32 seed1_volatile = 0x8; | ||
volatile ee_s32 seed2_volatile = 0x8; | ||
volatile ee_s32 seed3_volatile = 0x8; | ||
#endif | ||
volatile ee_s32 seed4_volatile = 0; | ||
volatile ee_s32 seed5_volatile = 0; | ||
/* Porting : Timing functions | ||
How to capture time and convert to seconds must be ported to whatever is supported by the platform. | ||
e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. | ||
Sample implementation for standard time.h and windows.h definitions included. | ||
*/ | ||
/* Define : TIMER_RES_DIVIDER | ||
Divider to trade off timer resolution and total time that can be measured. | ||
Use lower values to increase resolution, but make sure that overflow does not occur. | ||
If there are issues with the return value overflowing, increase this value. | ||
*/ | ||
|
||
#define NSECS_PER_SEC CLOCKS_PER_SEC | ||
#define CORETIMETYPE ee_u32 | ||
#define GETMYTIME(_t) (*_t=(ee_u32)(esp_timer_get_time()/1000)) | ||
#define MYTIMEDIFF(fin,ini) ((fin)-(ini) ) /* 32-bit Timer overflow */ | ||
#define TIMER_RES_DIVIDER 1 | ||
#define SAMPLE_TIME_IMPLEMENTATION 1 | ||
#define EE_TICKS_PER_SEC (1000) | ||
|
||
/** Define Host specific (POSIX), or target specific global time variables. */ | ||
static CORETIMETYPE start_time_val, stop_time_val; | ||
|
||
/* Function : start_time | ||
This function will be called right before starting the timed portion of the benchmark. | ||
Implementation may be capturing a system timer (as implemented in the example code) | ||
or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. | ||
*/ | ||
void start_time(void) | ||
{ | ||
GETMYTIME(&start_time_val ); | ||
} | ||
/* Function : stop_time | ||
This function will be called right after ending the timed portion of the benchmark. | ||
Implementation may be capturing a system timer (as implemented in the example code) | ||
or other system parameters - e.g. reading the current value of cpu cycles counter. | ||
*/ | ||
void stop_time(void) | ||
{ | ||
GETMYTIME(&stop_time_val ); | ||
} | ||
/* Function : get_time | ||
Return an abstract "ticks" number that signifies time on the system. | ||
Actual value returned may be cpu cycles, milliseconds or any other value, | ||
as long as it can be converted to seconds by <time_in_secs>. | ||
This methodology is taken to accomodate any hardware or simulated platform. | ||
The sample implementation returns millisecs by default, | ||
and the resolution is controlled by <TIMER_RES_DIVIDER> | ||
*/ | ||
CORE_TICKS get_time(void) | ||
{ | ||
CORE_TICKS elapsed = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); | ||
return elapsed; | ||
} | ||
/* Function : time_in_secs | ||
Convert the value returned by get_time to seconds. | ||
The <secs_ret> type is used to accomodate systems with no support for floating point. | ||
Default implementation implemented by the EE_TICKS_PER_SEC macro above. | ||
*/ | ||
secs_ret time_in_secs(CORE_TICKS ticks) | ||
{ | ||
secs_ret retval = ((secs_ret)ticks) / EE_TICKS_PER_SEC; | ||
return retval; | ||
} | ||
|
||
ee_u32 default_num_contexts = 1; | ||
|
||
/* Function : portable_init | ||
Target specific initialization code | ||
Test for some common mistakes. | ||
*/ | ||
void portable_init(core_portable *p, int *argc, char *argv[]) | ||
{ | ||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { | ||
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); | ||
} | ||
if (sizeof(ee_u32) != 4) { | ||
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); | ||
} | ||
p->portable_id = 1; | ||
} | ||
/* Function : portable_fini | ||
Target specific final code | ||
*/ | ||
void portable_fini(core_portable *p) | ||
{ | ||
p->portable_id = 0; | ||
} |
Oops, something went wrong.