内积
内积或者标量积在度量两个向量的正交性时是很有效的操作。大多数C语言程序员应该熟悉以下的内积操作:
short dot(short a[], short b[], int size) {
int i;
int output = 0;
for(i=0; i output += (a[i] * b[i]); } return output; 下面是Blackfin处理器汇编代码的主要部分: //P0=loop count, I0 & P1 are address registers A1 = A0 = 0; // A0 & A1 are aCCumulators LSETUP (loop1,loop1) LC0 = P0 ;// Setup hardware loop starting at label loop1:
loop1: A1 +=R1.H*R0.H, A0+=R1.L*R0.L||R1=[P1++]||R0=[I0++]; 下面几点说明了简化这种紧凑编码的 DSP 体系结构特性。 硬件循环缓冲器和循环计数器在每次迭代的末端不需要跳转指令。由于内积是乘积总和,因此可在一次循环中完成。该汇编程序所示是LSETUP指令,它是执行循环所需的唯一指令。 多发布指令允许在相同的周期内执行多条指令和两次数据访问。在每一次迭代时,必须先读取a[i]和b[i]值,然后相乘,最后写回到可变输出的运行总和中。在许多MCU平台上,这实际上等于四条指令。汇编代码的最后一行示出在一个周期内可执行的所有操作。 并行ALU操作允许同时执行两条16bit指令。汇编代码示出在每次迭代中使用的两个累加器单元(A0和A1),这将迭代次数减少了50%,从而将原来的执行时间减少了一半。 FIR算法 有限脉冲响应(FIR)滤波器是一种等价于卷积操作很常见的滤波器结构。A通过C操作看起来非常类似于内积。 //将信号取样到循环缓冲器中 x[cur] = sampling_function(); cur = (cur+1)%TAPS; // 在循环中增加cur指针 //完成乘加 y = 0; for (k=0; k y += h[k] * x[(cur+k)%TAPS]; } 使用汇编语言编写的FIR内核格式有些类似于内积。在这个特定的例子中,取样值存储在R0寄存器中,同时系数存储在R1寄存器中。 // P0 存有滤波器抽头 R0=[I0++] || R1=[I1++]; // 设置R0和R1的初始值 A1=A0=0; // 将累加器置零 LSETUP (loop1, loop1) LC0 = P0;//设置内部循环 loop1: A1+=R0.L*R1.L, A0+=R0.H*R1.H||R0=[I0++]||R1=[I1++]; //计算 除了具有所描述的用于内积的特性外,上面所示的FIR算法也可使用循环缓冲。 循环缓冲器不需要直接取余运算。在C代码片段中,%(取余)运算符可提供一种用于循环缓冲的机理。正如汇编内核中所示,这些取余运算符不能被编译为内循环中的其他指令。相反,数据地址发生器寄存器I0和I1可在外循环中配置,以便在循环到达系数缓冲器边界时能够自动返回起始处。 FFT算法 快速傅立叶变换(FFT)是许多信号处理算法不可缺少的一部分,其特点之一是输入向量按照连续时间顺序排列,但输出按比特翻转顺序排列。大多数传统的通用 处理器 要求程序员用单独的程序整理比特翻转输出。在DSP平台上,比特翻转可用于寻址引擎。 比特翻转寻址在实现FFT时不需要单独的比特翻转程序,允许硬件自动将FFT算法的输出进行比特翻转,无须程序员编写额外的程序,从而改进了性能。 除了上面所提到的指令外,有些处理器也包括额外一套专用指令以支持多种应用。提供这些指令的目的就是进一步提高对算法的处理能力,例如维特比算法、HufFMan编码以及许多其他比特操作程序。
本文关键字:处理器 DSP/FPGA技术,单片机-工控设备 - DSP/FPGA技术
www.55dianzi.com