资源描述
第第5 5章章 线性汇编优化代码线性汇编优化代码5.1 汇编优化器选项与伪指令汇编优化器选项与伪指令5.2 编写并行代码编写并行代码5.3 软件流水软件流水5.4 多周期循环的模迭代多周期循环的模迭代5.5 循环传递路径循环传递路径5.6 循环中的循环中的IF-Then-Else语句语句5.7 循环展开循环展开5.8 生命太长问题生命太长问题5.9 消除冗余取数消除冗余取数5.10 存储体存储体5.11 软件流水外循环软件流水外循环5.12 同内循环一起条件执行外循环同内循环一起条件执行外循环5.13 通用目标文件格式(通用目标文件格式(COFF)5.1 5.1 汇编优化器选项与伪指令汇编优化器选项与伪指令(1)-on选项(2)-mt选项和no_mdep伪指令(3).mdep伪指令(4).mptr伪指令(5).trip伪指令5.2 5.2 编写并行代码编写并行代码|5.2.1 点积的点积的C代码代码a)定点点积的C代码intdotp(shorta,shortb)intsum,i;sum=0;for(i=0;i100;i+)sum+=ai*bi;return(sum);5.2.1 5.2.1 点积的点积的C C代码代码b)浮点点积的C代码floatdotp(floata,floatb)inti;floatsum;sum=0;for(i=0;i15ADDpi_scaled,bi,ci;ci=(m*ai)15+biSTHci,*cptr+;存储cicntrSUBcntr,1,cntr;循环计数器递减cntrBLOOP;跳转到loop5.4.2 5.4.2 确定最小迭代间隔确定最小迭代间隔v1.展开展开的加权矢量和的的加权矢量和的C代码代码v2.转换转换展开的内核循环为线性汇编展开的内核循环为线性汇编v3.确定确定新的最小迭代间隔新的最小迭代间隔5.4.3 5.4.3 画相关性图画相关性图图5-11把相关性图均匀分成了两个部分,最小迭代间隔为2。5.4.4 5.4.4 线性汇编资源分配线性汇编资源分配【例例5.33】带资源分配的加权矢量和的线性汇编程序。LDW.D2*A4+,A2;ai&ai+1LDW.D1*B4+,B2;bi&bi+1MPY.M1A2,B6,A5;pi=m*aiMPYHL.M2A2,B6,B5;pi+1=m*ai+1SHR.S1A5,15,A7;pi_scaled=(m*ai)15SHR.S2B5,15,B7;pi+1_scaled=(m*ai+1)15AND.L2XB2,B10,B8;biSHR.S2B2,16,B1;bi+1ADD.L1XA7,B8,A9;ci=(m*ai)15+biADD.L2B7,B1,B9;ci+1=(m*ai+1)15+bi+1STH.D1A9,*A6+2;存储ciSTH.D2B9,*B0+2;存储ci+1A1 SUB.L1A1,1,A1;循环计数器递减A1 B.S1LOOP;跳转至loop5.4.5 5.4.5 模迭代间隔编排模迭代间隔编排v1.资源资源冲突冲突v2.生命太长生命太长v3.解决生命生命太长的问题解决生命生命太长的问题v4.安排剩余指令安排剩余指令5.4.6 5.4.6 使用汇编优化器出来加权矢量和使用汇编优化器出来加权矢量和例5.34为加权矢量和的线性汇编,该代码作为汇编优化器的输入,由汇编优化器产生软件流水循环。【例例5.34】加权矢量和的线性汇编。5.4.7 5.4.7 最后汇编最后汇编该代码包括如下优化:由于第次迭代的STHci+1与第+1次迭代的STHci并行执行,为防止STHci+执行次,而STHci执行次,对循环限定执行49次,但在循环退出后安排ADDci+1和STHci+指令;用于ADD指令的mask由MVK和MVKH指令设置;数组C的奇元素指针也在前面填充部分设置。【例例5.35】加权矢量和汇编代码。5.5 5.5 循环传递路径循环传递路径|5.5.1 将将C代码的内核循环转换为线性汇编代码的内核循环转换为线性汇编【例例5.37】IIR内核循环的线性汇编。LDH*xptr+,xi;xi+1MPYc1,xi,p0;c1*xiLDH*xptr,xi+1;xi+1MPYc2,xi+1,p1;c2*xi+1ADDp0,p1,s0;c1*xi+c2*xi+1LDH*yptr+,yi;yiMPYc3,yi,p2;c3*yiADDs0,p2,s1;c1*xi+c2*xi+1+c3*yiSHRs1,15,yi+1;yi+1STH yi+1,*yptr;存储yi+1cntrSUBcntr,1,cntr;循环计数器递减cntrBLOOP;跳转至loop5.5.2 5.5.2 画相关性图画相关性图图5-15是IIR滤波器的相关性图,从存yi+1到取yi之间形成了一个循环传递路径,由于存取指令使用相同的存储器流水线。5.5.3 5.5.3 确定最小迭代间隔确定最小迭代间隔v1.画画新的相关性图新的相关性图图5-16中所示是一个循环传递路径为4(2+1+1)的新的相关性图,因为MPYp2指令能够直接从寄存器中读取yi+1,因此循环传递路径可以减少6个周期,5.5.3 5.5.3 确定最小迭代间隔确定最小迭代间隔v2.新新的的TMS320C6x指令(内核循环)指令(内核循环)【例例5.38】循环传递路径较小的IIR内核循环的线性汇编。LDH*xptr+,xi;xi+1MPYc1,xi,p0;c1*xiLDH*xptr,xi+1;xi+1MPYc2,xi+1,p1;c2*xi+1ADDp0,p1,s0;c1*xi+c2*xi+1MPYc3,y,p2;c3*yiADDs0,p2,s1;c1*xi+c2*xi+1+c3*yiSHRs1,15,y;yi+1STH y,*yptr+;存储yi+1cntrSUBcntr,1,cntr;循环计数器递减cntrBLOOP;跳转至loop5.5.4 5.5.4 线性汇编资源分配线性汇编资源分配【例例5.39】带分配资源的IIR内核循环线性汇编。LDH.D1*A4+,A2;xi+1MPY.M1A6,A2,A5;c1*xiLDH.D1*A4,A3;xi+1MPY.M1XB6,A3,A7;c2*xi+1ADD.L1A5,A7,A9;c1*xi+c2*xi+1MPY.M2XA8,B2,B3;c3*yiADD.L2XB3,A9,B5;c1*xi+c2*xi+1+c3*yiSHR.S2B5,15,B2;yi+1STH.D2B2,*B4+;存储yi+1A1SUB.L1A1,1,A1;循环计数器递减A1B.S1LOOP;跳转至loop5.5.5 5.5.5 线模迭代间隔安排线模迭代间隔安排表5-14是IIR滤波器的模迭代间隔表,表中SHR指令及时在周期10结束,以便下次迭代的MPYp2在周期11读取其结果。5.5.6 5.5.6 使用汇编优化器处理使用汇编优化器处理IIRIIR滤波器滤波器【例例5.40】IIR滤波器的线性汇编。.global_iir_iir:.cprocx,y,c1,c2,c3.regxi,xi1,yi1.regp0,p1,p2,s0,s1,cntrMVK100,cntr;cntr=100LDH.D2*y+,yi1;yi+1LOOP:.trip100LDH.D1*x+,xi;xiMPY.M1c1,xi,p0;c1*xiLDH.D1*x,xi1;xi+1MPY.M1Xc2,xi1,p1;c2*xi+1ADD.L1p0,p1,s0;c1*xi+c2*xi+1MPY.M2Xc3,yi1,p2;c3*yiADD.L2Xs0,p2,s1;c1*xi+c2*xi+1+c3*yiSHR.S2s1,15,yi1;yi+1STH.D2yi1,*y+;存储yi+1cntrSUB.L1cntr,1,cntr;循环计数器递减cntrB.S1LOOP;跳转至loop.endproc5.5.7 5.5.7 最后汇编最后汇编例5.41是IIR滤波器的最后汇编代码,代码中,循环外有一个取y0指令,除此之外没有取y数组指令,执行该代码需要408个周期(4100)+8)。【例例5.41】IIR滤波器的汇编代码。5.6 5.6 循环中的循环中的IF-Then-ElseIF-Then-Else语句语句|5.6.1 IF-Then-Else的的C代码代码【例例5.42】IF-Then-Else的C代码。intif_then(shorta,intcodeword,intmask,shorttheta)inti,sum,cond;sum=0;for(i=0;i32;i+)cond=codeword&mask;if(theta=!(!(cond)sum+=ai;elsesum=ai;mask=mask1;return(sum);5.6.2 5.6.2 转换转换C C代码为线性汇编代码为线性汇编【例例5.43】IF-Then-Else内核循环的线性汇编。ANDcodeword,mask,cond;cond=codeword&maskcondMVK1,cond;!(!(cond)CMPEQ theta,cond,if;(theta=!(!(cond)LDH*aptr+,ai;aiifADDsum,ai,sum;sum+=ai!ifSUBsum,ai,sum;sum=aiSHLmask,1,mask;mask=mask1;cntrADD1,cntr,cntr;计数器递减cntrBLOOP;循环5.6.3 5.6.3 画相关性图画相关性图图5-17是If-Then-ElseC代码的相关性图。5.6.4 5.6.4 确定最小迭代间隔确定最小迭代间隔从表5-15中可以看出,没有一个资源是使用超过两次的,因此,最小迭代间隔仍然为2。单元指令合计/单元单元指令合计/单元.M10.M20.S1SHL&B2.S2MVK1.D1LDH1.L2CMPEQ1.D2ADD&SUB2.L2或.S2AND1.L1,.S1,或.D1.L2,.S2或.D2ADD1非.M单元合计5非.M单元合计45.6.5 5.6.5 线性汇编资源分配线性汇编资源分配【例例5.44】If-Then-Else代码的线性汇编。.global_if_then_if_then:.cproca,cword,mask,theta.regcond,if,ai,sum,cntrMVK32,cntr;cntr=32ZEROsum;sum=0LOOP:.trip32AND.S2Xcword,mask,cond;cond=codeword&maskcondMVK.S21,cond;!(!(cond)CMPEQ.L2theta,cond,if;(theta=!(!(cond)LDH.D1*a+,ai;aiifADD.L1sum,ai,sum;sum+=ai!ifSUB.D1sum,ai,sum;sum=aiSHL.S1mask,1,mask;mask=mask1;cntrADD.L21,cntr,cntr;计数器递减cntrB.S1LOOP;循环.returnsum.endproc5.6.6 5.6.6 最后汇编最后汇编例5.45是软件流水后的最后汇编代码,该循环代码的性能为70个周期。【例例5.45】If-Then-Else汇编代码。5.6.7 5.6.7 性能比较性能比较【例例5.46】循环次数大于3的If-Then-Else汇编代码。5.7 5.7 循环展开循环展开|5.7.1 展开展开IF-Then-Else的的C代码代码【例例5.47】if-Then-Else的C代码。5.7.2 C5.7.2 C代码转换会线性汇编代码转换会线性汇编【例例5.48】循环展开的If-Then-Else内核线性汇编。ANDcodeword,maski,condi;condi=codeword&maskicondiMVK1,condi;!(!(condi)CMPEQtheta,condi,ifi;(theta=!(!(condi)LDH*aptr+,ai;aiifiADDsumi,ai,sumi;sum+=ai!ifiSUBsumi,ai,sumi;sum=aiSHLmaski,1,maski+1;maski+1=maski1;ANDcodeword,maski+1,condi+1;condi+1=codeword&maski+1condi+1MVK1,condi+1;!(!(condi+1)CMPEQtheta,condi+1,ifi+1;(theta=!(!(condi+1)LDH*aptr+,ai+1;ai+!ifi+1ADDsumi+1,ai+1,sumi+1;sum+=ai+1!ifi+1SUBsumi+1,ai+1,sumi+1;sum=ai+1SHLmaski+1,1,maski;maski=maski+115MPYa1,d,a2;a2=a1*dADDa2,a0,a3;a3=a2+a0ADDsum0,a3,sum0;sum0+=a3MPYbi,c,b0;b0=bi*cSHRb0,15,b1;b1=b015MPYb1,e,b2;b2=b1*eADDb2,b0,b3;b3=b2+b0ADDsum1,b3,sum1;sum1+=b3cntrSUBcntr,1,cntr;循环计数器递减cntrBLOOP;跳转到loop5.8.3 5.8.3 画相关性图画相关性图图5-19所示为生命太长代码相关性图,该算法包含3个各自独立的图,其中两个独立图中有分开的联合路径,从a0到a3与从b0到b3。5.8.4 5.8.4 确定最小迭代间隔确定最小迭代间隔根据图5-19的相关性图和线性汇编指令可得出生命太长代码的资源表如表5-17所示。单元指令合计/单元单元指令合计/单元.M1MPY2.M2MPY2.S1B&SHR2.S2SHR1.D1LDHs1.D2LDH1.L1,S1或.D12 ADDs2.L2,.S2或.D22ADDs and SUB3非.M单元合计5非.M单元合计55.8.4 5.8.4 确定最小迭代间隔确定最小迭代间隔图5-20是加MV指令的新相关图,该图左边的叉路由MV指令分成两段。5.8.5 5.8.5 线性汇编资源安排线性汇编资源安排例5.53是根据相关图得出的安排功能单元的线性汇编,此处使用了两个2x和一个1x通路,c、d、和e可以载入循环外的另一端寄存器中。【例例5.53】生命太长代码的线性汇编。5.8.6 5.8.6 带带MVMV指令的最后汇编指令的最后汇编例5.54是带有MV指令的生命太长代码的最后汇编代码,执行该代码需要212个周期(200*100+11+1)。【例例5.54】带有MV指令的生命太长代码的最后汇编代码。5.9 5.9 消除冗余取数消除冗余取数|5.9.1 转换转换C代码为线性汇编代码为线性汇编【例例5.57】FIR滤波器内核循环的线性汇编。LDH.D2*x_1+2,x1;x1=xj+i+1LDH.D1*h+2,h0;h0=hiMPY.M1x0,h0,p00;x0*h0MPY.M1Xx1,h0,p10;x1*h0ADD.L1p00,sum0,sum0;sum0+=x0*h0ADD.L2Xp10,sum1,sum1;sum1+=x1*h0LDH.D1*x+2,x0;x0=xj+i+2LDH.D2*h_1+2,h1;h1=hi+1MPY.M2x1,h1,p01;x1*h1MPY.M2Xx0,h1,p11;x0*h1ADD.L1Xp01,sum0,sum0;sum0+=x1*h1ADD.L2p11,sum1,sum1;sum1+=x0*h1ctrSUB.S2ctr,1,ctr;循环计数器递减ctrB.S2LOOP;跳转至loop5.9.2 5.9.2 画相关性图画相关性图图5-21是消除冗余取后的FIR滤波器的相关性图。5.9.3 5.9.3 确定最小迭代间隔确定最小迭代间隔表5-18是FIR滤波器代码的资源表,可以确定最小迭代间隔为2,这意味着每个周期可执行两个乘累加操作。单元指令合计/单元单元指令合计/单元.M12 MPY2.M22 MPY2.S1B&SHR0.S2B1.D12 LDH2.D22 LDHs2.L1,S1或.D12 ADDs2.L2,.S2或.D22ADDs and SUB3非.M单元合计4非.M单元合计61x路径22x路径25.9.4 5.9.4 线性汇编资源分配线性汇编资源分配【例例5.58】例 FIR滤波器的线性汇编。5.9.5 5.9.5 最后汇编最后汇编该嵌套循环执行的总周期数为2350,此处每个外循环都有15个周期的开销:9个周期执行内环填充;6个周期执行到外环的跳转。【例例5.59】例消除冗余取指令的最终FIR滤波器汇编代码。5.10 5.10 存储体存储体|5.10.1 FIR滤波器的内核循环滤波器的内核循环【例例5.60】FIR滤波器最后汇编代码的内核循环。LOOP:ADD.L2XA8,B9,B9;sum1+=x1*h0|ADD.L1A7,A9,A9;sum0+=x0*h0|MPY.M2B1,B0,B7;*x1*h1|MPY.M1XB1,A1,A8;*x1*h0|B2B.S2LOOP;*跳转至内循环|LDH.D1*A5+2,A1;*h0=hi|LDH.D2*B5+2,B1;*x1=xj+i+1ADD.L1XB7,A9,A9;sum0+=x1*h1|ADD.L2B8,B9,B9;sum1+=x0*h1|MPY.M2XA0,B0,B8;*x0*h1|MPY.M1A0,A1,A7;*x0*h0|B2SUB.S2B2,1,B2;*内循环计数器递减|LDH.D2*B4+2,B0;*h1=hi+1|LDH.D1*A4+2,A0;*x0=xj+i+25.10.1 FIR5.10.1 FIR滤波器的内核循环滤波器的内核循环画出数组的奇偶元素的读取安排在同一循环周期内的FIR滤波器相关图,如图5-24所示。5.10.2 5.10.2 展开的展开的FIRFIR滤波器的滤波器的C C代码代码例5.61是展开内核循环后的FIR滤波器C代码,该方法增加了安排指令的灵活性,而在不考虑数组存储形式和存储器block的情况下,写出不产生存储体冲突的FIR滤波器代码。【例例5.61】展开内核循环后的FIR滤波器C代码。5.10.3 5.10.3 将将C C代码转换为线性汇编代码转换为线性汇编例5.62为循环展开的FIR滤波器C代码内核循环的线性汇编。【例例5.62】展开的FIR滤波器内核循环线性汇编。5.10.4 5.10.4 画相关性图画相关性图图5-25是不存在存储器冲突的FIR滤波器的相关性图。5.10.5 5.10.5 含有含有.mptr.mptr命令的展开后命令的展开后FIRFIR线性汇线性汇编编例5.63给出了具有.mptr伪指令的展开FIR滤波器内核循环的线性汇编,.mptr伪指令允许汇编优化器根据特定指针寄存器和存储器访问信息,确定两个存储器操作是否存在bank冲突。【例例5.63】展开的FIR滤波器线性汇编。5.10.6 5.10.6 线性汇编资源分配线性汇编资源分配随着一个循环内的指令数的增加,对该循环内的每个数值安排特定的寄存器越来越困难,由于TMS320C6000仅有32个寄存器,如果一个循环内有33条指令,且每一条指令都有一个数值,则这些数值不能单独占用一个寄存器,而是由该循环中不在相同周期存活的数值分享寄存器,手工安排寄存器虽然不复杂,但是可能会很慢。5.10.7 5.10.7 确定最小迭代间隔确定最小迭代间隔如表5-19所示为FIR滤波器代码资源,没有存储器冲突的FIR滤波器的最小迭代间隔应该是4,这意味着每周期完成2个乘累加。单元指令合计/单元单元指令合计/单元.M14 MPY4.M24 MPY2.S10.S2B1.D14 LDHs4.D24 LDHs2.L1,S1或.D14 ADDs4.L2,.S2或.D24ADDs and SUB3非.M单元合计8非.M单元合计101x路径42x路径45.10.8 5.10.8 最后汇编最后汇编例5.64是消除冗余取和无存储器冲突的FIR滤波器的最后汇编代码,该代码的执行周期数为2402(50(8*4+10+6)+2),其外环开销为16个周期。【例例5.64】消除冗余取和无存储器冲突的FIR滤波器汇编代码。5.11 5.11 软件流水外循环软件流水外循环|5.11.1 展开展开FIR滤波器的滤波器的C代码代码【例例5.65】循环展开后的FIR滤波器C代码。5.11.2 5.11.2 最后汇编最后汇编例5.66是软件流水外环的FIR滤波器的最后汇编代码。在内循环后的每条指令注释中使用了e、p或o标记,分别表示指令是排空、填充和外环指令。【例例5.66】消除冗余取、无存储器冲突和软件流水外环的FIR滤波器汇编代码。5.12 5.12 同内循环一起条件执行外循环同内循环一起条件执行外循环|5.12.1 展开展开FIR滤波器的滤波器的C代码代码【例例5.67】展开后的FIR滤波器C代码。5.12.2 5.12.2 将内核循环的将内核循环的C C代码转换为线性汇代码转换为线性汇编编【例例5.68】展开后的FIR内核循环的线性汇编。5.12.3 5.12.3 将外环的将外环的C C代码转换为线性汇代码转换为线性汇编编【例例5.69】FIR滤波器外环线性汇编。sctrSUBsctr,1,sctr;存储循环计数器递减!sctrSHRsum07,15,y0;(sum015)!sctrSHRsum17,15,y1;(sum115)!sctrSTHy0,*y+2;yj=(sum015)!sctrSTHy1,*y_1+2;yj+1=(sum115)!sctrMVK4,sctr;复位存储循环计数器pctrSUBpctr,1,pctr;复位循环计数器指针递减!pctrSUBx,rstx2,x;复位xptr!pctrSUBx_1,rstx1,x_1;复位x_1ptr!pctrSUBh,rsth1,h;复位hptr!pctrSUBh_1,rsth2,h_1;复位h_1ptr!pctrMVK4,pctr;复位指针复位循环计数器5.12.4 5.12.4 展开展开FIRFIR滤波器的滤波器的C C代码代码由例5.70可看出内循环与外循环总指令数为38条,显然不能使用4周期循环,为减少外环开销,又不降低内环吞吐量,必须再展开一次内循环,例为展开后的FIR滤波器C代码,其每次内环迭代处理8个元素。【例例5.70】展开的FIR滤波器C代码。5.12.5 C5.12.5 C代码转换为线性汇编(内核循环)代码转换为线性汇编(内核循环)该代码中指令有如下的调整:使用LDW指令代替LDH指令,以减少循环的取指数;移位和存储指令紧跟在LDW指令后;sum0和sum1的第一个ADD指令是存储计数的条件执行指令,因为当sctr=0时,一个内循环已结束,新的内循环第一次迭代开始启动,第一个ADD不应该将p00与前次循环的sum07相加;sum0的第一个ADD和第一个MPYp00的结果写入同一寄存器,第2个ADD读取p00与p01。【例例5.71】条件地执行外环的FIR滤波器线性汇编。5.12.6 5.12.6 确定最小迭代间隔确定最小迭代间隔根据表5-20可得出最小迭代将为8,这意味着每个周期仍执行两个乘累加。单元合计/单元单元合计/单元.M18.M28.S17.S26.D15.D26.L1,S1或.D18.L2,.S2或.D28非.M单元合计20非.M单元合计201x路径72x路径55.12.7 5.12.7 最后汇编最后汇编例5.72给出了外环条件地与内环并行执行的FIR滤波器的最后汇编代码。【例例5.72】FIR滤波器最后汇编代码。5.12.8 5.12.8 性能比较性能比较该代码的循环计数为1612:50(84+0)+12,并且消除了外循环带来的开销,表5-21为FIR滤波器代码的性能比较。代码举例周期周期数例3.90 消除冗余取数的FIR滤波器代码50(16*2+9+6)+22352例3.98 消除冗余取和无存储器冲突的FIR滤波器汇编代码50(8*4+10+6)+22402例3.100 消除冗余取数和无存储器冲突的FIR滤波器外环软件流水的最后汇编代码50(7*4+6+6)+62006例3.103 FIR滤波器外环线性汇编50(8*4+0)+1216125.13 5.13 通用目标文件格式(通用目标文件格式(COFFCOFF)|5.13.1 段(段(sections)图5-26所示为一个假想的目标存储器和目标文件各个段之间的关系。5.13.2 5.13.2 汇编器对段的处理汇编器对段的处理v1.未未初始化段初始化段v2.初始化初始化段段v3.命名命名段段v4.子子段段v5.使用使用SECTIONS伪指令伪指令5.13.3 5.13.3 连接器对段的处理连接器对段的处理v1.默认默认的存储器分配的存储器分配图5-28所示为把两个文件连接到一起的过程。5.13.3 5.13.3 连接器对段的处理连接器对段的处理v2.在在存储器映射图内放置各段存储器映射图内放置各段图5-28解释了连接器组合各个段的缺省方法,有时用户可能不想用缺省的方法,例如,可能不想把所有的.text组合成单一的.text段;或者可能想把一个命名段置于一个.data段通常所在的位置。绝大多数存储器映像图含有不同长度不同类型的存储器(RAMROMEPROM等)用户可能希望把一个段放在一种指定类型的存储器内。
展开阅读全文