请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G474芯片使用SIMD指令做乘加运算的问题

[复制链接]
仲裁者 提问时间:2021-12-7 09:45 / 已解决

大家好,我现在想测试一下SIMD指令执行16bit加法和乘法是否会比直接写加法和乘法更快

我的代码截图如下(16bit加法)

代码.PNG

用的是SADD16()指令(我不知道是否是我调用的指令不对),执行下来,直接加法运算的执行时间是23us,而使用了SADD16()指令做加法的时间为27us,比直接计算慢了。

请问这个是怎么回事,是否是我哪里没搞对

收藏 评论9 发布时间:2021-12-7 09:45

举报

9个回答
yr 最优答案 回答时间:2021-12-8 22:41:31

仲裁者 发表于 2021-12-8 16:49
你好,我知道为什么我测试的结果是差不多快慢了</p>
<p>__ASM volatile ("uadd16 %0, %1, %2" : "=r" (*(uint32 ...

固件包的CMSIS目录下docs->index.html-> cortex-M->reference->Intrinsic functions for SIMD instructions

yr 回答时间:2021-12-7 11:17:29

根据你的描述和注释来看,SIMD的指令你可能用法错了,应该传入2个32的数,高半字和低半字分别是要平行加法的两个数,这样结果也是32位,我觉得是快一倍。具体你参照说明。

uint32_t __SADD16 ( uint32_t val1 ,
uint32_t val2
)

This function enables you to perform two 16-bit signed integer additions. The GE bits in the APSR are set according to the results of the additions.

Parameters| val1 | first two 16-bit summands. | | ------ | ----------------------------- | | val2 | second two 16-bit summands. |

Returns* the addition of the low halfwords in the low halfword of the return value.

  • the addition of the high halfwords in the high halfword of the return value.

Each bit in APSR.GE is set or cleared for each byte in the return value, depending on the results of the operation.If res is the return value, then:* if res[15:0] >= 0 then APSR.GE[1:0] = 11 else 00

  • if res[31:16] >= 0 then APSR.GE[3:2] = 11 else 00

Operation:res[15:0] = val1[15:0] + val2[15:0]

res[31:16] = val1[31:16] + val2[31:16]

仲裁者 回答时间:2021-12-7 14:24:27
yr 发表于 2021-12-7 11:17
根据你的描述和注释来看,SIMD的指令你可能用法错了,应该传入2个32的数,高半字和低半字分别是要平行 ...


[md]你好,我看了你的回复后,认为一个UADD16指令相当于进行了两次16bit加法,参数1的低16bit+参数2的低16bit以及参数1的高16bit+参数2的高16bit,最终两者的和放在返回值得低16bit和高16bit。

按照我的理解,我写了如下的测试代码:

1.用UADD16指令进行一次加法

__ASM volatile ("uadd16 %0, %1, %2" : "=r" (*(uint32_t*)(uiRes+0)) : "r" (((uint32_t)uiCal1[1]<<16)+uiCal1[0]), "r" (((uint32_t)uiCal2[1]<<16)+uiCal2[0]));

2.直接进行两次加法
uiRes[0]=uiCal1[0]+uiCal2[0];
uiRes[1]=uiCal1[1]+uiCal2[1];

两种代码的执行结果是一样的,测试了执行时间也是相同的,都是996ns,那岂不是执行速度是一样的吗?我哪里理解错误了吗?
yr 回答时间:2021-12-7 15:38:44

仲裁者 发表于 2021-12-7 14:24
你好,我看了你的回复后,认为一个UADD16指令相当于进行了两次16bit加法,参数1的低16bit+参数2的低1 ...

[md]你的理解没错。但是两者还是有区别,用UADD16指令的话,内核一次读入2个数据,一次32位加完成2个16位加,然后再返回到存储器。如果用两次加法,要读4次,加2次,写回2次,这样从总时间上看是要更耗时,可以从反汇编看出指令的区别。我觉得要测试的话,需要循环多次,如果是UADD16的话,循环次数应该减半。如果是乘加指令,是_SMLAD,这个比较明显。

仲裁者 回答时间:2021-12-7 16:28:57

yr 发表于 2021-12-7 15:38
你的理解没错。但是两者还是有区别,用UADD16指令的话,内核一次读入2个数据,一次32位加完成2个16位 ...

[md]你好,我试了一下100次for循环加法,UADD16确实只循环50次就算完了,但对比两种计算方法,UADD16只比直接运算快了2us,优势不是很明显

yr 回答时间:2021-12-8 10:18:36

仲裁者 发表于 2021-12-7 16:28
你好,我试了一下100次for循环加法,UADD16确实只循环50次就算完了,但对比两种计算方法,UADD16只比 ...

[md]其实不然,SIMD指令,一条指令相当于普通指令的2倍,时间开销也约节省一半

image.png

仲裁者 回答时间:2021-12-8 16:46:27
你好,我知道为什么我测试的结果是差不多快慢了

__ASM volatile ("uadd16 %0, %1, %2" : "=r" (*(uint32_t*)(uiRes+i)) : "r" (((uint32_t)uiCal1[i+1]<<16)+uiCal1), "r" (((uint32_t)uiCal2[i+1]<<16)+uiCal2));

因为我传给UADD16的参数本身就是个加法运算。。。

另外,你之前发的SIMD指令说明文档的链接能发我一下吗?我想看一下乘加的复合运算,SIMD指令怎么用,谢谢了
仲裁者 回答时间:2021-12-8 16:49:40
yr 发表于 2021-12-8 10:18
[md]其实不然,SIMD指令,一条指令相当于普通指令的2倍,时间开销也约节省一半

!(data/attachment/forum ...

你好,我知道为什么我测试的结果是差不多快慢了

__ASM volatile ("uadd16 %0, %1, %2" : "=r" (*(uint32_t*)(uiRes+i)) : "r" (((uint32_t)uiCal1[i+1]<<16)+uiCal1), "r" (((uint32_t)uiCal2[i+1]<<16)+uiCal2));

因为我传给UADD16的参数本身就是个加法运算。。。

另外,你之前发的SIMD指令说明文档的链接能发我一下吗?我想看一下乘加的复合运算,SIMD指令怎么用,谢谢了

仲裁者 回答时间:2021-12-9 08:46:48

yr 发表于 2021-12-8 22:41
固件包的CMSIS目录下docs-&gt;index.html-&gt; cortex-M-&gt;reference-&gt;Intrinsic functions for SIMD instru ...

[md]感谢

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版