From f93327db201e1aa6ddeb4998506e6305cbbe60b1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 24 Jul 2023 11:25:54 +0200 Subject: [PATCH] feat(coremark): add coremark component and example --- .github/ISSUE_TEMPLATE/bug-report.yml | 1 + .github/workflows/upload_component.yml | 1 + .gitmodules | 4 + coremark/CMakeLists.txt | 26 +++ coremark/LICENSE.md | 100 +++++++++ coremark/README.md | 82 ++++++++ coremark/coremark | 1 + .../examples/coremark_example/CMakeLists.txt | 5 + coremark/examples/coremark_example/README.md | 40 ++++ .../coremark_example/main/CMakeLists.txt | 2 + .../main/coremark_example_main.c | 34 ++++ .../coremark_example/main/idf_component.yml | 5 + .../coremark_example/sdkconfig.defaults | 4 + .../coremark_example/sdkconfig.defaults.esp32 | 3 + .../sdkconfig.defaults.esp32s2 | 3 + .../sdkconfig.defaults.esp32s3 | 3 + coremark/idf_component.yml | 8 + coremark/linker.lf | 4 + coremark/port/core_portme.c | 123 +++++++++++ coremark/port/core_portme.h.in | 191 ++++++++++++++++++ test_app/CMakeLists.txt | 2 +- 21 files changed, 641 insertions(+), 1 deletion(-) create mode 100644 coremark/CMakeLists.txt create mode 100644 coremark/LICENSE.md create mode 100644 coremark/README.md create mode 160000 coremark/coremark create mode 100644 coremark/examples/coremark_example/CMakeLists.txt create mode 100644 coremark/examples/coremark_example/README.md create mode 100644 coremark/examples/coremark_example/main/CMakeLists.txt create mode 100644 coremark/examples/coremark_example/main/coremark_example_main.c create mode 100644 coremark/examples/coremark_example/main/idf_component.yml create mode 100644 coremark/examples/coremark_example/sdkconfig.defaults create mode 100644 coremark/examples/coremark_example/sdkconfig.defaults.esp32 create mode 100644 coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 create mode 100644 coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 create mode 100644 coremark/idf_component.yml create mode 100644 coremark/linker.lf create mode 100644 coremark/port/core_portme.c create mode 100644 coremark/port/core_portme.h.in diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index e200a45e68..dae61109e5 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -23,6 +23,7 @@ body: - bdc_motor - cbor - coap + - coremark - eigen - esp_encrypted_img - esp_jpeg diff --git a/.github/workflows/upload_component.yml b/.github/workflows/upload_component.yml index 556b4bc4ce..a996625969 100644 --- a/.github/workflows/upload_component.yml +++ b/.github/workflows/upload_component.yml @@ -29,6 +29,7 @@ jobs: cbor; ccomp_timer; coap; + coremark; eigen; esp_delta_ota; esp_encrypted_img; diff --git a/.gitmodules b/.gitmodules index fd625620b7..29d8a05298 100644 --- a/.gitmodules +++ b/.gitmodules @@ -96,3 +96,7 @@ sbom-url = https://github.com/glennrp/libpng.git sbom-description = Portable Network Graphics support, official PNG reference library sbom-hash = 07b8803110da160b158ebfef872627da6c85cbdf + +[submodule "coremark/coremark"] + path = coremark/coremark + url = https://github.com/eembc/coremark.git diff --git a/coremark/CMakeLists.txt b/coremark/CMakeLists.txt new file mode 100644 index 0000000000..d26321b2dc --- /dev/null +++ b/coremark/CMakeLists.txt @@ -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 "$;$;${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}) diff --git a/coremark/LICENSE.md b/coremark/LICENSE.md new file mode 100644 index 0000000000..14e53e9eec --- /dev/null +++ b/coremark/LICENSE.md @@ -0,0 +1,100 @@ +# COREMARK® ACCEPTABLE USE AGREEMENT + +This ACCEPTABLE USE AGREEMENT (this “Agreement”) is offered by Embedded Microprocessor Benchmark Consortium, a California nonprofit corporation (“Licensor”), to users of its CoreMark® software (“Licensee”) exclusively on the following terms. + +Licensor offers benchmarking software (“Software”) pursuant to an open source license, but carefully controls use of its benchmarks and their associated goodwill. Licensor has registered its trademark in one of the benchmarks available through the Software, COREMARK, Ser. No. 85/487,290; Reg. No. 4,179,307 (the “Trademark”), and promotes the use of a standard metric as a benchmark for assessing the performance of embedded systems. Solely on the terms described herein, Licensee may use and display the Trademark in connection with the generation of data regarding measurement and analysis of computer and embedded system benchmarking via the Software (the “Licensed Use”). + +## Article 1 – License Grant. +1.1. License. Subject to the terms and conditions of this Agreement, Licensor hereby grants to Licensee, and Licensee hereby accepts from Licensor, a personal, non-exclusive, royalty-free, revocable right and license to use and display the Trademark during the term of this Agreement (the “Term”), solely and exclusively in connection with the Licensed Use. During the Term, Licensee (i) shall not modify or otherwise create derivative works of the Trademark, and (ii) may use the Trademark only to the extent permitted under this License. Neither Licensee nor any affiliate or agent thereof shall otherwise use the Trademark without the prior express written consent of Licensor, which may be withheld in its sole and absolute discretion. All rights not expressly granted to Licensee hereunder shall remain the exclusive property of Licensor. + +1.2. Modifications to the Software. Licensee shall not use the Trademark in connection with any use of a modified, derivative, or otherwise altered copy of the Software. + +1.3. Licensor’s Use. Nothing in this Agreement shall preclude Licensor or any of its successors or assigns from using or permitting other entities to use the Trademark, whether or not such entity directly or indirectly competes or conflicts with Licensee’s Licensed Use in any manner. + +1.4. Term and Termination. This Agreement is perpetual unless terminated by either of the parties. Licensee may terminate this Agreement for convenience, without cause or liability, for any reason or for no reason whatsoever, upon ten (10) business days written notice. Licensor may terminate this Agreement effective immediately upon notice of breach. Upon termination, Licensee shall immediately remove all implementations of the Trademark from the Licensed Use, and delete all digitals files and records of all materials related to the Trademark. + +## Article 2 – Ownership. +2.1. Ownership. Licensee acknowledges and agrees that Licensor is the owner of all right, title, and interest in and to the Trademark, and all such right, title, and interest shall remain with Licensor. Licensee shall not contest, dispute, challenge, oppose, or seek to cancel Licensor’s right, title, and interest in and to the Trademark. Licensee shall not prosecute any application for registration of the Trademark. Licensee shall display appropriate notices regarding ownership of the Trademark in connection with the Licensed Use. + +2.2. Goodwill. Licensee acknowledges that Licensee shall not acquire any right, title, or interest in the Trademark by virtue of this Agreement other than the license granted hereunder, and disclaims any such right, title, interest, or ownership. All goodwill and reputation generated by Licensee’s use of the Trademark shall inure to the exclusive benefit of Licensor. Licensee shall not by any act or omission use the Trademark in any manner that disparages or reflects adversely on Licensor or its Licensed Use or reputation. Licensee shall not take any action that would interfere with or prejudice Licensor’s ownership or registration of the Trademark, the validity of the Trademark or the validity of the license granted by this Agreement. If Licensor determines and notifies Licensee that any act taken in connection with the Licensed Use (i) is inaccurate, unlawful or offensive to good taste; (ii) fails to provide for proper trademark notices, or (iii) otherwise violates Licensee’s obligations under this Agreement, the license granted under this Agreement shall terminate. + +## Article 3 – Indemnification. +3.1. Indemnification Generally. Licensee agrees to indemnify, defend, and hold harmless (collectively “indemnify” or “indemnification”) Licensor, including Licensor’s members, managers, officers, and employees (collectively “Related Persons”), from and against, and pay or reimburse Licensor and such Related Persons for, any and all third-party actions, claims, demands, proceedings, investigations, inquiries (collectively, “Claims”), and any and all liabilities, obligations, fines, deficiencies, costs, expenses, royalties, losses, and damages (including reasonable outside counsel fees and expenses) associated with such Claims, to the extent that such Claim arises out of (i) Licensee’s material breach of this Agreement, or (ii) any allegation(s) that Licensee’s actions infringe or violate any third-party intellectual property right, including without limitation, any U.S. copyright, patent, or trademark, or are otherwise found to be tortious or criminal (whether or not such indemnified person is a named party in a legal proceeding). + +3.2. Notice and Defense of Claims. Licensor shall promptly notify Licensee of any Claim for which indemnification is sought, following actual knowledge of such Claim, provided however that the failure to give such notice shall not relieve Licensee of its obligations hereunder except to the extent that Licensee is materially prejudiced by such failure. In the event that any third-party Claim is brought, Licensee shall have the right and option to undertake and control the defense of such action with counsel of its choice, provided however that (i) Licensor at its own expense may participate and appear on an equal footing with Licensee in the defense of any such Claim, (ii) Licensor may undertake and control such defense in the event of the material failure of Licensee to undertake and control the same; and (iii) the defense of any Claim relating to the intellectual property rights of Licensor or its licensors and any related counterclaims shall be solely controlled by Licensor with counsel of its choice. Licensee shall not consent to judgment or concede or settle or compromise any Claim without the prior written approval of Licensor (whose approval shall not be unreasonably withheld), unless such concession or settlement or compromise includes a full and unconditional release of Licensor and any applicable Related Persons from all liabilities in respect of such Claim. + +## Article 4 – Miscellaneous. +4.1. Relationship of the Parties. This Agreement does not create a partnership, franchise, joint venture, agency, fiduciary, or employment relationship between the parties. + +4.2. No Third-Party Beneficiaries. Except for the rights of Related Persons under Article 3 (Indemnification), there are no third-party beneficiaries to this Agreement. + +4.3. Assignment. Licensee’s rights hereunder are non-assignable, and may not be sublicensed. + +4.4. Equitable Relief. Licensee acknowledges that the remedies available at law for any breach of this Agreement will, by their nature, be inadequate. Accordingly, Licensor may obtain injunctive relief or other equitable relief to restrain a breach or threatened breach of this Agreement or to specifically enforce this Agreement, without proving that any monetary damages have been sustained, and without the requirement of posting of a bond prior to obtaining such equitable relief. + +4.5. Governing Law. This Agreement will be interpreted, construed, and enforced in all respects in accordance with the laws of the State of California, without reference to its conflict of law principles. + +4.6. Attorneys’ Fees. If any legal action, arbitration or other proceeding is brought for the enforcement of this Agreement, or because of an alleged dispute, breach, default, or misrepresentation in connection with any of the provisions of this Agreement, the successful or prevailing party shall be entitled to recover its reasonable attorneys’ fees and other reasonable costs incurred in that action or proceeding, in addition to any other relief to which it may be entitled. + +4.7. Amendment; Waiver. This Agreement may not be amended, nor may any rights under it be waived, except in writing by Licensor. + +4.8. Severability. If any provision of this Agreement is held by a court of competent jurisdiction to be contrary to law, the provision shall be modified by the court and interpreted so as best to accomplish the objectives of the original provision to the fullest extent +permitted by law, and the remaining provisions of this Agreement shall remain in effect. + +4.9. Entire Agreement. This Agreement constitutes the entire agreement between the parties and supersedes all prior and contemporaneous agreements, proposals or representations, written or oral, concerning its subject matter. + + +# Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +## TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + You must give any other recipients of the Work or Derivative Works a copy of this License; and + You must cause any modified files to carry prominent notices stating that You changed the files; and + You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/coremark/README.md b/coremark/README.md new file mode 100644 index 0000000000..ef326e4a3a --- /dev/null +++ b/coremark/README.md @@ -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. + + + diff --git a/coremark/coremark b/coremark/coremark new file mode 160000 index 0000000000..d5fad6bd09 --- /dev/null +++ b/coremark/coremark @@ -0,0 +1 @@ +Subproject commit d5fad6bd094899101a4e5fd53af7298160ced6ab diff --git a/coremark/examples/coremark_example/CMakeLists.txt b/coremark/examples/coremark_example/CMakeLists.txt new file mode 100644 index 0000000000..1f9f039906 --- /dev/null +++ b/coremark/examples/coremark_example/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + +set(COMPONENTS main) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(coremark_example) diff --git a/coremark/examples/coremark_example/README.md b/coremark/examples/coremark_example/README.md new file mode 100644 index 0000000000..63be9abaff --- /dev/null +++ b/coremark/examples/coremark_example/README.md @@ -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 +``` diff --git a/coremark/examples/coremark_example/main/CMakeLists.txt b/coremark/examples/coremark_example/main/CMakeLists.txt new file mode 100644 index 0000000000..5922389710 --- /dev/null +++ b/coremark/examples/coremark_example/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS coremark_example_main.c + PRIV_REQUIRES coremark) diff --git a/coremark/examples/coremark_example/main/coremark_example_main.c b/coremark/examples/coremark_example/main/coremark_example_main.c new file mode 100644 index 0000000000..59a906b440 --- /dev/null +++ b/coremark/examples/coremark_example/main/coremark_example_main.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#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); +} diff --git a/coremark/examples/coremark_example/main/idf_component.yml b/coremark/examples/coremark_example/main/idf_component.yml new file mode 100644 index 0000000000..9fa4f47be0 --- /dev/null +++ b/coremark/examples/coremark_example/main/idf_component.yml @@ -0,0 +1,5 @@ +description: Coremark benchmark application +dependencies: + espressif/coremark: + version: "*" + override_path: '../../../' diff --git a/coremark/examples/coremark_example/sdkconfig.defaults b/coremark/examples/coremark_example/sdkconfig.defaults new file mode 100644 index 0000000000..0fc52645b2 --- /dev/null +++ b/coremark/examples/coremark_example/sdkconfig.defaults @@ -0,0 +1,4 @@ +# For IDF v5.x +CONFIG_ESP_TASK_WDT_INIT=n +# For IDF v4.x +CONFIG_ESP_TASK_WDT=n diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32 new file mode 100644 index 0000000000..53ddd0870c --- /dev/null +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32 @@ -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 diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 new file mode 100644 index 0000000000..f21989ebb5 --- /dev/null +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 @@ -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 diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 new file mode 100644 index 0000000000..3ac48bd812 --- /dev/null +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 @@ -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 diff --git a/coremark/idf_component.yml b/coremark/idf_component.yml new file mode 100644 index 0000000000..9da4cd930d --- /dev/null +++ b/coremark/idf_component.yml @@ -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" diff --git a/coremark/linker.lf b/coremark/linker.lf new file mode 100644 index 0000000000..104835962b --- /dev/null +++ b/coremark/linker.lf @@ -0,0 +1,4 @@ +[mapping:coremark] +archive: libcoremark.a +entries: + * (noflash) diff --git a/coremark/port/core_portme.c b/coremark/port/core_portme.c new file mode 100644 index 0000000000..0a62cc85ce --- /dev/null +++ b/coremark/port/core_portme.c @@ -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 +#include +#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 . + This methodology is taken to accomodate any hardware or simulated platform. + The sample implementation returns millisecs by default, + and the resolution is controlled by +*/ +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 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; +} diff --git a/coremark/port/core_portme.h.in b/coremark/port/core_portme.h.in new file mode 100644 index 0000000000..bad5ac71bc --- /dev/null +++ b/coremark/port/core_portme.h.in @@ -0,0 +1,191 @@ +/* + * SPDX-FileCopyrightText: 2018 EEMBC + * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Topic : Description + This file contains configuration constants required to execute on different platforms +*/ +#ifndef CORE_PORTME_H +#define CORE_PORTME_H +/************************/ +/* Data types and settings */ +/************************/ + +#include +#include "esp_idf_version.h" + +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. +*/ +#ifndef HAS_FLOAT +#define HAS_FLOAT 1 +#endif +/* Configuration : HAS_TIME_H + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef HAS_TIME_H +#define HAS_TIME_H 0 +#endif +/* Configuration : USE_CLOCK + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef USE_CLOCK +#define USE_CLOCK 0 +#endif +/* Configuration : HAS_STDIO + Define to 1 if the platform has stdio.h. +*/ +#ifndef HAS_STDIO +#define HAS_STDIO 1 +#endif +/* Configuration : HAS_PRINTF + Define to 1 if the platform has stdio.h and implements the printf function. +*/ +#ifndef HAS_PRINTF +#define HAS_PRINTF 1 +#endif + +/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION + Initialize these strings per platform +*/ +#ifndef COMPILER_VERSION + #ifdef __GNUC__ + #define COMPILER_VERSION "GCC"__VERSION__ + #else + #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" + #endif +#endif +#ifndef COMPILER_FLAGS + #define COMPILER_FLAGS "$>,EXCLUDE,^-(([DWI])|(fmacro)).*>, >" +#endif +#ifndef MEM_LOCATION + #define MEM_LOCATION "IRAM" +#endif + +/* Data Types : + To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! +*/ +typedef int16_t ee_s16; +typedef uint16_t ee_u16; +typedef int ee_s32; +typedef double ee_f32; +typedef uint8_t ee_u8; +typedef unsigned long ee_u32; +typedef ee_u32 ee_ptr_int; + +#define ee_size_t size_t + +/* Configuration : CORE_TICKS + Define type of return from the timing functions. + */ + +typedef ee_u32 CORE_TICKS; + +/* align_mem : + This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. +*/ +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) + +/* Configuration : SEED_METHOD + Defines method to get seed values that cannot be computed at compile time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. +*/ +#ifndef SEED_METHOD +#define SEED_METHOD SEED_VOLATILE +#endif + +/* Configuration : MEM_METHOD + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). +*/ +#ifndef MEM_METHOD +#define MEM_METHOD MEM_STATIC +#endif + +/* Configuration : MULTITHREAD + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. + + Two sample implementations are provided. Use or to enable them. + + It is valid to have a different implementation of and in , + to fit a particular architecture. +*/ +#ifndef MULTITHREAD +#define MULTITHREAD 1 +#define USE_PTHREAD 0 +#define USE_FORK 0 +#define USE_SOCKET 0 +#endif + +/* Configuration : MAIN_HAS_NOARGC + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value greater then 1. +*/ +#ifndef MAIN_HAS_NOARGC +#define MAIN_HAS_NOARGC 1 +#endif + +/* Configuration : MAIN_HAS_NORETURN + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main +*/ +#ifndef MAIN_HAS_NORETURN +#define MAIN_HAS_NORETURN 0 +#endif + +/* Variable : default_num_contexts + Not used for this simple port, must cintain the value 1. +*/ +extern ee_u32 default_num_contexts; + +typedef struct CORE_PORTABLE_S { + ee_u8 portable_id; +} core_portable; + +/* target specific init/fini */ +void portable_init(core_portable *p, int *argc, char *argv[]); +void portable_fini(core_portable *p); + +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE==1200) +#define PROFILE_RUN 1 +#elif (TOTAL_DATA_SIZE==2000) +#define PERFORMANCE_RUN 1 +#else +#define VALIDATION_RUN 1 +#endif +#endif + +#endif /* CORE_PORTME_H */ diff --git a/test_app/CMakeLists.txt b/test_app/CMakeLists.txt index 39683c07b2..f053bf8944 100644 --- a/test_app/CMakeLists.txt +++ b/test_app/CMakeLists.txt @@ -9,7 +9,7 @@ set(EXTRA_COMPONENT_DIRS ../libsodium ../expat ../cbor ../jsmn ../qrcode ../coap # 2. Add here if the component is compatible with IDF >= v4.4 if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4") - list(APPEND EXTRA_COMPONENT_DIRS ../iqmath ../pid_ctrl ../esp_encrypted_img ../pcap ../esp_jpeg ../libpng ../zlib) + list(APPEND EXTRA_COMPONENT_DIRS ../iqmath ../pid_ctrl ../esp_encrypted_img ../pcap ../esp_jpeg ../libpng ../zlib ../coremark) endif() # 3. Add here if the component is compatible with IDF >= v5.0