轻松玩转树莓派Pico之七、让Pico跑个分
admin
2024-05-18 18:41:28
0

1、CoreMark介绍

CoreMark是一个综合基准,用于测量嵌入式系统中使用的中央处理器(CPU)的性能。代码用C编写,包含以下算法:列表处理(增删改查和排序)、矩阵操作(公共矩阵操作)、状态机(确定输入流是否包含有效数字)和CRC(Cyclic redundancy check 循环冗余校验) 。目前 CoreMark已迅速成为测量与比较处理器性能的业界基准测试。

为了确保编译器在编译时不会预先计算结果,程序的每次计算均会即时得到一项数据,而此数据不会再编译时被得到。另外,在计时中,所有的代码均为基准自身的代码,而不是调用库中的代码。

测试标准是在配置参数的组合下单位时间内运行的CoreMark程序次数(单位:CoreMark/MHz),该数字值越大则说明测试的性能越好。

eembc官网https://www.eembc.org/coremark/scores.php

有各种CPU进行CoreMark测试后的数据可以查阅比对。不同编译器及编译器优化等级对应的coremark得分都不一样。

CoreMark官网:https://www.eembc.org/

源码下载地址:https://github.com/eembc/coremark

2、CoreMark适配

使用前文《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。

2.1、添加FreeRTOS相关文件

参照前文《FreeRTOS体验》一文,添加FreeRTOS相关文件,并可正常运行。

2.2、添加coremark相关文件

主要涉及CMakeLists.txt的add_executable加入coremark对应的c文件,target_include_directories加入对应.h路径。

add_executable(pico_coremark pico_coremark.c FreeRTOS-Kernel/event_groups.cFreeRTOS-Kernel/list.cFreeRTOS-Kernel/queue.cFreeRTOS-Kernel/tasks.cFreeRTOS-Kernel/timers.cFreeRTOS-Kernel/portable/GCC/ARM_CM0/port.cFreeRTOS-Kernel/portable/MemMang/heap_4.ccoremark/core_list_join.ccoremark/core_main.ccoremark/core_matrix.ccoremark/core_state.ccoremark/core_util.ccoremark/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
)

2.3、修改core_portme.h

在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"
  • 其他参数使用默认设置

2.4、修改core_portme.c

  • 修改MEM_METHOD == MEM_MALLOC下对应malloc、free函数实现。

修改portable_malloc函数内malloc为pvPortMalloc

修改portable_free函数内malloc为pvPortFree

/* Function: portable_mallocProvide malloc() functionality in a platform specific way.
*/
void *
portable_malloc(size_t size)
{return pvPortMalloc(size);
}
/* Function: portable_freeProvide 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())

3、跑分

3.1、修改core_mian.c

由于pico默认有main函数,进入main函数进行硬件初始化,FreeRTOS任务创建等工作。core_main.c中也定义了main函数,重定义了,修改core_main.c中的main为coremark_main,并通过创建的task,在task中调用coremark_main,以免main函数栈空间不够运行失败。

代码如下:

#include 
#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 2void vTaskCode( void * pvParameters )
{/* The parameter value is expected to be 1 as 1 is passed in thepvParameters 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;
}

3.2、测速跑分

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

3.3、跑分结果

Debug模式下 coremark为1.18CoreMark/MHz,Release模式下1.75CoreMark/MHz,Debug和Release编译模式运行速度有一定的差距。

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...