博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Visual DSP定点数(fract)使用指南
阅读量:4961 次
发布时间:2019-06-12

本文共 5271 字,大约阅读时间需要 17 分钟。

fract数据类型(Fractional Data Type

C类型

用法

fract16

16位有符号定点数,1.15

fract32

32位有符号定点数1.31

fract2x16

16位有符号定点数

这几个数据类型实际上并不是固有的数据类型,而是使用typedef语句将short定义成fract16,long定义成fract32fract2x16。因此,你不能直接通过fract16*fract16来得到正确的定点相乘结果。对于C++,有两个类”fract””shortfract”定义了基本的算术操作。以下仅谈在C中的操作。

内建函数(Built-in Functions

由于fract算术的特殊性,系统提供了一套接口用于实现这些运算,它们定义在fract.h文件中。所有在fract.h中的文件都被标记为“内联”的,所以如果开了编译器优化,内建函数将会被展开。下面给出的内建函数并不全,更多的请参考[1]

fract16 内建函数

fract16 add_fr1x16(fract16 f1, fract16 f2);

       执行16位加法(f1 + f2)

fract16 sub_fr1x16(fract16 f1, fract16 f2);

       执行16位减法(f1 – f2)

fract16 mult_fr1x16(fract16 f1, fract16 f2)

       执行16位乘法(f1 * f2),结果截短到16

fract16 multr_fr1x16(fract16 f1, fract16 f2)

       执行16位乘法,结果舍入到16位。是否进位根据ASTAT寄存器的RND_MOD是否被设置。

fract32 mult_fr1x32(fract16 f1, fract16 f2)

       执行16位乘法,返回32位结果。

fract16 abs_fr1x16(fract16 f1)

       返回输入参数的绝对值,如0x8000返回0x7fff

fract16 min_fr1x16(fract16 f1, fract16 f2)

       返回f1,f2的较小值

fract16 max_fr1x16(fract16 f1, fract16 f2)

       返回f1,f2的较大值

fract16 negate_fr1x16(fract16 f1)

       返回-f1

fract16 shl_fr1x16(fract16 src, short shft)

       src作算术移位,shft为正则向左移,保留符号位,空的位用0填充;shft为负则向右移,符号扩展;

fract32 内建函数

fract32 add_fr1x32(fract32 f1,fract32 f2)

       返回f1 + f2

fract32 sub_fr1x32(fract32 f1,fract32 f2)

       返回f1 – f2

fract32 mult_fr1x32x32(fract32 f1,fract32 f2)

       返回f1*f2,运算的中间结果保存在40位的累加寄存器,然后舍入到32位。

fract32 multr_fr1x32x32(fract32 f1,fract32 f2)

       和上一个函数一样,只不过提供了额外的舍入精度

fract32 mult_fr1x32x32NS(fract32 f1, fract32 f2)

       提供不饱和的乘法f1 * f2,这个相对来说会快一些

fract32 abs_fr1x32(fract32 f1)

       返回f1的绝对值

fract32 min_fr1x32(fract32 f1, fract32 f2)

       返回f1, f2的较小值

fract32 max_fr1x32(fract32 f1, fract32 f2)

       返回f1, f2的较大值

fract32 negate_fr1x32(fract32 f1)

       返回-f1

fract16 sat_fr1x32(fract32 f1)

       如果f1 > 0x00007fff,则返回0x7fff,如果f1< 0xffff8000,则返回0x8000,其他情况,返回f1的低16

 

fract2x16 内建函数

将两个fract16打包成fract2x16表示为{a,b}”a”为高半部,”b”为低半部

fract2x16 compose_fr2x16(fract16 f1, fract16 f2)

f1,f2打包成fract2x16的类型

输入:2fract16

输出:{f1, f2}

fract16 high_of_fr2x16(fract2x16 f)

返回f的高半部

输入:{a, b}

输出:a

fract16 low_of_fr2x16(fract2x16 f)

返回f的低半部

输入:{a, b}

输出:b

fract2x16 add_fr2x16(fract2x16 f1,fract2x16 f2)

输入:f1{a, b}, f2{c, d}

输出:{a + c, b + d}

fract2x16 sub_fr2x16(fract2x16 f1,fract2x16 f2)

输入:f1{a, b}, f2{c, d}

输出:{a – c, b – d}

fract2x16 mult_fr2x16(fract2x16 f1,fract2x16 f2)

输入:f1{a, b}, f2{c, d}

输出:{trunc16(a*c), trunc16(b*d)}

fract2x16 multr_fr2x16(fract2x16 f1,fract2x16 f2)

输入:f1{a, b}, f2{c, d}

输出:{round16(a*c), round16(b*d)}

fract2x16 negate_fr2x16(fract2x16 f1)

输入:f1{a, b}

输出:{-a, -b}

fract2x16 shl_fr2x16(fract2x16 f1,short shft)

输入:f1{a, b} shft

输出:{a << shft, b << shft}

fract16 sum_fr2x16(fract2x16 f1)

输入:f1{a, b}

输出:a + b

fract2x16 add_as_fr2x16(fract2x16 f1,fract2x16 f2)

输入:f1{a, b}, f2{c, d}

输出:{a + c, b – d}

fract16fract2x16的一点注解

当编译使用单数据fract16运算的程序时,编译器会尝试优化,寻找可以并行计算的情形,因此重写程序以显式使用fract2x16并不总是能产生性能提高。

fract数据类型的应用(Application of Fractional Data Type)

fract常量的表示

要对一个fract类型(fract16, fract32)赋常量值应该使用r16,r32后缀。

例如:

要为fract16类型的变量a赋值0.5,那么可以使用

a=0x4000a=0.5r16

两种方式,显然,后者看起来更直观。

分数与浮点数之间的转换

VisualDSP++运行时库提供了高层次的支持用于fract与浮点数之间的转换。这些函数的声明包含在头文件fract2float_conv.h里。

fract32 fr16_to_fr32(fract16);        //Deposits a fract16 to make a fract32

fract16 fr32_to_fr16(fract32);        //Truncate a fract32 to make a fract16

 

fract32 float_to_fr32(float);           //Convert a float to fract32

fract16 float_to_fr16(float);           //Convert a float to fract16

 

float fr16_to_float(fract16);    //Convert a fract16 to float

float fr32_to_float(fract32);    //Convert a fract32 to float

综合实例

fract转换为float并输出

#include 
<
stdio.h
>
#include 
<
fract.h
>
#include 
<
fract2float_conv.h
>
int
 main( 
void
 )
{
       fract16 x
=
0
.4r16;
       
float
 fx;
       fx 
=
 fr16_to_float(x);
       printf(
"
x=%f\n
"
, fx);
       
return
 
0
;
}

 

输出:

       x=0.399994

fractfloat的时间花费对比

代码很简单,这里不再费口舌:

#include 
<
stdio.h
>
#include 
<
fract.h
>
#include 
<
fract2float_conv.h
>
#include 
<
time.h
>
#define
 COUNT 10000
int
 main( 
void
 )
{
       
int
 i;
       fract32 x, y, z;
       
float
 fx, fy, fz;
       clock_t t1, t2;    
       
//
test fract,be sure that the sum won't overflow
       t1 
=
 clock();
       x 
=
 
0
; y 
=
 
0
; z 
=
 
0
;
       
for
 (i 
=
 
0
; i 
<
 COUNT; i
++
)
       {
              z 
=
 add_fr1x32(z, mult_fr1x32x32NS(x, y));
              x 
=
 add_fr1x32(x, 
0
.000001r32);
              y 
=
 add_fr1x32(y, 
0
.000001r32);
       }
       t2 
=
 clock();
       printf(
"
result:%f\n
"
, fr32_to_float(z));
       printf(
"
fract operations cost:%uk Cycles\n
"
, (t2 
-
 t1) 
/
 
1000
);
       
//
test float
       t1 
=
 clock();
       fx 
=
 
0
; fy 
=
 
0
; fz 
=
 
0
;
       
for
 (i 
=
 
0
; i 
<
 COUNT; i
++
)
       {
              fz 
+=
 fx 
*
 fy;
              fx 
+=
 
0.000001
;
              fy 
+=
 
0.000001
;
       }
       t2 
=
 clock();
       printf(
"
result:%f\n
"
, fz);
       printf(
"
float operations cost:%uk Cycles\n
"
, (t2 
-
 t1) 
/
 
1000
);
       
return
 
0
;
}

 

输出(DEBUG模式)

       result:0.333131

       fract operations cost:360k Cycles

       result:0.333240

       float operations cost:5148k Cycles

输出(RELEASE模式)

       result:0.333131

       fract operations cost:90k Cycles

       result:0.333240

       float operations cost:5018k Cycles

这里可以看到性能的差异还是很大的。在RELEASE下,性能相差50倍以上。不过这里有一点值得注意,两个运算的结果并不完全一样,相差得有点大。这里没法给出详细的理论分析差异的原因,个人猜想是由于误差累积差成的。因此,在实际应用中,最好注意下不要这种连续累加的情况。使用multr_fr1x32x32结果会更接近一些,不过也差不了多少。

扩展阅读(Further Reading)

参考[1]有关于C++操作fract的详细细节,以及复数fract内建函数的使用,有兴趣的读者请自行了解。这些都在[1]Compiler->C/C++ Compiler Language->Compiler Built-In Functions章节。还有一些有关映射ETSI(European Telecommunications Standards Institute) fract函数到内建函数的资料,本人也没用过。

参考(References

[1]“Visual DSP++ 5.0 Compiler and Library Manual for Blackfin Processors”

转载于:https://www.cnblogs.com/pheye/archive/2011/05/10/2042216.html

你可能感兴趣的文章
django-beautifulsoup的简单使用
查看>>
【Marschner模型】Light Scattering from Human Hair Fibers人类头发纤维的光照散射
查看>>
实验一作业
查看>>
设置RDLC中table控件的表头在每页显示
查看>>
time及各种cpu时间
查看>>
MFC reference
查看>>
扎马步-计算机网络和系统基础知识
查看>>
64位/32位
查看>>
浅谈对Struts2上传文件的理解
查看>>
看完这篇分析,还不懂分布式事物,请给我差评
查看>>
C#中的委托和事件(续)
查看>>
Codeforces Round #445 Div. 2 A ACM ICPC+B Vlad and Cafes
查看>>
C# Excel数据导入到数据库
查看>>
c# 去除字符串中重复字符
查看>>
POJ 1147
查看>>
作品第三课----简单计算器
查看>>
贫血模型和充血模型
查看>>
Mui 微信支付、支付宝支付
查看>>
下拉框、多选框、单选框 通过TagHelper绑定数据
查看>>
卷积神经网络_(1)卷积层和池化层学习
查看>>