本帖最后由 RISCVLAR 于 2021-9-15 11:38 编辑
CH32V103和CH32V307 CoreMark跑分测试
关于CH32V103的CoreMark的跑分测试,之前在本版块很多网友已经发过测试帖子,本人本贴也是在此基础上参考进行,对V103和V307进行一次测试。
1、CoreMark基本介绍 CoreMark以每秒迭代次数作为性能评价。关于迭代,迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。 CoreMark是衡量嵌入式系统中微控制器性能的基准。通过包含列表处理(查找和排序)、矩阵处理(常见的矩阵操作)、状态机(确定输入流是否包含有效数字)和CRC(循环冗余校验)等算法的测试给出性能评价。
2、运行CoreMark所需条件 运行CoreMark,需要定时器提供计时功能,还需要一种向外部打印消息的手段。一个比较简单的方法是,调用stdio.h中定义的printf()函数,将其重定向到串口。关于计时功能,此处测试时使用SysTick提供计时功能。
3、移植所需注意事项 关于CoreMark文件移植,可见附件具体程序。需要注意的是:由于core_main.c文件已定义了main()函数,该main()函数执行时调用core_portme.c中的portable_init()函数作为MCU初始化接口,因此需要将工程中原main.c文件MCU初始化代码移动到到portable_init()函数里并删除或者注释掉原有main.c文件。 此外,在core_portme.c文件中,还需要注意以下几个地方: #define EE_TICKS_PER_SEC 1000
此处定义每秒1000个Tick,每个Tick时长1ms,对应定时器每1ms触发一次中断。使用一个计数变量,定时器进入中断一次,该变量值+1;对该变量值/1000即可求得定时器运行时长,也就是上文的Sec。所以EE_TICKS_PER_SEC并非一定要设置为1000,和定时器中断频率对应即可。 与定时相关的函数有以下三个: void start_time(void);//启动计时器;
void stop_time(void);//停止计时器;
CORE_TICKS get_time(void);//获取计时器的计数值。
在start_time()里实现定时器启动功能,在stop_time()里实现定时器停止功能,在get_time()中获取中断计数值。数据类型“CORE_TICKS ”实际上就是“unsigned long”。为方便操作,推荐将计数变量设置为全局变量,这样可以通过extern关键字直接访问。关于以上三个函数的具体内容,可以参考程序。 此外,还需要注释掉不用的代码,如下: //#define NSECS_PER_SEC CLOCKS_PER_SEC
//#define CORETIMETYPE clock_t
//#define GETMYTIME(_t) (*_t = clock())
//#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
//#define TIMER_RES_DIVIDER 1
//#define SAMPLE_TIME_IMPLEMENTATION 1
为获得有效的测试结果,需修改core_portme.c中关于ITERATIONS的设置,官方代码中ITERATIONS没有定义: volatile ee_s32 seed4_volatile = ITERATIONS;
关于ITERATIONS的值,MCU主频不同,设置的值也不同,V103主频最高为80MHz,程序中设置值为2000 volatile ee_s32 seed4_volatile = 2000
V307主频最高为144MHz,程序中设置值为4000 volatile ee_s32 seed4_volatile = 4000
注意,该值如果设置过低,会报错,如下 打印测试结果时,编译器优化等级和调试等级也可以打印出来。这类信息可在core_portme.h中通过宏COMPILER_FLAGS修改。此处使用-Ofast优化,调试等级-g3,修改如下: #ifndef COMPILER_FLAGS
//#define COMPILER_FLAGS "-g -O3 -Otime" /* "Please put compiler flags here (e.g. -o3)" */
#define COMPILER_FLAGS "-Ofast -g3"
#endif
4、CH32V103和CH32V307 CoreMark跑分 跑分结果如下: CH32V103: CH32V307:
|