vdsp提供了三种不同的方式进行fract16的乘法运算。
1.1 mult_fr1x16函数
这个函数定义为:
#pragma inline
#pragma always_inline
static fract16 mult_fr1x16(fract16 __a, fract16 __b) {
fract16 __rval = __builtin_mult_fr1x16(__a, __b);
return __rval;
}
从这里可以看出我们实际可以使用__builtin_mult_fr1x16这一函数调用。
写一个很简单的程序:
typedef fract16 ft;
ft calc(ft x, ft y)
{
ft r;
r = __builtin_mult_fr1x16(x, y);
return r;
}
__builtin_mult_fr1x16展开后的汇编代码为:
// line 29
R0.L = R0.L * R1.L (T);
R0 = R0.L (X);
W[FP + 16] = R0;
因而完成这样一个运算将只需要一个cycle的时间。
这里的乘法运算使用了(T)尾缀,文档里这样解释:
Signed fraction with truncation. Truncate Accumulator 9.31 format value at bit 16. (Perform no rounding.) Saturate the result to 1.15 precision in destination register half. Result is between minimum -1 and maximum 1-2-15 (or, expressed in hex, between minimum 0x8000 and maximum 0x7FFF).
这种计算方式直接将累加器里的数进行截断而不进行任何舍入的处理。
1.2 multr_fr1x16
这个函数定义为:
/* Performs a 16-bit fractional multiplication of the two input
** parameters. The result is rounded to 16 bits. Whether the
** rounding is biased or unbiased depends what the RND_MOD bit
** in the ASTAT register is set to.
*/
#pragma inline
#pragma always_inline
static fract16 multr_fr1x16(fract16 __a, fract16 __b) {
fract16 __rval = __builtin_multr_fr1x16(__a, __b);
return __rval;
}
它实际使用__builtin_multr_fr1x16完成计算,展开后的汇编代码就是:
// line 29
R0.L = R0.L * R1.L ;
R0 = R0.L (X);
W[FP + 16] = R0;
它不使用尾缀进行乘法计算,关于这种计算方式,文档这样描述:
Signed fraction. Multiply 1.15 * 1.15 to produce 1.31 results after left-shift correction. Round 1.31 format value at bit 16. (RND_MOD bit in the ASTAT register controls the rounding.) Saturate the result to 1.15 precision in destination register half. Result is between minimum -1 and maximum 1-2-15 (or, expressed in hex, between minimum 0x8000 and maximum 0x7FFF).
也就是说它将对结果进行舍入操作,当然和截断相比,它们之间的差值最大也就是2-15。
1.3 multu_fr1x16
这个函数在文档里面没有记载,其定义为:
/* 16-bit unsigned fractional multiplication using the FU option
*/
#pragma inline
#pragma always_inline
static fract16 multu_fr1x16(fract16 __a, fract16 __b) {
fract16 __rval = __builtin_multu_fr1x16(__a, __b);
return __rval;
}
展开__builtin_multu_fr1x16的汇编代码为:
// line 29
R0.L = R0.L * R1.L (FU);
R0 = R0.L (X);
W[FP + 16] = R0;
它使用了FU尾缀进行乘法运算,文档这样描述:
Unsigned fraction. Multiply 0.16 * 0.16 to produce 0.32 results. No shift correction. Round 0.32 format value at bit 16. (RND_MOD bit in the ASTAT register controls the rounding.) Saturate the result to 0.16 precision in destination register half. Result is between minimum 0 and maximum 1-2-16 (or, expressed in hex, between minimum 0x0000 and maximum 0xFFFF).
它采用的是0.16的格式,而不是fract16的1.15格式,难怪在文档里面没有记载,嘿嘿。
编缉推荐阅读以下文章
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!