CUDA快速傅里叶变换 - cuFFT

CUDA为开发人员提供了多种库,每一类库针对某一特定领域的应用,CUFFT库则是CUDA中专门用于进行傅里叶变换的函数库,这一系列的文章是博主近一段时间对cuFFT库的学习总结,主要内容是文档的译文,其间夹杂一些博主自己的理解。初学CUDA,理解有误之处在所难免,阅读本篇文章的读者如若发现请不吝指正。

1. 简介

cuFFT是的全称是CUDA Fast Fourier Transform,顾名思义,它提供了一系列的函数帮助开发者进行快速傅里叶变换的运算。cuFFT库由两个子库构成,它们分别是CUFFT和CUFFTW。CUFFTW库是一个移植工具(porting tool),它为用户提供了一些接口,以使得用户使用FFTW库(一个非常流行的CPU快速傅里叶变换库)编写的程序能够运行在CUDA GPU上。而CUFFT则是纯CUDA接口的快速傅里叶变换库。

        在CUDA toolkit 5.5版本中,cuFFT库支持的特性有:

        1、对于可以表示为的输入规模,CUFFT会自动采用一些优化算法来达到最佳的运算性能

        2、对于所有的输入规模,CUFFT的算法复杂性均为O(nlogn)

        3、不同输入输出类型的指定:其中C2C代表输入输出均为复数,R2C代表输入为实数而输出为复数,C2R代表输入为复数而输出为实数。

        4、可以进行1维、2维和3维变换

        5、多个不同的1D、2D、3D变换可以并行进行

        6、同时支持单精度浮点和双精度浮点运算

        7、支持就地转换(输出直接覆盖输入)和外部转换(输出和输入不重叠)

        8、与FFTW库兼容的数据布局

        9、支持跨步输入数据读取

        10、支持流执行(Streamed execution),这样就同时支持了计算与数据传输的异步并行执行。

        11、对于单精度浮点数,一次最多传输128百万元素,双精度则一次最多传输64百万元素。

        12、CUFFT库提供的API是线程安全的。


2. 使用CUFFT API

        在关注具体的API之前,我们先来回顾一下快速傅里叶变换的背景知识。
        快速傅里叶变换(FFT)是离散傅里叶变换(DFT)的快速算法,在数字信号处理、大整数乘法和求解偏微分方程等领域都有着广泛的应用,DFT的作用是将时域(time domain)上的一组离散复数与到频域(frequency domain)上的一组值相互映射,以对输入数据进行进一步处理。离散傅里叶公式可以表示为:

其中,X k 是与输入数据 x k 大小相同的数组,这一公式也被称作正向(forward)DFT。把上式中e的指数符号修改为正(positive),我们就得到了逆向(inverse)DFT。CUFFT API根据N的不同,将使用不同的优化算法,以达到最佳的性能。
        CUFFT API的原型是FFTW库,FFTW则是一个基于CPU的高效FFT库。CUFFT提供了一个简单的被称为plan的配置方法,使用plan的好处是可以根据输入数据的大小预先配置好内存和计算资源,使得真正运算时处理器能达到最佳的性能。设置好plan后,运行execution函数,真正的傅里叶变换便开始执行了。一旦配置完成,配置信息便被保存起来,这对于多次调用来说非常省时。
        下面来看一个代码片段,计算BATCH块大小为NX的一维DFT的CUDA代码通常如下所示:
#define NX 256  
#define BATCH 10  
... {  
    cufftHandle plan;  
    cufftComplex *data;  
    ...  
    cudaMalloc((void**)&data, sizeof(cufftComplex)*NX*BATCH);  
    cufftPlan1d(&plan, NX, CUFFT_C2C, BATCH);  
    ...  
    cufftExecC2C(plan, data, data, CUFFT_FORWARD);  
    cudaThreadSynchronize();  
    ...  
    cufftDestroy(plan);  
    cudaFree(data);  
}  

2.1. 访问CUFFT(Accessing CUFFT)

        CUFFT和CUFFTW均被实现为共享库,可以使用编译器和链接器把它们集成到普通的程序当中。这些库文件和头文件在不同系统上的默认位置如下图所示:


最常见的使用这些库函数的方法是修改一个已经存在的CUDA文件,以filename.cu为例,在filename.cu中将头文件cufft.h包含进来,然后在程序中调用CUFFT库函数,为了使得程序可以运行,一个单一文件的编译和链接命令的形式可以如下:



2.2. 傅里叶变换配置(Fourier Transform Setup)

        在CUDA上进行傅里叶变换一般需要做以下几步工作:
        1. 创建一个plan。调用函数cufftPlan1D/cufftPlan2D/cufftPlan3D可以分别创建一个简单的1维/2维/3维的傅里叶变换。调用函数cufftPlanMany则可以创建支持更多配置操作的变换计划。
        2. 执行plan。这一步可以使用cufftExecC2C()、cufftExecR2C()或cufftExecC2R()等函数完成plan的计算任务。
        3. 执行完成以后若不再需要该plan,则调用cufftDestroy()函数销毁该plan及为其分配的计算资源。

2.3 傅里叶变换类型(Fourier Transform Types)

        CUFFT库实现了三种不同类型的傅里叶变换:C2C(复数到复数)、C2R(复数到实数)、R2C(实数到复数)。本质上,这三种转换都可以被看做是复数域到复数域的变换,之所以这样划分,其最主要的考量是性能因素。例如,在一般的数字信号处理中,输入数据是一些离散的实数域上的采样点,这时候对它们做傅里叶变换实际上就是R2C,根据埃尔米特对称性(Hermitian symmetry),变换后,*代表共轭复数。CUFFT的傅里叶变换类型则利用了这些冗余,将计算量降到最低。

        变换执行函数的单精度和双精度版本分别定义如下:

        1. cufftExecC2C() / cufftExecZ2Z() - 单精度/双精度浮点数复数域到复数域的傅里叶变换

        2. cufftExecR2C() / cufftExecD2Z() - 单精度/双精度浮点数实数域到复数域的傅里叶变换(正向傅里叶变换)

        3. cufftExecC2R() / cufftExecZ2D() - 单精度/双精度浮点数复数域到实数域的傅里叶变换(逆向傅里叶变换)

 

