现在的位置: 首页 > 综合 > 正文

Vdsp(bf561)中的浮点运算(14):fract16除法

2013年01月14日 ⁄ 综合 ⁄ 共 3124字 ⁄ 字号 评论关闭

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

  

本文适用于

ADSP-BF561

Visual DSP++ 5.0 (update 6)

Vdsp dual processor simulate

  

欢迎转载,但请保留作者信息

 

原来指望能够有div_fr1x16之类的函数来实现fract16的除法,但是很遗憾vdsp居然不直接提供这样的函数,让人颇为尴尬,估计是因为其CPU不直接提供fract除法的缘故。不过vdsp文档里面提供了一个做除法的例子:

fract16 saturating_fract_divide(fract16 nom, fract16 denom)

{

     int partialres = (int)nom;

     int divisor = (int)denom;

     fract16 rtn;

     int i;

     int aq;   /* initial value irrelevant */

 

     if (partialres == 0) {

         /* 0/anything gives 0 */

         rtn = 0;

     } else if (partialres >= divisor) {

          /* fract16 values have the range -1.0 <= x < +1.0,  */

         /* so our result cannot be as high as 1.0.          */

         /* Therefore, for x/y, if x is larger than y, */

         /* saturate the result to positive maximum.   */

         rtn = 0x7fff;

     } else {

         /* nom is a 16-bit fractional value, so move */

         /* the 16 bits to the top of partialres.     */

         /* (promote fract16 to fract32) */

         partialres <<= 16;

 

         /* initialize sign bit and AQ, via divs(). */

         partialres = divs(partialres, divisor, &aq);

 

         /* Update each of the value bits of the partial result */

         /* and reset AQ via divq().                            */

         for (i=0; i<15; i++) {

              partialres = divq(partialres, divisor, &aq);

         }

 

         rtn = (fract16) partialres;

     }

 

     return rtn;

 

}

这个计算过程在不打开优化的情况下将需要500cycle,在打开优化之后将只需要42cycle!相比较于将fract16转换为float进行计算还是要快得多。

但是很显然,例子中给出的这个函数并没有考虑到符号位,比如计算0.2 / -0.4这样的式子时它将直接返回1,因而我们需要对它进行适当的修改。

fract16 saturating_fract_divide(fract16 nom, fract16 denom)

{

     int partialres;

     int divisor;

     fract16 rtn;

     int i;

     int aq;   /* initial value irrelevant */

     int sign = (nom ^ denom) & 0x8000;

     partialres = abs_fr1x16(nom);

     divisor = abs_fr1x16(denom);

 

     if (partialres == 0) {

         /* 0/anything gives 0 */

         rtn = 0;

     } else if (partialres >= divisor) {

         /* fract16 values have the range -1.0 <= x < +1.0,  */

         /* so our result cannot be as high as 1.0.          */

         /* Therefore, for x/y, if x is larger than y, */

         /* saturate the result to positive maximum.   */

         rtn = 0x7fff;

     } else {

         /* nom is a 16-bit fractional value, so move */

         /* the 16 bits to the top of partialres.     */

         /* (promote fract16 to fract32) */

         partialres <<= 16;

 

         /* initialize sign bit and AQ, via divs(). */

         partialres = divs(partialres, divisor, &aq);

 

          /* Update each of the value bits of the partial result */

         /* and reset AQ via divq().                            */

         for (i=0; i<15; i++) {

              partialres = divq(partialres, divisor, &aq);

         }

 

         rtn = (fract16) (partialres);

         if(sign)

              rtn = negate_fr1x16(rtn);

     }

 

     return rtn;

 

}

优化之前需要522cycle,优化之后需要50cycle

 

 

 

 

1       参考资料

Vdsp(bf561)中的浮点运算(13):fract16乘法运算(2009-8-18)

Vdsp(bf561)中的浮点运算(12):fract16加减运算(2009-8-17)

Vdsp(bf561)中的浮点运算(11):fract16float的转换(2009-8-17)

Vdsp(bf561)中的浮点运算(10):fract16类型表示(2009-8-17)

Vdsp(bf561)中的浮点运算(9):long doublefloat的比较(2009-8-14)

Vdsp(bf561)中的浮点运算(8):float除法运算(2009-8-14)

Vdsp(bf561)中的浮点运算(7):float乘法运算(2009-8-13)

Vdsp(bf561)中的浮点运算(6):float加减运算(2009-8-13)

Vdsp(bf561)中的浮点运算(5):float类型表示总结(2009-8-12)

Vdsp(bf561)中的浮点运算(4):FLT_MAX(2009-8-12)

Vdsp(bf561)中的浮点运算(3):FLT_MIN(2008-12-19)

Vdsp(bf561)中的浮点运算(2):float的疑问(2008-12-18)

Vdsp(bf561)中的浮点运算(1):文档的说法(2008-12-16)

 

 

 

 

抱歉!评论已关闭.