关于GD32与STM32芯片数据运算速度
1.芯片时钟作用下:
-
1000个定点数的运算
速度太快,未测出有效结果
-
10000个定点数的运算
芯片 | 乘法 | 除法 |
---|---|---|
GD32 | 测不到 | 1ms |
STM32 | 2ms | 2ms |
- 100000个定点数的运算
芯片 | 乘法 | 除法 |
---|---|---|
GD32 | 9ms | 11ms |
STM32 | 24ms | 24ms |
2.DSP库作用下
- 100000个定点数的运算
芯片 | 乘法 | 备注 |
---|---|---|
GD32 | 4ms | 内部集成DSP功能、FPU浮点运算功能 |
STM32 | 24ms |
3.定点DSP除法运算
库函数未提供除法函数,需做一些转换
方法:
- 将除法转换乘法与移位(乘以 / 除以2的n次方)
- 乘法:c = a*4 =》 c = a<<2;
- 除法:c = b/4 =》 c = b>>2;
- 将除法转换乘法与移位(不乘以 / 除以2的n次方)
- 乘法:c = a*9 =》 c = (a<<3)+a;
- 除法:c = b/7 =》 c =b/(8-1) - a ;
移位所用DSP库函数
void arm_shift_q31(q31_t * pSrc,int8_t shiftBits,q31_t * pDst,uint32_t blockSize)
3.移位除法
除法则可以视为乘法的逆运算。对于二进制来说,从高到低的每一位,将除数提升到当前位的权值(即,乘以2^k,等同于左移k位),如果此时被除数扔大于除数,就说明结果在这个位上商1。然后从被除数减掉除数提升后的值。遍历每一位,即为最终的结果。
除法就是移位相减
99用2进制是 1100011
5是101先1100011 - 1010000 = 10011(其中二进制1010000 = 5乘2的4次幂)
再10011 - 1010 = 1001 ( 其中二进制1010 = 5乘2的1次幂)
再1001 - 101 = 100( 其中二进制101 = 5乘2的0次幂)最后得到商为24+21+2^0 = 16+2+1=19
余数为二进制100 = 4
/*!
\brief division operation
\param[in] y:被除数
x:除数
\param[out] merchant:商
\retval none
*/
int divi( int y,int x)
{
int i=0;
int remain = 0;//余数
while(y>x)//向左移位到x>=y
{
arm_shift_q31(&x,1,&x,1);
++i; //记录左移的次数
}
arm_shift_q31(&x,-1,&x,1); //使x<=y
--i;
while(i >= 0)
{
if(y >= x)
{
merchant += 1<<i;
y -= x;
}
arm_shift_q31(&x,-1,&x,1);
--i;
remain = y;
}
return merchant;
}
4.测试程序
#include "gd32f30x.h"
#include "systick.h"
#include "test.h"
uint32_t tick;
/*!
\brief strat time
\param[in] none
\param[out] none
\retval none
*/
void start_time(void) {
tick = 0;
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 1000U)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
/*!
\brief stop time
\param[in] none
\param[out] none
\retval none
*/
void stop_time(void) {
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
/*!
\brief get time
\param[in] none
\param[out] none
\retval none
*/
uint32_t elapsed;
uint32_t get_time(void) {
elapsed = (uint32_t)tick;
return elapsed;
}
/*!
\brief this function handles SysTick exception
\param[in] none
\param[out] none
\retval none
*/
void SysTick_Handler(void)
{
delay_decrement();
++tick;
}
主函数
int main(void)
{
int i = 0;
q31_t pSrcA = 2;
q31_t pSrcB = i++;
start_time();
/* the multiply operation */
arm_mult_q31(&pSrcA,&pSrcB,pDst,100000);
stop_time();
value = get_time();
while (1){
}
}