
DSP处理器与通用处理器的比较
考虑一个数字信号处理的实例,比如有限冲击响应滤波器(FIR)。用数学语言来说,FIR滤波器是做一系列的点积。取一个输入量和一个序数向量,在系数和输入样本的滑动窗口间作乘法,然后将所有的乘积加起来,形成一个输出样本。
类似的运算在数字信号处理过程中大量地重复发生,使得为此设计的器件必须提供专门的支持,促成了了DSP器件与通用处理器(GPP)的分流:
1 对密集的乘法运算的支持
GPP不是设计来做密集乘法任务的,即使是一些现代的GPP,也要求多个指令周期来做一次乘法。而DSP处理器使用专门的硬件来实现单周期乘法。DSP处理器还增加了累加器寄存器来处理多个乘积的和。累加器寄存器通常比其他寄存器宽,增加称为结果bits的额外bits来避免溢出。
同时,为了充分体现专门的乘法-累加硬件的好处,几乎所有的DSP的指令集都包含有显式的MAC指令。
2 存储器结构
传统上,GPP使用冯诺依曼存储器结构。这种结构中,只有一个存储器空间通过一组总线(一个地址总线和一个数据总线)连接到处理器核。通常,做一次乘法会发生4次存储器访问,用掉至少四个指令周期。
大多数DSP采用了哈佛结构,将存储器空间划分成两个,分别存储程序和数据。它们有两组总线连接到处理器核,允许同时对它们进行访问。这种安排将处理器存贮器的带宽加倍,更重要的是同时为处理器核提供数据与指令。在这种布局下,DSP得以实现单周期的MAC指令。
还有一个问题,即现在典型的高性能GPP实际上已包含两个片内高速缓存,一个是数据,一个是指令,它们直接连接到处理器核,以加快运行时的访问速度。从物理上说,这种片内的双存储器和总线的结构几乎与哈佛结构的一样了。然而从逻辑上说,两者还是有重要的区别。
GPP使用控制逻辑来决定哪些数据和指令字存储在片内的高速缓存里,其程序员并不加以指定(也可能根本不知道)。与此相反,DSP使用多个片内存储器和多组总线来保证每个指令周期内存储器的多次访问。在使用DSP时,程序员要明确地控制哪些数据和指令要存储在片内存储器中。程序员在写程序时,必须保证处理器能够有效地使用其双总线。
此外,DSP处理器几乎都不具备数据高速缓存。这是因为DSP的典型数据是数据流。也就是说,DSP处理器对每个数据样本做计算后,就丢弃了,几乎不再重复使用。
3 零开销循环
如果了解到DSP算法的一个共同的特点,即大多数的处理时间是花在执行较小的循环上,也就容易理解,为什么大多数的DSP都有专门的硬件,用于零开销循环。所谓零开销循环是指处理器在执行循环时,不用花时间去检查循环计数器的值、条件转移到循环的顶部、将循环计数器减1。
与此相反,GPP的循环使用软件来实现。某些高性能的GPP使用转移预报硬件,几乎达到与硬件支持的零开销循环同样的效果。
4 定点计算
大多数DSP使用定点计算,而不是使用浮点。虽然DSP的应用必须十分注意数字的精确,用浮点来做应该容易的多,但是对DSP来说,廉价也是非常重要的。定点机器比起相应的浮点机器来要便宜(而且更快)。为了不使用浮点机器而又保证数字的准确,DSP处理器在指令集和硬件方面都支持饱和计算、舍入和移位。
5 专门的寻址方式
DSP处理器往往都支持专门的寻址模式,它们对通常的信号处理 *** 作和算法是很有用的。例如,模块(循环)寻址(对实现数字滤波器延时线很有用)、位倒序寻址(对FFT很有用)。这些非常专门的寻址模式在GPP中是不常使用的,只有用软件来实现。
6 执行时间的预测
大多数的DSP应用(如蜂窝电话和调制解调器)都是严格的实时应用,所有的处理必须在指定的时间内完成。这就要求程序员准确地确定每个样本需要多少处理时间,或者,至少要知道,在最坏的情况下,需要多少时间。
如果打算用低成本的GPP去完成实时信号处理的任务,执行时间的预测大概不会成为什么问题,应为低成本GPP具有相对直接的结构,比较容易预测执行时间。然而,大多数实时DSP应用所要求的处理能力是低成本GPP所不能提供的。
这时候,DSP对高性能GPP的优势在于,即便是使用了高速缓存的DSP,哪些指令会放进去也是由程序员(而不是处理器)来决定的,因此很容易判断指令是从高速缓存还是从存储器中读取。DSP一般不使用动态特性,如转移预测和推理执行等。因此,由一段给定的代码来预测所要求的执行时间是完全直截了当的。从而使程序员得以确定芯片的性能限制。
思路:利用输入语句输入3个实数,用输出语句输出正序,用输出语句输出反序
/源程序如下:/
#include<stdioh>
int
main()
{
float x,y,z;/定义3个整数/
printf("请输入一个3个实数:");
scanf("%f,%f,%f",
&x,&y,&z);/输入3个数中间用逗号分开/
printf("依次输出这三个数为:%f,%f,%f\n“,x,y,z);
printf("倒序输出这三个数为:%f,%f,%f\n“,z,y,x)/将输出的三个数位置倒序即可/
return
0;
}
VC++60测试如下
请输入一个3个实数:1,2,3
依次输出这三个数为:100,200,300
倒序输出这三个数为:300,200,100
import javautil;//倒入的util中的包用Scanner类;
public class TestOhce {
public static void invertOrder(String s) { //这是倒序的字符串,用字符数组实现;
char[] cArray = stoCharArray();
for (int i = 0, j = cArraylength - 1; i < j; i++, j--) { //倒序算法;
char tmp; //设置一个中间字符变量;
tmp = cArray[j];
cArray[j] = cArray[i];
cArray[i] = tmp;
}
for (int i = 0; i < cArraylength; i++) {
Systemoutprint(cArray[i] + " ");
}
}
public void charIO() { //字符数组输出
Scanner s = new Scanner(Systemin);//输入一个字符串;
while (true) {
Systemoutprintln("intput: ");
String str = snext();//输入字符串赋值给str
if ("exit"equals(str)) {
Systemoutprintln("bye - bye");//判断是否退出;
} else {
thisinvertOrder(str);//调用倒序算法
}
}
}
public static void main(String[] args) {
new TestOhce()charIO();//创建对象;
}
}
0xf8000000在long 看来就是一个负数。
要改用unsigned long
#include<stdioh>
#include<mathh>
unsigned long fun(chars,int k);
unsigned long fun(chars,int k)//十六进制转十进制函数
{
unsigned long i,t;
unsigned long sum=0;
for(i=k;i<k+2;i++)
{
if(s[i]<='9')t=s[i]-'0';
else t=s[i]-'a'+10;
sum=sum16+t;
}
return sum;
}
int main()
{
char svid[8];
unsigned long svid1,svid2,svid3,svid4,svidnum,i;
for(i=0;i<8;i++)
{
scanf("%c",&svid[i]);
}
svid1=fun(svid,0);
svid2=fun(svid,2);//乘以2的8次方
svid3=fun(svid,4);//乘以2的16次方
svid4=fun(svid,6);//乘以2的24次方
svidnum=16777216svid4+65536svid3+256svid2+svid1;
//现在fp在空格上
printf("%u\n",svidnum);
return 0;
}
以上就是关于dsp中的FFT是如何实现信号的倒序输入全部的内容,包括:dsp中的FFT是如何实现信号的倒序输入、C语言输入任意3个实数,然后按倒序和依次输出怎么编程、用java编写一段程序,输入一段字符串,然后输出该字符串的倒序状态。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)