在线时间514 小时
UID2025756
注册时间2013-7-16
NXP金币0
该用户从未签到
金牌会员
- 积分
- 9267
- 最后登录
- 1970-1-1
|
【经验分享】KE02单条乘法指令为一个周期的测试方法讲解
一,问题描述
前不久,在我们飞思卡尔的外部坛子有几位网友提出我们Coretex M0+内核芯片的乘法指令运行周期的问题。通过cortex M0+内核相关文档,我们知道乘法指令MULS Rd, Rm, Rd 占用的机器周期是1或者是32,那么到底是1还是32呢?网友为了验证,就采用KE02作为平台自己测试了,很多人都是采用在乘法指令前后翻转IO的方式,然后通过示波器去测试IO之间的时间来确定乘法指令的运行时间,这样测下来,时间还是比较长的,有些网友甚至测出来有好几个us,甚至十几个us,这么长的时间对于20M的主频(一个机器周期只有0.05us)来说真是长的有些不可思议。那么到底是什么原因导致测试结果这么长呢,IO口翻转的方法测试单指令的乘法指令靠谱吗?答案是No。
为什么不行呢?因为测试的时候如果使用IO翻转,本身IO翻转就占用一定的机器周期,另外对于C语言写的乘法指令,比如如下定义:
uint32_t test1, test2;
uint32_t result;
test1=0x11;
test2=0x22;
result= test1*test2;
result= test1*test2;对应的汇编并不只是一条乘法指令,而是包含了取值到test1,test2,然后在做乘法,最后还要将乘法指令放到result中去(请查看图1),其实这些取值,存储指令占用的机器周期还是比较长的,通过手册可知是2个机器周期,而如果乘法指令只有1个机器周期,这样测试明显是不正确的。
图1
可能还有人想,那么如果我直接用result= 0x11*0x22;这样是否就能比较快的测试乘法指令呢?这个也是不可以的,因为如果这样做,编译器会先把0x11*0x22计算好后放在一个地方,然后运行到这句乘法语句的时候,直接掉值,大家如果查看它对应的汇编语句,是看不到muls这条指令的,只有一些取值存值的过程,如图2。
图2
那么究竟怎样测试才能准确的测出单条muls的运行时间呢?下面章节2将详细讲解。
二,测试方法讲解
大家从上面的图1可以看到,其实一条C的乘法指令对应了包含乘法指令muls,LDR,STR等多条指令,如何才能准确测试呢?
我们可以使用芯片的systick来测试,因为systick的counter是可以配置为core clock(CLKSOURCE=1)或者core clock/16(CLKSOURCE=0)的,如果我们选择counter为core clock,而运行指令的机器周期也是按照core时钟来的,所以就能比较准确的测试单条指令的运行时间。另外,在我们KE02的驱动库中,是有关于systick的驱动代码的,如果大家使用的是KL系列,相关例程中也是有systick的驱动的,测试方法类同。
具体的测试思想就是,初始化好systick后,在result= test1*test2;前面使能读取当前的systick值,并且存起来,运行完乘法语句之后再次读当前的systick值,然后再存起来,紧接着做一个减法,就知道乘法语句result= test1*test2;和第二次取systick值一共运行了多少个内核时钟,最后再减去减去乘法语句中除了乘法指令之外的语句以及第二次取systick值的时间,就是我们需要的muls指令的时间。
下面再结合测试结果讲解。
|
|