Skip to main content
欢迎来到PAWPAW技术文档网站了解更多信息

使用`lib_xcore_math`进行BFP运算

lib_xcore_math中的*_prepare()函数

为了方便BFP操作,lib_xcore_math的向量API中的许多函数都有一个相应的“准备”函数。通常,这个函数的名称是在原函数名称后面加上 _prepare

例如,除了vect_s16_mul()之外,还有一个函数vect_s16_mul_prepare():

C_API
void vect_s16_mul_prepare(
exponent_t* a_exp,
right_shift_t* a_shr,
const exponent_t b_exp,
const exponent_t c_exp,
const headroom_t b_hr,
const headroom_t c_hr);

注意,vect_s16_mul_prepare()接受与向量b[]c[]相关联的指数和头空间,但不直接接受b[]c[]。准备函数的思想是利用可用的信息(除了实际输入元素值)来选择输出指数,并选择为函数所需的任何其他辅助输入参数。

vect_s16_mul_prepare()的情况下,a_expa_shr输出 参数。输出指数通过a_exp输出,vect_s16_mul()所需的右移参数acc_shr通过a_shr输出。

与之相对比的是vect_s32_mul_prepare():

C_API
void vect_s32_mul_prepare(
exponent_t* a_exp,
right_shift_t* b_shr,
right_shift_t* c_shr,
const exponent_t b_exp,
const exponent_t c_exp,
const headroom_t b_hr,
const headroom_t c_hr);

该函数输出了两个移位参数b_shrc_shr,这与vect_s32_mul()所需的参数相匹配。

最后,让我们来看一下vect_s32_dot_prepare(),我们将在第3B部分中遇到:

C_API
void vect_s32_dot_prepare(
exponent_t* a_exp,
right_shift_t* b_shr,
right_shift_t* c_shr,
const exponent_t b_exp,
const exponent_t c_exp,
const headroom_t b_hr,
const headroom_t c_hr,
const unsigned length);

除了接受一个length参数外,它与vect_s32_mul_prepare()非常相似。

vect_s32_mul()对两个输入向量进行逐元素乘法运算,vect_s32_dot()则对逐元素乘积进行求和。因此,vect_s32_dot_prepare()还需要知道要求和的乘积数量。

如果正在将2个逐元素乘积相加,那么结果的可能值范围是元素乘积本身的两倍,这意味着指数需要增加以避免溢出。如果正在将16个逐元素乘积相加,结果可能会增大16倍,需要额外的4位(4=log2(16)4=log_2(16))来存储结果,或者将输出指数增加4。

BFP类型

bfp_s32_tlib_xcore_math中的一个结构类型,表示具有32位尾数的BFP向量。bfp_s32_t类型有4个重要字段:

字段描述
int32_t* data指向int32_t数组的指针;用于支持尾数向量的缓冲区。
unsigned length表示BFP向量中元素的数量。
exponent_t exp与向量的尾数相关联的指数。
headroom_t hr向量尾数的头空间。

注意:在lib_xcore_math中,除非另有说明,否则向量的“length”始终指元素的数量,而不是其欧几里得长度。

BFP操作

第3部分第3C部分中,我们将遇到几个BFP操作。

bfp_s32_init()

使用调用bfp_s32_init()来初始化bfp_s32_t(32位BFP向量)。最后一个参数calc_hr指示在初始化过程中是否计算头空间。当元素缓冲区未填充数据时,这是不必要的。

bfp_s32_dot()

bfp_s32_dot()计算两个BFP向量之间的内积,但与vect_s32_dot()不同,它会为我们处理所有指数和头空间的管理。bfp_s32_dot()基本上封装了第3B部分中执行的所有逻辑(除了将输出转换为适当的定点表示)。

bfp_s32_headroom()

bfp_s32_use_exponent()