赞
踩
CoreMark是一个综合基准,用于测量嵌入式系统中使用的中央处理器(CPU)的性能。代码用C编写,包含以下算法:列表处理(增删改查和排序)、矩阵操作(公共矩阵操作)、状态机(确定输入流是否包含有效数字)和CRC(Cyclic redundancy check 循环冗余校验) 。目前 CoreMark已迅速成为测量与比较处理器性能的业界基准测试。
为了确保编译器在编译时不会预先计算结果,程序的每次计算均会即时得到一项数据,而此数据不会再编译时被得到。另外,在计时中,所有的代码均为基准自身的代码,而不是调用库中的代码。
测试标准是在配置参数的组合下单位时间内运行的CoreMark程序次数(单位:CoreMark/MHz),该数字值越大则说明测试的性能越好。
eembc官网https://www.eembc.org/coremark/scores.php
有各种CPU进行CoreMark测试后的数据可以查阅比对。不同编译器及编译器优化等级对应的coremark得分都不一样。
CoreMark官网:Embedded Microprocessor Benchmark Consortium
使用前文《pico-project-generator使用》生成的项目,将CoreMark代码下载至项目文件夹下。下载完成后,可以看到以下源文件在根目录下,其他文件夹都是针对不同平台的适配文件。
core_list_join.c
core_main.c
core_matrix.c
core_state.c
core_util.c
coremark.h
barebones目录:裸机环境下需要修改的适配文件
posix目录:cygwin、linux、freebsd、macos、rtems等操作系统都采用这个适配文件
simple目录:基本移植需要修改的适配文件
posix目录是为支持posix平台实现,如Linux。这次coremark基于FreeRTOS操作系统下进行,使用posix下的文件进行修改工作量较少。同时posix适配可通过修改MULTITHREAD宏进行多核并行运行。RP2040芯片是双核Cortex-M0+芯片,但本次只使用单核测试,也为后续做双核coremark测试做准备。
适配文件主要是修改posix目录下的core_portme.c和core_portme.h。
参照前文《FreeRTOS体验》一文,添加FreeRTOS相关文件,并可正常运行。
主要涉及CMakeLists.txt的add_executable加入coremark对应的c文件,target_include_directories加入对应.h路径。
- add_executable(pico_coremark pico_coremark.c
- FreeRTOS-Kernel/event_groups.c
- FreeRTOS-Kernel/list.c
- FreeRTOS-Kernel/queue.c
- FreeRTOS-Kernel/tasks.c
- FreeRTOS-Kernel/timers.c
- FreeRTOS-Kernel/portable/GCC/ARM_CM0/port.c
- FreeRTOS-Kernel/portable/MemMang/heap_4.c
- coremark/core_list_join.c
- coremark/core_main.c
- coremark/core_matrix.c
- coremark/core_state.c
- coremark/core_util.c
- coremark/posix/core_portme.c
- )
- target_include_directories(pico_coremark PRIVATE
- ${CMAKE_CURRENT_LIST_DIR}
- ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
- ${CMAKE_CURRENT_LIST_DIR}/FreeRTOS-Kernel/include
- ${CMAKE_CURRENT_LIST_DIR}/FreeRTOS-Kernel/portable/GCC/ARM_CM0
- ${CMAKE_CURRENT_LIST_DIR}/coremark
- ${CMAKE_CURRENT_LIST_DIR}/coremark/posix
- )
在core_portme.h头文件中加入:
#define USE_CLOCK 1
#define MAIN_HAS_NOARGC 1
#define SEED_METHOD SEED_VOLATILE
#define ITERATIONS 10000,由于CoreMark必须要运行超过10s,如果coremark在运行过程中提示出错,须将此参数改大。
设定memory模式:我选择的是使用FreeRTOS的堆,添加#define MEM_METHOD MEM_MALLOC
指定编译参数:#define FLAGS_STR"-O3",根据当前编译优化参数写入
指定存储相关参数:#define MEM_LOCATION "code in flash, data on heap"
我们在适配中要使用到FreeRTOS相关接口,加入相关头文件
-
- #include "FreeRTOS.h"
- #include "task.h"
其他参数使用默认设置
修改MEM_METHOD == MEM_MALLOC下对应malloc、free函数实现。
修改portable_malloc函数内malloc为pvPortMalloc
修改portable_free函数内malloc为pvPortFree
-
- /* Function: portable_malloc
- Provide malloc() functionality in a platform specific way.
- */
- void *
- portable_malloc(size_t size)
- {
- return pvPortMalloc(size);
- }
- /* Function: portable_free
- Provide free() functionality in a platform specific way.
- */
- void
- portable_free(void *p)
- {
- vPortFree(p);
- }
修改USE_CLOCK使能后计时相关接口为FreeRTOS提供的函数
-
- #define NSECS_PER_SEC configTICK_RATE_HZ
- #define CORETIMETYPE TickType_t
- #define GETMYTIME(_t) (*_t = xTaskGetTickCount())
由于pico默认有main函数,进入main函数进行硬件初始化,FreeRTOS任务创建等工作。core_main.c中也定义了main函数,重定义了,修改core_main.c中的main为coremark_main,并通过创建的task,在task中调用coremark_main,以免main函数栈空间不够运行失败。
代码如下:
-
- #include <stdio.h>
- #include "pico/stdlib.h"
- #include "FreeRTOS.h"
- #include "task.h"
-
- // UART defines
- // By default the stdout UART is `uart0`, so we will use the second one
- #define UART_ID uart1
- #define BAUD_RATE 9600
-
- // Use pins 4 and 5 for UART1
- // Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
- #define UART_TX_PIN 4
- #define UART_RX_PIN 5
-
- // GPIO defines
- // Example uses GPIO 2
- #define GPIO 2
-
- void vTaskCode( void * pvParameters )
- {
- /* The parameter value is expected to be 1 as 1 is passed in the
- pvParameters value in the call to xTaskCreate() below.
- configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
- */
- extern void coremark_main();
- coremark_main();
-
- const uint LED_PIN = PICO_DEFAULT_LED_PIN;
- gpio_init(LED_PIN);
- gpio_set_dir(LED_PIN, GPIO_OUT);
-
- for( ;; )
- {
- vTaskDelay(500);
- gpio_put(LED_PIN, 1);
- vTaskDelay(500);
- gpio_put(LED_PIN, 0);
- }
- }
-
- int main()
- {
- stdio_init_all();
-
- BaseType_t xReturned;
- TaskHandle_t xHandle = NULL;
- /* Create the task, storing the handle. */
- xReturned = xTaskCreate(
- vTaskCode, /* Function that implements the task. */
- "Blinky task", /* Text name for the task. */
- 512, /* Stack size in words, not bytes. */
- ( void * ) 1, /* Parameter passed into the task. */
- tskIDLE_PRIORITY,/* Priority at which the task is created. */
- &xHandle );
-
- vTaskStartScheduler();
- return 0;
- }
Pico默认工作频率为133MHz,代码通过QSPI运行在外部Flash上。
Debug编译模式下:
- 2K performance run parameters for coremark.
- CoreMark Size : 666
- Total ticks : 63178
- Total time (secs): 63.178000
- Iterations/Sec : 158.282947
- Iterations : 10000
- Compiler version : GCC10.2.1 20201103 (release)
- Compiler flags : -O0
- Memory location : code in flash, data on heap
- seedcrc : 0xe9f5
- [0]crclist : 0xe714
- [0]crcmatrix : 0x1fd7
- [0]crcstate : 0x8e3a
- [0]crcfinal : 0x988c
- Correct operation validated. See README.md for run and reporting rules.
- CoreMark 1.0 : 158.282947 / GCC10.2.1 20201103 (release) -O0 / code in flash, data on heap
Release编译模式下:
- 2K performance run parameters for coremark.
- CoreMark Size : 666
- Total ticks : 42558
- Total time (secs): 42.558000
- Iterations/Sec : 234.973448
- Iterations : 10000
- Compiler version : GCC10.2.1 20201103 (release)
- Compiler flags : -O3
- Memory location : code in flash, data on heap
- seedcrc : 0xe9f5
- [0]crclist : 0xe714
- [0]crcmatrix : 0x1fd7
- [0]crcstate : 0x8e3a
- [0]crcfinal : 0x988c
- Correct operation validated. See README.md for run and reporting rules.
- CoreMark 1.0 : 234.973448 / GCC10.2.1 20201103 (release) -O3 / code in flash, data on heap
Debug模式下 coremark为1.18CoreMark/MHz,Release模式下1.75CoreMark/MHz,Debug和Release编译模式运行速度有一定的差距。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。