endless · 2021年12月28日

【XR806开发板试用】简单移植coremark并测试实际跑分

前言

首先,拿到板子的时候,由于xr806它是个IOT的片子,所以自然而然必然,在预想里就会有很多大佬会把文章出发点考虑在wifi/bt,各种物联网/WEB应用上。那么怎么另辟蹊径回避这个热点又体现出XR806的特色呢,于是就有了写这篇文章的初衷——让我们从最简单的角度,实际看看ARM最新的v8架构的STAR核的跑分情况究竟如何:)

coremark这里就不做过多介绍了,这里指的是coremark的开源跑分软件,不同于其他基于linux的跑分软件,coremark的源码相对来说比较简单,非常易于MCU使用。需要了解详情的小伙伴请移步官网仔细查看,官网链接如下:

"download"页可以看github的下载链接。

"scores"页可以看到各种片子的跑分情况,小伙伴们在这里可以看到你们平时最熟悉的那些大厂的片子的实际官测分数(XR806的对手就是各种大厂牌子的MCU了)。

本次我们的对手就暂定为同为ARMv8架构的M33核芯片,没错,说的就是你——ST的stm32L552(这是ST最新的M33核的MCU,当然,这里提到它的主要原因是我手头也只有这一块demo板~~~~做对比:))。

准备

下载和编译环境配置这里不再累述,小伙伴们可以参照官方文档,做好鸿蒙源码下载同步,这里只是稍微单独说明两点:

1)为了省事务必使用ubuntu来搭建编译环境,目前在windows下用vscode搭建的过程尚未给全,此坑务趟,除非之前有鸿蒙开发的经验

2)官网有个别地方有路径字符编辑错误(此时不确定是否已更新),如果遇到问题可以参考其他小伙伴们关于环境搭建的试用文章

修改源码

先进入"device\xradio\xr806\ohosdemo\BUILD.gn",新增coremark的测试demo:

group("ohosdemo") {
    deps = [
        "core_mark_test:app_core_mark",
        #"hello_demo:app_hello",
        #"iot_peripheral:app_peripheral",
        #"wlan_demo:app_WlanTest",
    ]
}

然后我们在"ohosdemo"目录下,添加两个目录"include"、"src",把下载的coremark源码.c/.h分别放进去。

在"ohosdemo\core_mark_test"目录下建立一个BUILD.gn(从其他demo的文件夹下复制一个过来,修改其内容),内容如下:

import("//device/xradio/xr806/liteos_m/config.gni")

static_library("app_core_mark") {
   configs = []

   sources = [
      "src/main.c",
      "src/core_list_join.c",
      "src/core_main.c",
      "src/core_matrix.c",
      "src/core_portme.c",
      "src/core_state.c",
      "src/core_util.c",
   ]

   cflags = board_cflags

   include_dirs = board_include_dirs
   include_dirs += [
      "//kernel/liteos_m/kernel/arch/include",
      "include",
   ]
}

整个demo的源码目录结构如下:

.
├── BUILD.gn
├── core_mark_test
│   ├── BUILD.gn
│   └── src
│   |   ├── main.c
|   |   ├── core_list_join.c
|   |   ├── core_main.c
|   |   ├── core_matrix.c
|   |   ├── core_portme.c
|   |   ├── core_state.c
|   |   └── core_util.c
|   └── include
│       ├── core_main.h
│       ├── core_portme.h
│       ├── coremark.h
├── hello_demo
├── iot_peripheral
└── wlan_demo

然后来正式修改程序:

1)core_portme.h,修改如下:

/* Topic : Description
    This file contains configuration constants required to execute on different platforms
*/
#ifndef CORE_PORTME_H
#define CORE_PORTME_H

#define ITERATIONS 5000//COREMARK_ITERATIONS

修改ITERATIONS为固定5000次计算迭代,大约执行约十几秒的时间(coremark有要求至少运行超过10秒,这个值可以根据CPU的频率填入适当的值)。

2)core_portme.c,修改如下:

/* 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 1000                                //时间戳直接改成1000次/秒
#define CORETIMETYPE unsigned long  
#define GETMYTIME(_t) (*_t=LOS_TickCountGet())            //获取时间戳的函数改为鸿蒙的系统api LOS_TickCountGet()
#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
#define TIMER_RES_DIVIDER 1
#define SAMPLE_TIME_IMPLEMENTATION 1
#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)

由于用到了LOS_TickCountGet(),所以core_portme.c的文件头需要加上两个头文件:

#include <stdio.h>
#include <stdlib.h>
#include "ohos_init.h"        //新增
#include "kernel/os/os.h"    //新增
#include "coremark.h"

3)main.c修改如下:

#include <stdio.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "core_main.h"

static OS_Thread_t g_main_thread;

static void MainThread(void *arg)
{
    printf("coremark test start..\n");
    LOS_Msleep(2000);
    printf("3..\n");
    LOS_Msleep(1000);
    printf("2..\n");
    LOS_Msleep(1000);
    printf("1..\n");
    LOS_Msleep(1000);
    core_mark();
    while (1) {
        LOS_Msleep(500);
    }
}

void CoremarkMain(void)
{
    printf("Coremark Test Start\n");

    if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
                OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
        printf("[ERR] Create MainThread Failed\n");
    }
}

SYS_RUN(CoremarkMain);

运行与调试

编译,运行,第一次得到的结果如下:

第一次测试.png
312分,非常不理想,这个分数甚至不如stm32L552。原因初步分析了下,要么是cache没开,要么是编译优化等级不够。查了一下,也许需要强制指定-O3的编译优化来发挥效果。

修改方式如下:

打开项目目录下的device/xradio/xr806/liteos_m/config.gni文件(此文件用于设备商的编译配置):

# Board related common compile flags.
board_cflags = []
board_cflags += SDK_cflags
board_cflags += [
    "-includelog/log.h",
    "-DVIRTUAL_HCI",
    "-DCONFIG_ARM",
    #"-DNULL=((void*)0)",
    "-std=gnu99",
    "-O3",
]

增加最后一个编译选项 "-O3"。

然后重新编译,跑分结果如下:
第二次测试.png
好了,454分,比STM32L552的实际跑分还要高一点点(它的实测跑分384)。优化之后跑分提高了50%!其实对于某些其他芯片来说,优化等级提高甚至可以达到跑分翻倍的效果。

不过此分数和coremark官方跑分(其他同级芯片对比)从频率比上比还是不太理想,目前没有其他原因的想法,待后续再查验吧。

不过不管怎么样,确实压了STM32L552的M33一头(虽然它只有110M):)

各位小伙伴也可以尝试一下对coremark做小小的移植,在自己喜爱的各种MCU上做做跑分对比。

推荐阅读
关注数
13823
内容数
139
全志XR806开发板相关的知识介绍以及应用专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息