C++ 有没有比pmullw更有效地使用pmaddubsw进行无符号乘?

C++ 有没有比pmullw更有效地使用pmaddubsw进行无符号乘?,c++,assembly,simd,webassembly,C++,Assembly,Simd,Webassembly,是一条有趣的指令,因为它执行无符号乘有符号乘法。这在实践中意味着,操作数的顺序很重要,如果您尝试将无符号值乘以值大于127的有符号值,那么最终的位表示形式将得到意想不到的结果 我对此很感兴趣,因为我建议为WebAssembly SIMD指令集扩展(8位到16位)水平乘法加法指令 然后我想做的是确定针对AVX的x86_64指令的理想实现。如果我能在1-op中使用pmaddubsw,它将比使用pmullw、pand、psrlw所需的7-op解决方案更理想。但由于无符号乘的限制,我不确定是否有可能在1

是一条有趣的指令,因为它执行无符号乘有符号乘法。这在实践中意味着,操作数的顺序很重要,如果您尝试将无符号值乘以值大于127的有符号值,那么最终的位表示形式将得到意想不到的结果

我对此很感兴趣,因为我建议为WebAssembly SIMD指令集扩展(8位到16位)水平乘法加法指令

然后我想做的是确定针对AVX的x86_64指令的理想实现。如果我能在1-op中使用pmaddubsw,它将比使用pmullw、pand、psrlw所需的7-op解决方案更理想。但由于无符号乘的限制,我不确定是否有可能在1-op中得到无符号结果,或者至少得到比pmullw、pand、psrlw更好的解决方案

我想出的唯一符合行为的方法是屏蔽、移位和调用pmaddubsw两次,这会产生相同数量的指令,而不一定是更优的解决方案

你可以在电视上看到这两个


旁注:有人有不同的任务,但这个问题的目标相似--

只是为了澄清:您想要与
pmadubsw
相同的行为,只需要两个未签名的输入?(即,水平添加两个产品和饱和度——在本例中为
[0,0xffff]
)。我认为这是可以接受的。不管有没有饱和,饱和就是扼杀这个想法的原因。将有符号/无符号乘法转换为无符号/无符号乘法非常简单,只需添加
((有符号>>8)和无符号)如果调用两次,则饱和不起作用,对吗?在Intel UARCH上,分别计算最高位乘法的代码使用的长延迟乘法指令数与使用代码的
vpmullw
相同,并且总共使用的指令数相同。我希望它有类似的吞吐量,但它的延迟更差,因为它的依赖关系树更深。您可以尝试将
vpmaddubsw
中的一个替换为
,将
替换为字节与零比较的结果,因为它只有一个输入位,避免了昂贵的多行指令,但使用了更多的移位指令。