关于GD32与STM32芯片数据运算速度--除法移位

关于GD32与STM32芯片数据运算速度

1.芯片时钟作用下:

  • 1000个定点数的运算

    速度太快,未测出有效结果

  • 10000个定点数的运算

芯片乘法除法
GD32测不到1ms
STM322ms2ms
  • 100000个定点数的运算
芯片乘法除法
GD329ms11ms
STM3224ms24ms

2.DSP库作用下

  • 100000个定点数的运算
芯片乘法备注
GD324ms内部集成DSP功能、FPU浮点运算功能
STM3224ms

3.定点DSP除法运算

库函数未提供除法函数,需做一些转换

方法:

  1. 将除法转换乘法与移位(乘以 / 除以2的n次方)
  • 乘法:c = a*4 =》 c = a<<2;
  • 除法:c = b/4 =》 c = b>>2;
  1. 将除法转换乘法与移位(不乘以 / 除以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){

	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值