1701|0

1140

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

TMS320C66x编程的16位变为32位操作 [复制链接]

6位变为32位操作,使用intrinsic函数,用const等。
1、源代码:


Word32 L_mpy_ll(Word32 L_var1, Word32 L_var2)
{
        double aReg;
        Word32 lvar;
        /* (unsigned)low1 * (unsigned)low1 */
        aReg = (double)(0xffff & L_var1) * (double)(0xffff & L_var2) * 2.0;
        /* >> 16 */
        aReg = (aReg / 65536);
        aReg = floor(aReg);
        /* (unsigned)low1 * (signed)high2 */
        aReg += (double)(0xffff & L_var1) * ((double)L_shr(L_var2, 16)) * 2.0;
        /* (unsigned)low2 * (signed)high1 */
        aReg += (double)(0xffff & L_var2) * ((double)L_shr(L_var1, 16)) * 2.0;
        /* >> 16 */
        aReg = (aReg / 65536);
        aReg = floor(aReg);
        /* (signed)high1 * (signed)high2 */
        aReg += (double)(L_shr(L_var1, 16)) * (double)(L_shr(L_var2, 16)) * 2.0;
        /* saturate result.. */
        lvar = L_saturate(aReg);
        return(lvar);
}
2、改编后的代码:
static inline Word32 L_mpy_ll(Word32 L_var1, Word32 L_var2)
{
        Word32 aReg_hh;
        Word40 aReg, aReg_ll, aReg_lh, aReg_hl;

        aReg_ll = (Word40)_mpyu(L_var1, L_var2) >> 16;
        aReg_lh = (Word40)_mpyluhs(L_var1, L_var2);
        aReg_hl = (Word40)_mpyhslu(L_var1, L_var2);
        aReg_hh = _smpyh(L_var1, L_var2);
        aReg = _lsadd(aReg_ll, _lsadd(aReg_lh, aReg_hl));
        aReg = _lsadd(aReg >> 15, aReg_hh);

        return(_sat(aReg));
}
3、优化方法说明:
        C6000编译器提供的intrinsic 可快速优化C代码,intrinsic用前下划线表示同调用函数一样可以调用它,即直接内联为C6000的函数。
        例如,在上例的源代码中没有使用intrinsics,每一行C代码需多个指令周期,在改编后的代码中,每一行代码仅需一个指令周期。
        例如,“aReg_ll = (Word40)_mpyu(L_var1, L_var2) >> 16”中“_mpyu”就是一个intrinsics函数,它表示两个无符号数的高16位相乘,结果返回。C6000支持的所有intrinsics指令及其功能参见《TMS320C6000系列DSP的原理与应用》一书的第265、266页,该书还提供了另外的例子。这些内联函数定义在CCS所在的C6000 / CGTOOLS / Include目录下的C6X.h文件中。
下面这个例子是C6000的“Programmer's Guide”上提取的使用intrinsics优化C代码的例子。


源代码:


int dotprod(const short *a, const short *b, unsigned int N)
{
        int i, sum = 0;

        for (i = 0; i < N; i++)
                sum += a * b;
        return sum;
}
改编后代码:
int dotprod(const int *a, const int *b, unsigned int N)
{
        int i, sum1 = 0, sum2 = 0;

        for (i = 0; i < (N >> 1); i++)
        {
                sum1 += _mpy(a, b);
                sum2 += _mpyh(a, b);
        }
        return sum1 + sum2;
}
技巧:
在C语言的调试全部通过以后,可以尝试将尽可能多的语句使用intrinsics函数加以改编,尤其在循环体内,这种改编可以大幅度减少执行时间。

 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表