【MCXN947开发板测评】Coremark内核测试
本帖最后由 ew2024 于 2025-1-8 06:16 编辑这里写一下关于MCXN947的Coremark测试的一些过程分享。中间遇到一些离谱的事,后边一条一条说。
# Coremark介绍
可能有人对Coremark了解不多,这里大概介绍一下。
CoreMark是处理器的性能基准测试,由嵌入式微处理器基准测试联盟(EEMBC)在2009年开发,为了取代过时且有争议的Dhrystone标准。软件使用C语言编写,是一个免费使用,易于移植的基准测试程序。目前CoreMark已经成为测量与比较各类处理器性能的业界标准基准测试。CoreMark得分越高,意味着性能更高。Coremark包含了一系列算法:列表操作(查找和排序)、常用的矩阵运算、状态机以及CRC,这样做的目的据说是为了克服Dhrystone过于依赖libc库的缺点。这里是(https://www.eembc.org/coremark/)地址,里边有源码下载、相关介绍以及Coremark相对Dhrysone做了哪些改进,感兴趣的可以看一看。
# 移植Coremark
虽然是源码给出,但是是不能直接使用的,需要我们对源码进行一定的改动才能进行测试,总的来说,有两个部分需要改
1. 对printf进行处理支持
2. 提供一个对应平台的准确时间测量方式
有两种测量方式,一种是进行源码移植测试,一种是使用keil测试,下边将围绕源码移植进行展开,keil测试的大家可以查询*perf_counter*这个包,他已经内置了Coremark测试,安装好后在RTE中就可以找到使用。
移植Coremark,实际上就是处理以下这6个文件和simple中的portme的两个文件,重点在simple中的文件。
## core_portme.h
首先看core_portme.h文件,开头有段代码是判断是否所使用的平台支持printf。在CoreMark中,最终的结果需要使用printf格式化输出函数打印出来,如果MCU软件平台不能使printf函数,则需要一些其他方式,自己实现或者使用barebones文件夹的一些方法(ee_printf.c与cvt.c文件)。如果平台提供有printf格式化输出函数,则确保core_portme.h中的**HAS_PRINTF宏为1**。
```c+++
#ifndef HAS_PRINTF
#define HAS_PRINTF 1
#endif
```
然后定义`ITERATIONS`变量的大小,这个是后续测试迭代次数,因为Coremark有个规定,小于10s的将不进行测试,初次定可以定小一点,不行再调大,否则运行时间太长。我是这样定义的
```c++
#define ITERATIONS 500000
```
接下来修改编译信息的部分,其实这部分修改对于运行没有什么帮助,只是最后得到结果时候进行展示的。
要注意看一下这部分的代码,主函数是否有参数以及返回值的宏,这有关后续Coremark的主函数的定义。
## core_portme.c
在core_portme.c中,进行定义,便于后续的时间的处理。
```c++
extern uint32_t systick_count;
```
时间的处理有多种方式,比较简单的就是对源码进行修改,不需要自己实现。
我们主要修改的是这段的前三行代码。重点在第三行,这个是获得时间的部分,关系到计时。这个定义好了, 后续的start_time/stop_time/get_time就都可以正常运行了。
## core_main.c
由于这个是被调用函数,就需要把这个的主函数名字改掉,改为Coremark_main这样类似的即可,防止多个main出现。
这里提醒一下,移植过来的8个文件中需要打印信息的部分,换行符为`\r`,这是Linux环境下的,这样使用会信息连在一起不方便看,统一替换为`\r\n`
## coremark.h
这个文件里边加入Coremark_main的声明,便于在主函数中调用。为了更健壮一点,可以这样
```c++
#if MAIN_HAS_NOARGC
MAIN_RETURN_TYPE
coremark_main(void);
#else
MAIN_RETURN_TYPE
coremark_main(int argc, char *argv[]);
#endif
```
在这里我们要修printf函数,把ee_printf代指的换为本平台所提供的printf函数。
```c++
#if HAS_PRINTF
#define ee_printf PRINTF
#endif
```
## main.c
主函数中加入Coremark.h,然后添加以下代码,实现计时功能
```c++
uint32_t systick_count = 0;
void SysTick_Handler(void)
{
systick_count++;
}
void SysTick_Init(void)
{
/* Stop and clear the SysTick. */
SysTick->CTRL = 0UL;
/*Configure SysTick to interrupt at the requested rate. */
NVIC_SetPriority (SysTick_IRQn, (1UL <<__NVIC_PRIO_BITS)- 1UL), /* set Priority for systick Interrupt */
SysTick->LOAD =( SystemCoreClock / 1000)- 1UL; /* set reload register */
SysTick->VAL = 0UL;
/* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
/* Enable sysTick IRQ and SysTick Timer */
}
```
接着在main函数中调用即可。
# 问题
## IDE
可以通过上边的图看到,我使用的不是keil。我这里使用的是官方的MCUXpresso IDE,这和我之前发的帖子不一样。这是因为,我在keil做完上述的配置之后,代码怎么都没有办法成功运行。
可以看到,在这个图中,函数上下我均放置了输出,用来看代码运行,在注释掉Coremark_main函数时候,能够正常输出两个hello world,解注释后,最开始什么都没有输出,Debug模式单步调试看到进入Coremark_main函数中后就无法继续运行了,系统不知道为什么处于卡死状态,在Coremark_main入口处加入字符输出也没有输出。这个问题困扰我很久也解决不了。
我忽然有个念头,就是再次尝试下载官方IDE,虽然之前反复下载十几次都没办法正常运行,但是我就是有个想法想再试试。安装完成后,意外的是没有发生之前的报错,能够正常连接板子并下载。然后我把代码复制到这边打开,就能够运行出结果了。我感觉我的电脑有点太bug了,以至于以前出现的各种问题我怀疑并不是厂家的问题,而是我这边的问题(-_-)。
## 输出函数
换到官方IDE时候,最开始得到的结果并不是正常的,而是没有结果
而正常的应该是这样的
可以看到应该输出数值的地方,并没有数字,而是奇怪的字符以及空白。我们可以看下源代码
可以看到,数字部分是由于格式化输出导致的,`lu`是长无符号整形,但是在IDE中被标记了,说明是无法识别的,但是这是长见的表示,我初步怀疑是语言标准的问题,因此编译时候使用GNU99/GUN11/C99/C11都尝试过,结果均无法识别。然后我怀疑是这个格式化无法识别,参照这个[帖子](https://stackoverflow.org.cn/questions/2844),使用了`%I64d`以及`#include <inttypes.h>`中的`PRIu32` 都无法正常,接着尝试了其他的一些符号。
这时候我怀疑是平台所实现的PRINTF有问题,查(https://mcuxpresso.nxp.com/api_doc/dev/116/group__debugconsole.html)可以看到,是厂家并没有定义。
。
但是又一个问题有了,`lu`没有定义的话,那为什么`f`输出是空呢,这个明明是定义过的。
我对符号进行了修改,`f/F`,强制类型转换`float/double`都试过了
结果还是不行,我又做了下测试,正如下边的图所示,果然是无法输出正确的值的,而不是程序中间运算什么出现了问题。
为了能有个正常的输出,我就直接将`f`修改为了`d`,保留整数部分做个参考即可。于是得到了最终结果。这个是O3优化,得分446
我后续又测了几组。分别是O0优化(不优化 ),得分98
O1优化,得分329
由于IDE中没有-Ofast选项,大家可以参考这个博主所说的进行设置。[-Ofast设置](https://www.cnblogs.com/henjay724/p/16626201.html)可以看到,并没有多少改变。
|优化方式|得分|
| :---: | :---: |
| O0|98 |
| O1|329|
| O3|446|
| Ofast|446|
我还尝试O3基础上打开LTO,但是奇怪的是,显示运行时长太短,不进行测试,我将迭代次数提高10倍,依然不行,提高100倍,还是提示时间较短,但是实际上等待输出的时间并不短,而且我不认为加入这一个优化能够提高上百倍的速度,所以我觉得可能是运行时候又发生什么问题了,导致无法正常运行,后续有机会的话我再研究下是因为什么。
# 建议
1. 第一点就是建议官方检查一下PRINTF的问题,由于我的电脑的问题,我不是很确定是否是库的问题还是我这边的问题,浮点数是否能正常输出,同时建议在PRINTF的格式化字符中增加对长度的支持。
2. 第二点是,官方IDE做的确实不错,功能齐全,但是使用时候有个问题,在下载代码时候,点击调试下载以及运行按钮,出现的界面不能长时间保持,如果在这个状态待得时间太长,在关闭Debug模式时候,IDE可能会卡住,甚至无法响应,得关闭软件重新启动才可以正常。这种无法响应是概率产生的,我使用时候,感觉到某段时间发生概率很高,经常要重启,某段时间时候又不需要重启,可以正常关闭,这个情况比较影响使用体验。
3. 还有一个问题是,能否改变括号的高亮,IDE中的配对的括号是只有一个线框包围,不便于查看,希望能对颜色什么进行高亮支持,比如高亮标注所选括号的另一半括号位置,或者类似vscode中Rainbow Brackets插件一样。 <p>给刚接触官方IDE的伙伴提醒一下,光把新文件加入到项目/include文件夹中是不够的,还需要在项目设置中添加,具体可以参照这个https://community.nxp.com/t5/MCUXpresso-IDE/Undefined-reference-problem/m-p/965603</p>
页:
[1]