![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| 循序渐进做优化:从C62x到C64x一例(上) | |||||
作者:61ic 文章来源:本站原创 点击数: 更新时间:2005-9-26 ![]() |
|||||
|
一、引言 f TI TMS320C641X DSP是德州仪器最高端的数字信号处理器,性能卓越,但因为其价格相对较高,只能针对特定行业的高端用户,对于大部分DSP研发人员,有时甚至很难接触到它们,所以相关深入的讨论很少。而媒体处理器TI TMS320DM642/DM640/DM643出现了,它集成了丰富的外设,甚至可以说,对于音视频和基于网络的应用比C641X更易使用,价格却十分便宜,所以在各种领域已开始大规模应用,当然关键的仍然是它们有着与C641X一样TI最强大的内核C64x,所以希望高效地(如更高分辨率或更多路)使用DM64x,除了片上内存的有效利用外,程序上基于C64x指令集(VelociTI.2 Core)的调度汇编级的优化变得十分关键。 TMS320C64x指令集与C6000公共指令集(VelociTI,支持流水线、VLIW,如TMS320C62x所使用的)相比共扩展了88条指令,这些指令的扩展是建立在其CPU结构改进基础上的,主要分三种情况: (1)与C6000公共指令集的指令功能及运行完全一致,只是增加了可执行的功能单元。这类指令共有6条。 (2)与C6000公共指令集内对应指令的功能及运行基本一致,主要差别是指令操作数的类型增加了,即大量引入了SIMD(单一指令多数据流扩展)指令。这类指令有34条。 (3)新增指令48条。 原来基于C62x(VelociTI)的优化程序可以不做更改的运行在C64x,但如果能够利用这些扩展的指令,情况将如何呢?本文将通过实例详细说明如何应用C64x系列指令进行程序优化,以达到提高执行效率的目的。这里我们以mpeg-4编解码中的一个函数为例,具体说明如何应用C64x系列指令集进行调度汇编级的程序优化。 二、应用C6000公共指令集的优化程序 在这里,将要进行优化的C语言函数为: void interpolate8x8_halfpel_h_c(uint8_t * dst, const uint8_t* src, const uint32_t DstStride, const uint32_t Srcstride, const uint32_t rounding) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int32_t tot =(int32_t) src[j * Srcstride + i] + (int32_t) src[j * Srcstride + i + 1]; tot = (tot + 1 - rounding) >> 1; dst[j * DstStride + i] = (uint8_t) tot; } } } 上面函数的执行体为一嵌套循环,函数的源操作数和目的操作数都是字节型数据。为了对比说明C64x系列指令集的优势,我们首先用C6000系列的公共指令集对该函数的循环体进行汇编优化,其内核程序(因为篇幅原因,流水线填充和排空部分不另外列出,可参考内核导出)如下: H_LOOP: ;循环内核 add .l1 A_src1,A_src2,A_dst1 ;1 || add .l2 B_src5,B_src6,B_dst5 || ldbu .d1t1 *+A_ptrSrc[4],A_src5 || ldbu .d2t2 *+B_ptrSrc[4],B_src9 || sub .s1 Acnt,1,Acnt add .s1 A_dst1,A_round,A_dst1 ;2 || add .s2 B_dst5,B_round,B_dst5 || add .l1 A_src2,A_src3,A_dst2 || add .l2 B_src6,B_src7,B_dst6 || ldbu .d1t1 *++A_ptrSrc[A_SrcStride],A_src1 || ldbu .d2t2 *++B_ptrSrc[B_SrcStride],B_src5 shru .s1 A_dst1,1,A_dst1 ;3 || shru .s2 B_dst5,1,B_dst5 || add .l1 A_dst2,A_round,A_dst2 || add .l2 B_dst6,B_round,B_dst6 || ldbu .d1t1 *+A_ptrSrc[1],A_src2 || ldbu .d2t2 *+B_ptrSrc[1],B_src6 add .l1 A_src3,A_src4,A_dst3 ;4 || add .l2 B_src7,B_src8,B_dst7 || shru .s1 A_dst2,1,A_dst2 || shru .s2 B_dst6,1,B_dst6 || stb .d1t1 A_dst1,*A_ptrDst++[1] || stb .d2t2 B_dst5,*B_ptrDst++[1] [A1]B .s2 H_LOOP ;5 || add .l1 A_dst3,A_round,A_dst3 || add .l2 B_dst7,B_round,B_dst7 || stb .d1t1 A_dst2,*A_ptrDst++[1] || stb .d2t2 B_dst6,*B_ptrDst++[1] add .l1 A_src4,A_src5,A_dst4 ;6 || add .l2 B_src8,B_src9,B_dst8 || shru .s1 A_dst3,1,A_dst3 || shru .s2 B_dst7,1,B_dst7 add .s1 A_dst4,A_round,A_dst4 ;7 || add .s2 B_dst8,B_round,B_dst8 || ldbu .d1t1 *+A_ptrSrc[2],A_src3 || ldbu .d2t2 *+B_ptrSrc[2],B_src7 shru .s1 A_dst4,1,A_dst4 ;8 || shru .s2 B_dst8,1,B_dst8 || stb .d1t1 A_dst3,*A_ptrDst++[1] || stb .d2t2 B_dst7,*B_ptrDst++[1] ldbu .d1t1 *+A_ptrSrc[3],A_src4 ;9 || ldbu .d2t2 *+B_ptrSrc[3],B_src8 stb .d1t1 A_dst4,*A_ptrDst++[A_DstAdjust] ;10 || stb .d2t2 B_dst8,*B_ptrDst++[B_DstAdjust] 这个优化程序是应用C6000公共指令集的最佳优化,它将C语言函数循环体的内循环进行了展开,采用分段读取源操作数的方法,即同时以一次内循环中8个数据的第一、第五个字节开始,使用ldbu指令读取数据,这样可以比全部从边侧读取字节数据的方法节省一个内核周期。数据处理完后使用stb指令存储数据。最终该程序的内核长度为10个周期,执行次数为七次,整个函数占用88个指令周期
|
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 没有相关文章 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|