并行计算课程设计任务书讲义Word文档下载推荐.docx
《并行计算课程设计任务书讲义Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《并行计算课程设计任务书讲义Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
1.3测试实例
对给定的
,利用串行FFT递归算法
(蝶式递归计算原理)计算其傅里叶变换的结果。
二.设计算法及要求
2.1算法设计原理
令为n/2次单位元根,则有.
将b向量的偶数项和奇数项分别记为
和注意推导中反复使用
2.2算法设计
对于以上的分析可画出如图1所示的离散傅里叶变换递归计算流图。
图1n=8的FFT蝶式计算图
三.算法描述与设计流程
3.1算法描述
3.2流程图
输入序列对应值(例如5+j3,输入53)
计算出前size_x/2个
exp(-j*2π*k/size_x)个值,
即W的值
级数i>
=错误!
未找到引用源。
?
输出fft结果序列
结束
计算出该级需要的W的个数l
该级该组起始下标j>
级数i加1
组起始下标加2*l
该级该组元素序数k>
X[j+k]X[j+k]l
X[j+k+l]*W[(size_x/2/l)*k]X[j+k+l]
-1
K加1
是
否
是
否
图2算法设计流程图
四.原程序代码与运行结果
4.1源程序
/************FFT***********///整个程序输入和输出利用同一个空间x[N],节约空间
#include<
stdio.h>
math.h>
stdlib.h>
#defineN1000//定义输入或者输出空间的最大长度
typedefstruct
{
doublereal;
doubleimg;
}complex;
//定义复数型变量的结构体
voidfft();
//快速傅里叶变换函数声明
voidinitW();
//计算W(0)~W(size_x-1)的值函数声明
voidchange();
//码元位置倒置函数函数声明
voidadd(complex,complex,complex*);
/*复数加法*/
voidmul(complex,complex,complex*);
/*复数乘法*/
voidsub(complex,complex,complex*);
/*复数减法*/
voiddivi(complex,complex,complex*);
/*复数除法*/
voidoutput();
/*输出结果*/
complexx[N],*W;
/*输出序列的值*/
intsize_x=0;
/*输入序列的长度,只限2的N次方*/
doublePI;
//pi的值
intmain()
inti;
system("
cls"
);
PI=atan
(1)*4;
printf("
Pleaseinputthesizeofx:
\n"
/*输入序列的长度*/
scanf("
%d"
&
size_x);
Pleaseinputthedatainx[N]:
(suchas:
56)\n"
/*输入序列对应的值*/
for(i=0;
i<
size_x;
i++)
%lf%lf"
x[i].real,&
x[i].img);
initW();
//计算W(0)~W(size_x-1)的值
fft();
//利用fft快速算法进行DFT变化
output();
//顺序输出size_x个fft的结果
return0;
}
/*进行基-2FFT运算,蝶形算法。
这个算法的思路就是,
先把计算过程分为log(size_x)/log
(2)-1级(用i控制级数);
然后把每一级蝶形单元分组(用j控制组的第一个元素起始下标);
最后算出某一级某一组每一个蝶形单元(用k控制个数,共l个)。
*/
voidfft()
{
inti=0,j=0,k=0,l=0;
complexup,down,product;
change();
//实现对码位的倒置
log(size_x)/log
(2);
i++)//循环算出fft的结果
l=1<
<
i;
for(j=0;
j<
j+=2*l)
//算出第m=i级的结果【i从0到(log(size_x)/log
(2))-1】
for(k=0;
k<
l;
k++)//算出第i级内j组蝶形单元的结果
{//算出j组中第k个蝶形单元
mul(x[j+k+l],W[(size_x/2/l)*k],&
product);
/*size/2/l是该级W的相邻上标差,l是该级该组取的W总个数*/
add(x[j+k],product,&
up);
sub(x[j+k],product,&
down);
x[j+k]=up;
//up为蝶形单元右上方的值
x[j+k+l]=down;
//down为蝶形单元右下方的值
}
voidinitW()//计算W的实现函数
W=(complex*)malloc(sizeof(complex)*size_x);
/*申请size_x个复数W的空间(这部申请的空间有点多,
实际上只要申请size_x/2个即可)*/
for(i=0;
(size_x/2);
i++)
/*预先计算出size_x/2个W的值,存放,由于蝶形算法
只需要前size_x/2个值即可*/
W[i].real=cos(2*PI/size_x*i);
//计算W的实部
W[i].img=-1*sin(2*PI/size_x*i);
//计算W的虚部
voidchange()//输入的码组码位倒置实现函数
complextemp;
unsignedshorti=0,j=0,k=0;
doublet;
k=i;
j=0;
t=(log(size_x)/log
(2));
while((t--)>
0)
j=j<
1;
j|=(k&
1);
k=k>
>
if(j>
i)
temp=x[i];
x[i]=x[j];
x[j]=temp;
voidoutput()//输出结果实现函数
Theresultareasfollows\n"
%.4f"
x[i].real);
//输出实部
if(x[i].img>
=0.0001)//如果虚部的值大于0.0001,
输出+jx.img的形式
+j%.4f\n"
x[i].img);
elseif(fabs(x[i].img)<
0.0001)//如果虚部的绝对值
小于0.0001,无需输出
else
-j%.4f\n"
fabs(x[i].img));
//如果虚部的值小于-0.0001,输出-jx.img的形式
voidadd(complexa,complexb,complex*c)//复数加法实现函数
c->
real=a.real+b.real;
//复数实部相加
img=a.img+b.img;
//复数虚部相加
voidmul(complexa,complexb,complex*c)//复数乘法实现函数
real=a.real*b.real-a.img*b.img;
//获取相乘结果的实部
img=a.real*b.img+a.img*b.real;
//获取相乘结果的虚部
voidsub(complexa,complexb,complex*c)//复数减法实现函数
real=a.real-b.real;
//复数实部相减
img=a.img-b.img;
//复数虚部相减
voiddivi(complexa,complexb,complex*c)//复数除法实现函数
real=(a.real*b.real+a.img*b.img)/(b.real*b.real+b.img*b.img);
//获取相除结果的实部
img=(a.img*b.real-a.real*b.img)/(b.real*b.real+b.img*b.img);
//获取相除结果的虚部
4.2运行结果
图3运行结果图
五.算法分析及其优缺点
5.1算法分析
(1)FFT算法的基本原理是把长序列的DFT逐次分解为较短序列的DFT。
按照抽取方式的不同可分为DIT-FFT(按时间抽取)和DIF-FFT(按频率抽取)算法。
按照蝶形运算的构成不同可分为基2、基4、基8以及任意因子(2n,n为大于1的整数),基2、基4算法较为常用[5]。
(2)总体结构说明,输入数据为串行的数据流,故在第一级蝶形运算模块前加入串并转换模块,将串行数据流转换为并行的两列数据流以适应基2蝶形运算模块的输入信号要求。
由于每级蝶形运算一次处理的两个输入数据不能直接由前一级蝶形运算一次性输出,故在两个蝶形运算单元之间插入延时对齐模块,将前一级蝶形运算的结果(两列并行的数据流)作适当的延时并通过转接器对齐,形成后一级蝶形运算模块所需要的2列输入序列[6]。
在最后一级蝶形运算后加入串并转换模块,将2列并行的数据流合成为1列。
最后加入倒序模块将DIF-FFT得到的倒序输出序列整理为顺序输出。
基2蝶形运算模块由两个复数加法器和一个复数乘法器构成。
旋转因子由ROM产生后,作为复数乘法器的输入之一,与前面复数加法器得到的结果相乘完成一次蝶形运算。
为提高系统的运行速度可在蝶形运算单元中插入流水线寄存中间结果[2]。
(3)蝶形运算单元如图所示:
图4蝶式运算单元图
5.2优缺点
优点:
相对于DFT算法,FFT算法较高的效率,其基本思想是利用权函数
的周期性、对称性、特殊性及周期
的互换性,将
点DFT运算逐次分解为较短序列的DFT运算。
因DFT的运算量与序列长度的平方成比,故序列分解可大大减少运算量[10]。
从FFT算法实现角度讲,应具有运算量较少、结构规整、易实现、可同址运算、内部数据不需重拍等特点。
缺点:
由于定点乘法运算时间和占用资源都比定点加法都多得多,因此硬件实现定点FFT算法时,一般以乘法次数作为预算量的度量,对于浮点操作,因加法流水线比乘法流水线长,故不能忽略浮点加法运算时间而只根据浮点乘法运算次数推断计算时间[10]。
六.总结
这次课程设计是个难得的机会,可以让我们把所学的理论与实际相结合。
通过这次比较完整的一个程序的设计,我走出了纯理论的学习,从一种全新的角度去学习。
并且实现MPI运行过程中,除去知识的大量更新,我学到了很多东西。
其实个人而言,我体会较深的一点是团队互相帮助学习的过程,自己看书学习的经验,以及从网上或其他途径获得信息和知识的经验。
理论与实际相结合的设计,锻炼了我综合运用所学的基础知识,解决实际问题的能力,同时也提高我查阅文献资料、对程序整体的把握等其他能力水平。
而且通过对整体的掌控,对局部的取舍,以及对细节的斟酌处理,都使我的能力得到了锻炼,我的各方面经验都得到了极大的丰富。
这次课程设计,感谢老师在这一周的教导,每天陪着我们,解答我们的疑难,也监督我们的学习。
当然,同学们的帮助也是很重要的,我们互相讨论,虽然课题并不完全一样,可是解决方法却大同小异,各方面知识都要运用到,合作就显得至关重要。
总之,完成这次课程设计,我学到了很多。
希望学校以后多开设些课程设计,多些机会来锻炼我们。
七.参考文献
[1]陈国良,并行计算-结构·
算法·
编程(修订版)[M],北京:
高等教育出版社,2003.
[2]陈国良,并行算法的设计与分析[M],北京:
高等教育出版社,2002.
[3]陈国良,并行计算机体系结构[M],北京:
[4]李晓梅,并行算法[M],长沙:
湖南科技出版社,1992.
[5]沈志宇,并行程序设计[M],长沙:
国防科大出版社,1997.
[6]孙家昶,网络并行计算与分布式编程环境[M],北京:
科学出版社,1996.
[7]王鼎兴,陈国良编著,互联网络结构分析[M],北京:
科学出版社,1990.
[8]许士良,计算机常用算法(第二版)[M],北京:
清华大学出版社,1996.
[9]都志辉,高性能计算并行技术—MPI并行设计[M],北京:
清华大学出版社,2001.
[10]牟胜梅,面向可重构系统的几种常用算法及其实现技术研究,中国知网[J],(第一卷)04069007:
118,2008.