|
考虑一个数字信号处理的实例,比如有限冲击响应滤波器(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 一般不使用动态特性,如转移
预测和推理执行等。因此,由一段给定的代码来预测所要求的执行时间是完
全直截了当的。从而使程序员得以确定芯片的性能限制。
7 定点DSP 指令集
定点DSP 指令集是按两个目标来设计的:
使处理器能够在每个指令周期内完成多个操作,从而提高每个指令周期的计
算效率。
将存贮DSP 程序的存储器空间减到最小(由于存储器对整个系统的成本影响
甚大,该问题在对成本敏感的DSP 应用中尤为重要)。
为了实现这些目标,DSP 处理器的指令集通常都允许程序员在一个指令内说
明若干个并行的操作。例如,在一条指令包含了MAC 操作,即同时的一个或
两个数据移动。在典型的例子里,一条指令就包含了计算FIR 滤波器的一节
所需要的所有操作。这种高效率付出的代价是,其指令集既不直观,也不容
易使用(与GPP 的指令集相比)。
GPP 的程序通常并不在意处理器的指令集是否容易使用,因为他们一般使用
象C 或C++等高级语言。而对于DSP 的程序员来说,不幸的是主要的DSP 应
用程序都是用汇编语言写的(至少部分是汇编语言优化的)。这里有两个理
由:首先,大多数广泛使用的高级语言,例如C,并不适合于描述典型的DSP
算法。其次,DSP 结构的复杂性,如多存储器空间、多总线、不规则的指令
集、高度专门化的硬件等,使得难于为其编写高效率的编译器。
即便用编译器将C 源代码编译成为DSP 的汇编代码,优化的任务仍然很重。
典型的DSP 应用都具有大量计算的要求,并有严格的开销限制,使得程序的
优化必不可少(至少是对程序的最关键部分)。因此,考虑选用DSP 的一个
关键因素是,是否存在足够的能够较好地适应DSP 处理器指令集的程序员。
8 开发工具的要求
因为DSP 应用要求高度优化的代码,大多数DSP 厂商都提供一些开发工具,
以帮助程序员完成其优化工作。例如,大多数厂商都提供处理器的仿真工具,
以准确地仿真每个指令周期内处理器的活动。无论对于确保实时操作还是代
码的优化,这些都是很有用的工具。
GPP 厂商通常并不提供这样的工具,主要是因为GPP 程序员通常并不需要详
细到这一层的信息。GPP 缺乏精确到指令周期的仿真工具,是DSP 应用开发
者所面临的的大问题:由于几乎不可能预测高性能GPP 对于给定任务所需要
的周期数,从而无法说明如何去改善代码的性能。
|
|