CUDA cufftPlanMany的用法_31通道32*8像素的FFT
#include <cufft.h>
#include <iostream>
#include <cuda_runtime.h>
#include <helper_cuda.h>
#include <stdio.h>
using namespace std;
#define CHANNEL_NUM 31 //通道数、FFT次数
const int dataH = 32; //图像高度
const int dataW = 8; //图像宽度
cufftHandle fftplanfwd;//创建句柄
int main(void){
/* 开辟主机端的内存空间 */
printf("文件名planmany_cuda31.cu...\n");
printf("分配CPU内存空间...\n");
cufftComplex *h_Data = (cufftComplex*)malloc(dataH*CHANNEL_NUM*dataW* sizeof(cufftComplex));//可用cudaMallocHost设置
cufftComplex *h_resultFFT = (cufftComplex*)malloc(dataH*CHANNEL_NUM*dataW* sizeof(cufftComplex));
/* 开辟设备端的内存空间 */
printf("分配GPU内存空间...\n");
/* 定义设备端的内存空间 */
cufftComplex *d_Data;//device表示GPU内存,存储从cpu拷贝到GPU的数据
cufftComplex *fd_Data;//device表示GPU内存,R2C后存入cufftComplex类型数据
checkCudaErrors(cudaMalloc((void**)&d_Data, dataH*CHANNEL_NUM*dataW* sizeof(cufftComplex)));
checkCudaErrors(cudaMemset(d_Data, 0, dataH*CHANNEL_NUM * dataW* sizeof(cufftComplex))); // 初始为0
checkCudaErrors(cudaMalloc((void**)&fd_Data, dataH*CHANNEL_NUM*dataW* sizeof(cufftComplex))); // 开辟R2C后的设备内存
checkCudaErrors(cudaMemset(fd_Data, 0, dataH*CHANNEL_NUM*dataW* sizeof(cufftComplex))); // 初始为0
//随机初始化测试数据
printf("初始化测试数据...\n");
for (int i = 0; i < dataH*CHANNEL_NUM; i++){
for (int j = 0; j < dataW; j++){
h_Data[i*dataW + j].x = float(rand()%255);
h_Data[i*dataW + j].y = float(rand()%255);
}
}
//使用event计算时间
float time_elapsed = 0;
cudaEvent_t start, stop;
cudaEventCreate(&start); //创建Event
cudaEventCreate(&stop);
const int rank = 2;//维数
int n[rank] = { 32, 8 };//n*m
int*inembed = n;//输入的数组size
int istride = 1;//数组内数据连续,为1
int idist = n[0] * n[1];//1个数组的内存大小
int*onembed = n;//输出是一个数组的size
int ostride = 1;//每点DFT后数据连续则为1
int odist = n[0] * n[1];//输出第一个数组与第二个数组的距离,即两个数组的首元素的距离
int batch = CHANNEL_NUM;//批量处理的批数
//采用cufftPlanMany方法
checkCudaErrors(
cufftPlanMany(&fftplanfwd, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, batch));//针对多信号同时进行FFT
//printf("拷贝CPU数据到GPU中...\n");
checkCudaErrors(
cudaMemcpy(d_Data, h_Data, dataW * dataH*CHANNEL_NUM * sizeof(cufftComplex), cudaMemcpyHostToDevice));
//printf("执行R2C-FFT...\n");
printf("开始计时...\n");
cudaEventRecord(start, 0); //记录当前时间
checkCudaErrors(
cufftExecC2C(fftplanfwd, d_Data, fd_Data, CUFFT_FORWARD));
cudaEventRecord(stop, 0); //记录当前时间
cudaEventSynchronize(start); //Waits for an event to complete.
cudaEventSynchronize(stop); //Waits for an event to complete.Record之前的任务
cudaEventElapsedTime(&time_elapsed, start, stop); //计算时间差
//cudaDeviceSynchronize();
//printf("拷贝GPU数据返回到CPU中...\n");
checkCudaErrors(
cudaMemcpy(h_resultFFT, fd_Data, dataW *dataH*CHANNEL_NUM * sizeof(cufftComplex), cudaMemcpyDeviceToHost));//将fft后的数据拷贝回主机
//printf("显示返回到CPU中的数据...\n");
//for (int i = 0; i < dataH*CHANNEL_NUM*dataW; i++){
// cout << "h_resultFFT[" << i << "]=" << h_resultFFT[i].x << " + " << h_resultFFT[i].y << " i" << endl;
//}
cudaEventDestroy(start); //destory the event
cudaEventDestroy(stop);
printf("执行时间:%f(ms)\n", time_elapsed);
/* 销毁句柄 */
checkCudaErrors(cufftDestroy(fftplanfwd));
/* 释放设备空间 */
checkCudaErrors(cudaFree(d_Data));
checkCudaErrors(cudaFree(fd_Data));
free(h_Data);
free(h_resultFFT);
return 0;
}
CUDA8.0版本+VS2013的编译环境
再谈FFT:
1、库利-图基提出的基于蝶形算法的FFT,当变换的序列数量是2^n个那么变换速度很快;所以再用FFT是经常需要判断需要变换点的数量,不是2^n个则需要补0凑齐。
2、做FFt分析时,幅值的大小与FFT选择的点数相关,但不影响分析的结果,在IFFT时已经做了处理,要得到真实的振幅大小,只要将得到的变换结果乘以2除以N即可。
3、一维FFT与二维FFT原理不一样,二维如果用一维fft函数变换,可以分按行向量傅里叶变换、或按列向量傅里叶变换,二维数组整体对应的傅里叶变换函数维fft2();cufft中对应cufftplan2D();多维对应cufftplanmany();
4、cufftplanmany()数据的接口是一个数组首地址。用法详解:比如你有n通道的j*k维二维数组,那么可以将n个j*k数组的数组存到一个(j*n)*k的二维数组中,然后给赋予函数这个二维数组的首地址,然后设置好原来是j*k维的二维数组,一共有n个这样的数组,且它们是连续存在的(可以看上面代码来理解)。
5、傅里叶变换的作用在于将时域的信号转化到频域来处理,对于两个时域上函数的卷积运算可以转化到频域的乘积上来处理.
CUDA cufftPlanMany的用法_31通道32*8像素的FFT的更多相关文章
- cuda中时间用法
转载:http://blog.csdn.net/jdhanhua/article/details/4843653 在CUDA中统计运算时间,大致有三种方法: <1>使用cutil.h中的函 ...
- 并行计算提升32K*32K点(32位浮点数) FFT计算速度(4核八线程E3处理器)
对32K*32K的随机数矩阵进行FFT变换,数的格式是32位浮点数.将产生的数据存放在堆上,对每一行数据进行N=32K的FFT,记录32K次fft的时间. 比较串行for循环和并行for循环的运行时间 ...
- 两通道实信号使用一个FFT同时计算算法
前言 在工程的实际应用场景中,往往是需要最省资源量.而DSP资源和BRAM资源对FPGA来说弥足珍贵. 对于同时存在多个通道的实信号需要做FFT而言,常规做法是每个通道用一个FFT IP,FFT IP ...
- Java NIO 文件通道 FileChannel 用法
FileChannel 提供了一种通过通道来访问文件的方式,它可以通过带参数 position(int) 方法定位到文件的任意位置开始进行操作,还能够将文件映射到直接内存,提高大文件的访问效率.本文将 ...
- CUDA 笔记
名词解释 SM :Streaming Multiprocessor 而 Block 大致就是对应到 SM 所有的blocks 按照流水线被送到6个SM中进行计算 在 Compute Ca ...
- 【CUDA学习】GPU硬件结构
GPU的硬件结构,也不是具体的硬件结构,就是与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor 最 ...
- C++ IO 详细用法
http://www.cnblogs.com/keam37/ keam所有 转载请注明出处 本文将分别从<iostream>,<sstream>,<fstream> ...
- CUDA学习ing..
0.引言 本文记载了CUDA的学习过程~刚开始接触GPU相关的东西,包括图形.计算.并行处理模式等,先从概念性的东西入手,然后结合实践开始学习.CUDA感觉没有一种权威性的书籍,开发工具变动也比较快, ...
- CUDA零内存拷贝 疑问考证
今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维 ...
随机推荐
- git报“commiter email "root@localhost.localdomain"does not match your user account”
首先检查账户邮箱配置是否正确,检查方法: git config --list 发现邮箱及帐号配置正确,但是git push时仍然报如题错误: 原因:git执行add.commit 时已经记录下了做了该 ...
- svn conflict问题解决办法
转自:http://www.cnblogs.com/aaronLinux/p/5521844.html 目录: 1. 同一处修改文件冲突 1.1. 解决方式一 1.2. 解决方式二 1.3. 解决总结 ...
- NGS基础 - 高通量测序原理
NGS基础 - 高通量测序原理 原创: 赑屃 生信宝典 2017-07-23 NGS系列文章包括NGS基础.转录组分析.ChIP-seq分析.DNA甲基化分析.重测序分析五部分内容. NGS基础系列文 ...
- BZOJ4033或洛谷3177 [HAOI2015]树上染色
BZOJ原题链接 洛谷原题链接 很明显的树形\(DP\). 因为记录每个点的贡献很难,所以我们可以统计每条边的贡献. 对于每一条边,设边一侧的黑点有\(B_x\)个,白点有\(W_x\),另一侧黑点有 ...
- 201621123008 《Java 程序设计》 第九周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至 ...
- 关于出现“对不起,您安装的不是正版应用...”的解决方法
由于Discuz X版本增加了对插件的版本检测,在安装时,可能会出现:"对不起,您安装的不是正版应用,安装程序无法继续执行"的提示,如下图: 唱唱反调小编在此给大家分享解决方法: ...
- .net利用NPOI生成excel文件
整理代码,这个是生成excel文件,用的是HSSF的方式,只能生成65535行,256列的数据,如果要看office07之后的生成,之前的随笔里提过.这个是一个完整的过程. 首先是已经查找好的数据,这 ...
- setInterval与setTimeout 的区别
setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码 用法: setInterval("alert( ...
- python学习 day2 (3月2日)
.if if else 和 if elif else 的区别是: 前者 判断第一个 判断完第二个 之后还会执行else: 后者是只有满足条件(即都不符合if.elif里的条件时才会进入else) 不清 ...
- kbmmw 5.02发布
5.02.00 May 27 2017 Important notes (changes that may break existing code) ========================= ...