2.4 数据布局(Data Layout)

        CUFFT库包含有若干种数据类型,对于复数有cufftComplex / cufftDoubleComplex两种数据类型,对于实数则分别有cufftReal / cufftDouble两种数据类型。
        根据转换结果的存储位置不同,FFT变换可分为就地变换(in-place)和外部变换(out-of-place),前者直接在输入数据上进行变换,而后者则会将变换后的结果存入新的存储器地址。
        就地转换(in-place)支持两种数据布局:native和padded,前者用于获得最佳性能,而后者则用于与FFTW库兼容。
        在padded布局中输出信号的开始地址与输入信号一样,换句话说,实数域到复数域变换的输入数据和复数域到实数域的输出数据必须被填充。在native布局中则没有填充要求。
        输入数据和输出数据的尺寸总结如下:


2.5 流化CUFFT变换(Streamed CUFFT Transform)

        CUFFT的每一个plan都可以和某个流(stream)结合起来运行,一旦结合,那么该plan就会在特定的流上面运行。CUFFT执行的流化使得快速傅里叶变换可以和其它流中的数据拷贝任务并行运行,从而提高了设备利用率和程序性能。

2.6 线程安全(Thread Safety)

        CUFFT库从版本4.1开始拥有线程安全特性,也就是说,主机端的多个线程同时调用CUFFT中的函数时,CUDA可以保证任务执行的正确性。

http://blog.csdn.net/csgxy123/article/details/10525693

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
为了设计一个漂亮的Android为了设计一个漂亮的Android Studio App“我的”页面,你可以考虑以下几个步骤: Studio App“我的”页面,你可以考虑以下几个方面: 1.设计页面布局:你可以使用LinearLayout、RelativeLayout或Constraint1.页面布局:你可以使用LinearLayout、RelativeLayout或者ConstraintLayout等布局来设计你的页面。你需要考虑页面中包含哪些元素,例如头像、用户名、个人信息、设置选项等,Layout等布局方式来设计你的页面。在布局中,你需要考虑页面元素的大小、位置和排列方式,以及不同元素之间的间距和对齐方式并将它们放置在合适的位置。 2.添加控件:你可以使用TextView、ImageView、Button等控件来添加页面。 2.页面元素:你可以在页面中添加各种元素,例如TextView、ImageView、Button等。元素。例如,你可以使用ImageView来添加头像,使用TextView来添加用户名和个人信息,使用Button来添加设置你需要考虑元素的大小、颜色、字体、图标等,以及它们之间的排列方式和交互方式。 3.页面样式:你可以使用不同的样式来设计选项等。 3.设置控件属性:你可以设置控件的属性来改变它们的外观和行为。例如,你可以设置TextView的字体、你的页面,例如Material Design、Flat Design等。你需要考虑页面的整体风格和色彩搭配,颜色和大小,设置ImageView的大小和形状,设置Button的背景颜色和点击事件等。 4.添加交互功能:你可以使用Java代码来添加交互功能。例如,你可以使用setOnClickListener()方法来为Button添加点击事件,以及不同元素之间的协调性和一致性。 4.页面功能:你可以在页面中添加各种功能,例如个人信息、设置、消息通知等。使用setText()方法来改变TextView的文本内容,使用setBackgroundColor()方法来改变LinearLayout你需要考虑功能的实用性和易用性,以及它们之间的逻辑关系和交互方式。 下面是一个简单的Android Studio App的背景颜色等。 下面是一个简单的示例代码,它演示了如何使用LinearLayout、TextView和Button来设计“我的”页面设计示例,你可以参考一下: ```xml一个“我的”页面,并为Button添加了点击事件: ```java //<LinearLayout 在 Activity android中:添加以下layout代码_width ="LinearLayoutmatch_parent layout =" findViewById android(R:.id.mylayout_height_layout); ="TextViewmatch name_parent" androidView = findViewById:(R.idorientation.name="vertical_view); "> Button settingButton <ImageView = findViewById android(R:.idlayout.setting_button_width); //=" 设置100dp" TextView 的文 android:本内容layout_height name="View100.setTextdp("" John Smith android:"); src="@drawable///avatar " 为Button android添加:点击事件layout_gravity setting="Buttoncenter.setOnClickListener(new View.OnClickListener_horizontal()" { android @:Overridelayout _margin Top=" public50 voiddp onClick(View"/> v ) { <TextView // android 处:理layout点击_width="事件 wrap_content Toast" .makeText(getApplicationContext android:(), "layoutSetting_height clicked="wrap",_content Toast.LENGTH_SHORT" ).show android:text(); ="用户名 " } }); android:textSize```="20sp" android:textColor="#000000" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="个人信息" android:textSize="16sp" android:textColor="#FFFFFF" android:background="#FF04EDC9" android:layout_marginTop="50dp"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="设置" android:textSize="16sp" android:textColor="#FFFFFF" android:background="#FF04EDC9" android:layout_marginTop="20dp"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="消息通知" android:textSize="16sp" android:textColor="#FFFFFF" android:background="#FF04EDC9" android:layout_marginTop="20dp"/> </LinearLayout> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值