Coremark has been EEMBC’s CPU evaluation standard since 2009. EEMBC (Embedded Microprocessor Benchmark Consortium) is a non-profit organization with members including Huawei, Intel, ARM and Analog Devices. EEMBC is an important standard for evaluating embedded processors and compilers .
Coremark mainly detects ALU (Arithmetic Logic Unit), memory reference, pipeline and branch operations. It is designed to make it impossible for the CPU to run benchmark tests in advance, thus ensuring its fairness. During the specified test time, Coremark does not allow invoking third-party library, and the results are completely based on the optimization of the compiler and the execution processing time of the CPU. Because Coremark mainly provides testing of the CPU architecture, in order to abandon the superiority of the hardware manufacturing process, the final test results of Coremark will be normalized, that is to say, the final test results will be evenly divided into the system clock and the unit is Coremark/MHz. Coremark’s main code is written in C language, including list processing (find and sort), matrix manipulation (common matrix operations), state machine (determine if an input stream contains valid numbers), and CRC (cyclic redundancy check) .
The first step is to download the c source directory from the EEMBC official website, or directly search for the EEMBC github (https://github.com/eembc/coremark). There will be 8 files in the source directory that needs to be copied to the project workspace (Here, FreedomStudio is used as the platform). They are as follows:
Only three of them need to be changed. These three files are “core_portme.h”, “core_portme.c”, and “coremark.h” (Use core_portme.h and core_portme.c under “simple” folder) . The others can just be added directly to the project.
2.1 Porting core_portme.h
First of all, there are 14 macros in total. They are shown in Table 1 as follows:
|HAS_FLOAT||Define to 1 if platform supports floating point.|
|HAS_TIME_H||Define to 1 if platform has the time.h header file, and implementation of functions thereof.|
|USE_CLOCK||Define to 1 if platform has the time.h header file, and implementation of functions thereof.|
|HAS_STDIO||Define to 1 if the platform has stdio.h.|
|HAS_PRINTF||Define to 1 if the platform has stdio.h and implements the printf function.|
|COMPILER_VERSION||Put the compiler version here (e.g. GCC 7.2.0).|
|COMPILER_FLAGS||Put the compiler flags here (e.g. O3).|
|MEM_LOCATION||Put the memory location of code execution here (e.g. STACK).|
|CORTIMETYPE||Define type of return from the timing functions.|
|SEED_METHOD||Define the method to get seed values that cannot be computed at compile time.|
|MEM_METHOD||Define method to get a block of memory.|
|MULTITHREAD||Define for parallel execution.|
|MAIN_HAS_NOARGC||Needed if platform does not support getting arguments to main (This flag only matters if MULTITHREAD has been defined to a value greater then 1).|
|MAIN_HAS_NORETURN||Needed if platform does not support returning a value from main.|
Table 1 Macros Description
They should be modified and configured according to the porting system and platform. For example, HAS_FLOAT should be set to 0 if floating point operations are not supported. HAS_TIME_H and USE_CLOCK define whether the timer has the time.h header file and implementation of function thereof. time.h is imported to invoke the timer in the core_portme.c, which is then used in the main iteration loop to count the time. If the platform uses a different function to define time, it should be overwritten. HAS_PRINTF defines whether the platform uses the standard I/O library to print. It could be redefined according to the needs. MEM_LOCATION is very important, because it defines the location where the code is executed.
Figure 1 Configure HAS_FLOAT
Besides, there is an execution mode could be configured. As shown in Figure 2, there are PROFILE_RUN, PERFORMANCE_RUN, and VALIDATION_RUN that could be selected. TOTAL_DATA_SIZE could be modified in coremark.h.
Figure 2 Configuration of the execution mode
Some parameters like ITERATIONS could be defined here as well, as shown in Figure 3.
Figure 3 Parameter configuration
Last but not least, the corresponding libraries should be modified with respect to the configurations.
2.2 Porting core_portme.c
Parameter “EE_TICKS_PER_SEC” is the total ticks for every second, which is related to the system clock. It should be modified accordingly. The most important functions are related to timer, which are “start_time”,”stop_time”, and “get_time”. As mentioned above, the time-related function could be modified as needed. See Figure 4 for the details of time-related functions. In the main of core_main.c. The first ever function being called is “portable_init”. The initialization and debug print information could be implemented there as shown in Figure 5. Note that the libraries should also be correspondingly added.
Figure 4 Time-related functions
Figure 5 Initialization function
2.3 Porting coremark.h
The memory definition such as “malloc” and “free” could be modified here as shown in Figure 6.
Figure 6 Memory-related function
2.4 Other Points
The whole program is required to run for at least 10 seconds. The iteration times could be modified accordingly. Theoretically, the more iterations it runs, the more accurate the result will be. Also, README.md is included in the directory. See attached files for more information. For instance, as shown in Figure 7, it lists some rules ensuring the Coremark result is valid.
Figure 7 README.md Information
3. Test Result Evaluation
The FII RISC-V3.01 on FII-PRX100-S (ARTIX-7, XC7A100T) XILINX FPGA Board (https://fpgamarketing.com/FII-PRX100-S-ARTIX-100T-XC7A100T-Xilinx-RISC-V-FPGA-Board-FII-PRX100-S-1.htm) system clock is 50MHz, and the Coremark test score shown in Figure 8 is 3.38 (169/50 Coremark/MHz).
Figure 8 FII RISC-V3.01 Coremark
Figure 9 is a screenshot of the CPU Coremarks provided on the EEMBC website with certification.
Figure 9 Part of the CPU Coremark result of EEMBC
Figure 10 CPU Coremark Comparison
FII RISC-V3.01 is a single-core, a mix of 2-stage and 3-stage pipeline CPU. Figure 10 lists some other single-core CPUs’ Coremark being certified by EEMBC. FII RISC-V3.01 has been highlighted using red strokes. It can be seen that FII RISC-V3.01 Coremark is above the average Coremark among the listed 15 CPUs. For the three CPUs which have obviously higher Coremark, they are STMicroelectronics STM32H72x/73x rev Z (highlight as blue), STMicroelectronics STM32H7B3 rev Z (highlight as blue) and Renesas Electronics RX66T (highlight as blue). From the official manual by STMicroelectronics , STM32H72x/73x rev Z and STMicroelectronics STM32H7B3 rev Z both use Cortex-M7, which has a 6-stage super scalar pipeline. Renesas Electronics RX66T uses RXv3 core, which has improved 5-stage pipeline. Since with more stages of pipeline, undoubtedly the better performance of CPU is, to make the comparison of performance more fair, compared with Texas Stellaris Cortex-M3 (highlight as blue), which is also a 3-pipeline processor as FII RISC-V3.01. Nevertheless, FII RISC-V’s Coremark is greatly larger than theirs, even more than two times. Compared with another processor, Microchip ATSAML21J18B (highlight as blue), which is also a three-stage pipeline, the Coremark of FII RISC-V3.01 is still much higher.To conclude, with the same amount core stages of pipeline constrained, FII-RISCV3.01 performs outstandingly and is favourable.
- “EEMBC | Wikiwand”,Wikiwand, 2020. [Online]. Available: https://www.wikiwand.com/en/EEMBC. [Accessed: 29- Sep- 2020].
- “EEMBC”,org, 2020. [Online]. Available: https://www.eembc.org/coremark/index.php. [Accessed: 29- Sep- 2020].