【发布时间】:2017-07-20 03:21:02
【问题描述】:
我在做 8bit 定点工作,我有 A 数组和 B 数组都是 Q7 格式,我想得到它们的和积。 演示代码:
int8_t ra1[], ra2[], rb[];
int8x16_t va1, va2, vb;
int16x4_t vsum1, vsum2;
va1 = vld1q_s8(ra1);
va2 = vld1q_s8(ra2);
vb = vld1q_s8(rb);
vsum1 = vdup_n_s16(0);
vsum2 = vdup_n_s16(0);
for (......)
vsum1 = vmlal_s8(vsum1, vget_high_s8(va1), vget_high_s8(vb));
vsum1 = vmlal_s8(vsum1, vget_low_s8(va1), vget_low_s8(vb));
总和+=a * b;这个和是16bit,很容易溢出,因为a*b是Q7×Q7 16bit可以代表Q15。另外,我不能右移Q7xQ7的结果,我需要保持高精度。 我如何使用 neon,我想要 sum 是 32bit a,b 仍然是 8bit。我不想将 a 和 b 传输到 16bit 并使用 vmlal_s16,它会很慢。我只需要一个可以做乘法和加法的指令一个指令时间。 neon c 内部函数没有这个功能,也许 neon 汇编代码可以做到这一点。谁能帮帮我?谢谢。 Here 是 vmla 汇编代码信息。也许我可以使用它。请给一些建议,我不熟悉汇编代码。
【问题讨论】:
-
你确定在乘法之前将
a和b转换为16 位很慢(即你有没有测试过这个)? AFAIR,至少一些 NEON 实现需要两倍的时间来执行8 bit x 8 bit向量乘法作为16 bit x 16 bit向量乘法,因为它们在硬件中有 16 位乘法器。在这种情况下,这意味着在乘法之前扩大实际上不会增加任何成本。