基于DSP的信道译码算法优化
{/*计算度量值*/
branch_metric=hamm(conv_output[i],c,channel_data);
/*比较累计度量保留其中最小,并且记录其状态路径*/
if(accum_err_metric[nextstate[j][1]>accu
m_err_metric[j][0]+branch_metric]
{accum_err_metric[nextstate[j][i][1]=accum_err_metric[j][0]+branch_metri;
state_history[nextstate[j][i]][sh_ptr]=j;
}
}*/end of i<2*/
}/*end of j<number_of_states*/
}/*end of c<number_of_input*/
其中调用函数hanmm是计算当前输入值与网络图上的值相比较所返回的度量值。
Int hamm(char output_vector,int x,char channel_output[24])
{char target_vector=0;
int hamm=0;
int i=0;
int i=0;
target_vector=(output_vector)^channel_output[x];
for(i=1;i>=0;i--)
hamm+=(target_vector>>i)&0x01;
return hamm;
}
在验证了算法代码实现功能并以设置断点的方法测试代码的性能,这段循环运行耗时(时钟周期)为1790。显然,性能不能达到要求,就要进入代码优化的第二阶段了。
②一般在代码调试中,最影响性能的是其中的循环代码段。而软件流水是一种用于安排循环内的指令运行方式,尽可能充分利用CPU的功能单元等资源,使循环的多次迭代能够并行执行的一种技术。在C6000的C/C++编译器里,采用软件流水使编译出来的程序代码优化是一项核心技术。所以在进一步优化之前,需要调整并尽可能简化代码的结构并去除影响软件流水的因素使其能够被编译器充分流水,这对大幅提高整个代码的性能非常重要。
所以,在考虑影响因素同时对Viterbi算法的循环代码进行如下调整;
*使用内联函数(intrinsics)替代复杂的C语言程序。C6000编译器提供了许多intrinsics,可以快速优化C代码。Intrinsics是直接参与C6000汇编指令映射的内联函数。在这里使用了_extu(x,y,z),以简化其中hamm代码部分。
*尽管软件流水循环可包含intrinsics,但不能包含函数调用。所以需要把调用函数hamm在循环中展开实现。
*由于编译器仅对最内部的循环执行流水,所以为了提高性能应尽可能创造一比较大的内循环。在代码中可以看到,在最内循环是i的两次循环,仅对它进行流水,对整个代码的性能提高不大。所以一个想法是,将i和j循环全部展开,使编译器直接面对最大的C循环以最大发挥软件流水的作用。
*另外,展开循环后代码中的变量如果可以确定其运行中的值,就尽量以实值代入,这样减少了变量个数,也就是减少了所需分配的寄存器个数(C
《基于DSP的信道译码算法优化(第2页)》