C++学习|CUFFT计算一维傅里叶变换

news2024/11/17 6:36:48

CUFFT计算一维傅里叶变换

  • CUFFT库介绍
  • CUFFTW计算一维傅里叶变换
  • CUFFT计算一维傅里叶变换

前言:之前实现了CPU运行一维傅里叶变换,最近要改成GPU加速一维傅里叶变换,于是有了此篇作为记录,方便以后查阅。

CUFFT库介绍

CUFFT(CUDA Fast Fourier Transform):CUDA提供了一系列的函数帮助开发者进行快速傅里叶变换的运算。

CUFFT库构成:两个子库分别是CUFFT和CUFFTW。

  • CUFFTW:提供了一些接口,使得用户使用FFTW库(CPU快速傅里叶变换库,FFTW3文章有讲解过安装和使用)编写的程序能够运行在GPU上。其实意思就是FFTW CPU编写的代码可以用在CUFFTW GPU,因为它们的接口名字相同。这提高使用FFTW现有代码的可移植性。
  • CUFFT:是纯CUDA接口的快速傅里叶变换库。

CUFFTW计算一维傅里叶变换

使用的傅里变换的函数和CPU的FFTW3一摸一样,但是要改动一些地方。

  • 在cuda配置的时候,“项目-属性-连接器-输入lib”的部分还要加上cufftw.lib,不然无法解析fftw函数。
  • 头文件fftw3.h改成cufftw.h。
  • 还要进行GPU内存管理。
  • 因为涉及到GPU内存管理所以要写在cu文件下(一开始犯糊涂,直接在cpp文件改了,结果发现和CPU运行的速度一样)。

.cu文件代码:

#include"cuda.cuh"
#include <cuda_runtime.h>
#include<device_launch_parameters.h>
#include <stdio.h>
#include<cufftw.h>

void fftFun(int n, double *in, double* out) {
    // FFTW默认使用双精度浮点数,所以这里用double
    // 傅里叶变换数据
    fftw_complex* DataIn = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * n);
    fftw_complex* DataOut = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * n);
    fftw_plan Plan = fftw_plan_dft_1d(n, DataIn, DataOut, FFTW_FORWARD, FFTW_ESTIMATE);
    // 数据从cpu拷贝到gpu
    for (int i = 0; i < n; i++) {
        DataIn[i][0] = in[i];
    }
    // 进行傅里叶变换
    fftw_execute(Plan);
    // 数据从GPU拷贝回GPU
    for (int i = 0; i < n / 2; i++) {
        out[i] = sqrt(DataOut[i][0]*DataOut[i][0] + DataOut[i][1]*DataOut[i][1])/(n/2);// 计算振幅
    }
    // 销毁
    fftw_free(DataIn);
	fftw_free(DataOut);
	fftw_destroy_plan(Plan);
    return;
}

如何判断CUDA有没有用上,可以在任务管理器中看程序运行后CUDA调用GPU的情况。
在这里插入图片描述

CUFFT计算一维傅里叶变换

注意的点:

  • 在cuda配置的时候,“项目-属性-连接器-输入lib”的部分还要加上cufft.lib,不然无法解析fftw函数。
  • 头文件加上cufft.h。
  • 在.cu文件中编写,因为涉及到GPU内存管理。

.cu文件核心函数:

void fftFun(int n, cufftComplex* in, cufftComplex* out) {
    // 傅里叶变换数据
    // 这里cufftComplex是单精度的,如果要用双精度改为cufftDoubleComplex
    cufftComplex* DataIn, * DataOut;
    cudaMalloc((void**)&DataIn, sizeof(cufftComplex) * n);
    cudaMalloc((void**)&DataOut, sizeof(cufftComplex) * n);
    cufftHandle Plan;
    cufftPlan1d(&Plan, n, CUFFT_C2C, 1);// 双精度cufftPlan1d(&Plan, n, CUFFT_Z2Z, 1);
    // 把CPU数据复制到GPU
    cudaMemcpy(in, DataIn, n* sizeof(cufftComplex), cudaMemcpyHostToDevice);
    // 傅里叶变换
    // CUFFT_FORWARD为正向FFT,CUFFT_INVERSE为逆向FFT
    cufftExecC2C(Plan, DataIn, DataOut, CUFFT_FORWARD);// 双精度cufftExecZ2Z(Plan, DataIn, DataOut, CUFFT_FORWARD);
    // 把GPU数据复制到CPU
    cudaMemcpy(DataOut, out, n * sizeof(cufftComplex), cudaMemcpyDeviceToHost);
    // 销毁GPU开辟的东西
    cufftDestroy(Plan);
    cudaFree(DataIn);
    cudaFree(DataOut);
    return;
}

.cpp文件main函数

int main()
{
	// 输入n,再输入n个要进行傅里叶变换的采样点
	int n;
	cin >> n;
	// CPU的傅里叶变换数据分配内存
	// 双精度改为cufftDoubleComplex
	cufftComplex* in = (cufftComplex*)malloc(n * sizeof(cufftComplex));
	cufftComplex* out = (cufftComplex*)malloc(n * sizeof(cufftComplex));
	for (int i = 0; i < n; i++) {
		cin >> in[i].x;
		in[i].y = 0;
	}
	fftFun(n, in, out);
	// 输出傅里叶变换后的振幅,傅里叶变换左右对称所以只需要n/2个点
	for (int i = 0; i < n/2; i++) {
		cout << sqrt(out[i].x * out[i].x + out[i].y * out[i].y) / (n / 2) << " ";;// 计算振幅
	}
	cout << endl; 
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/956876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Protein - ECD (ExtraCellular Domain) 膜蛋白胞外区的 UniProt 与 PDB 数据分析

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132597158 ECD 是 Extracellular Domain 的缩写&#xff0c;指的是跨膜蛋白质的细胞外部分 (膜蛋白的胞外区)&#xff0c;通常包含一些功能性的结…

JVM的故事——类文件结构

类文件结构 文章目录 类文件结构一、概述二、无关性基石三、Class类文件的结构 一、概述 计算机是只认由0、1组成的二进制码的&#xff0c;不过随着发展&#xff0c;我们编写的程序可以被编译成与指令集无关、平台中立的一种格式。 二、无关性基石 对于不同平台和不同平台的…

77GHz线性调频连续波雷达

文章目录 前言 一、背景 二、优缺点 三、工作原理 四、电路模块设计 4.1.LFMCW信号源 4.2.发射电路 4.3.接收电路 4.4.信号处理器 五、应用 5.1.汽车测距 5.2.军事方面 5.3.气象方面 总结 前言 这篇文章是博主本科期间整理的关于77GHz线性调频连续波雷达的相关资料&#xff0c;…

【Java】文件操作和IO

文件操作和IO 文件树形结构组织和目录文件路径 Java中操作文件File 文件内容的读写(数据流)Reader和Writer字符输入流 Reader字符输出流 WriterFileReader 和 FileWriterFileReaderFileWriter InputStream和OutputStreamInputStreamFileInputStreamFileOutputStream 小程序扫描…

Vue3实现24小时倒计时

方法一:时间戳(24小时以内,毫秒为单位)转成时间,并且倒计时 效果预览: <script> // 剩余时间的时间戳,24小时的时间戳是86400000 const exTime = ref(86400000) // 支付时间期限 const payTime = ref() const maxtime = ref(0) //倒计时(时间戳,毫秒单位)转换成秒…

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

OPENCV实现ORB特征检测

# -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/8/31 """ import cv2 import numpy as np# 读图像 img = cv2.imread(F:\\learnOpenCV\\openCVLearning\\pictures\\chess.jpg)

应急日光灯 补光灯 太阳能路灯 升压LED电源驱动恒流IC

产品说明 AP9196 是一系列外围电路简洁的宽调光比升压调光 恒流驱动器&#xff0c;适用于 3-40V 输入电压范围的 LED 照明领域。 AP9196 采用我司专利算法&#xff0c;可以实现高精度的恒流 效果&#xff0c;输出电流恒流精度≤3&#xff05;&#xff0c;电压工作范围为 5-40V&…

重庆市人才系统注册流程

1、IE浏览器打开重庆市科技局官网首页(http://kjj.cq.gov.cn/) 2、选择“重庆市科技管理信息系统”—选择“科技资源共享”—板块—注册—选择“个人注册”—填写注册信息—注册 3、注册—选择“个人注册”—填写注册信息—注册—登录 4、选择“科技管理系统“ 5、选择“科技人…

Linux进程概念及其状态

文章目录 &#x1f347;1. 什么是进程&#x1f348;1.1 概念&#x1f348;1.2 理解进程 &#x1f34b;2. Linux的PCB&#x1f34e;3. 查看进程 & 杀死进程&#x1f352;4. 系统调用获取进程标识符&#x1f353;4.1 进程PID&#x1f353;4.2 父进程PPID &#x1f346;5. 系统…

MetInfo5.0文件包含漏洞

MetInfo历史版本与文件 环境在这里下载&#xff0c;使用phpstudy搭建 我们来看到这个index.php&#xff0c;如下图所示&#xff0c;其中定义了fmodule变量与module变量&#xff0c;其中require_once语句表示将某个文件引入当前文件&#xff0c;在这个代码中&#xff0c;通过r…

【JasperReports笔记06】JasperReport报表开发之常见的组件元素(Table、Subreport、Barcode等)

这篇文章&#xff0c;主要介绍JasperReport报表开发之常见的组件元素&#xff08;Table、Subreport、Barcode等&#xff09;。 目录 一、基础组件元素 1.1、StaticText 1.2、TextField 1.3、Image 1.4、Break分页 1.5、Rectangle矩形区域 1.6、Ellipse椭圆区域 1.7、Li…

基于MQTT协议的物联网关

随着工业领域的不断发展&#xff0c;数字化转型已经成为企业迈向未来的必由之路。在这个数字化浪潮中&#xff0c;HiWoo Box以其强大的功能和创新的设计&#xff0c;在工业物联网领域被越来越多的人所熟知。特别是其基于MQTT协议的物联网关能力&#xff0c;也为企业实现智能化数…

喷泉码浅谈

01、喷泉码简介 喷泉码&#xff08;Fountain Code&#xff09;是一种在无线通信、数据传输和网络编码领域中使用的错误纠正技术。它与传统的纠错码和编码方法有所不同&#xff0c;喷泉码被设计用于在不确定信道条件下的高效数据传输。传统的纠错码&#xff08;如海明码、RS码等…

无涯教程-Android - RadioButton函数

RadioButton有两种状态:选中或未选中,这允许用户从一组中选择一个选项。 Radio Button 示例 本示例将带您完成一些简单的步骤,以展示如何使用Linear Layout和RadioButton创建自己的Android应用程序。 以下是修改后的主要Activity文件 src/MainActivity.java 的内容。 packa…

【算法】函数渐近的界基础知识及定理

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Spring依赖注入(DI)

目录 构造器注入 set注入 拓展注入 bean的作用域 Singleton Prototype Dependency Injection 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 . 构造器注入 具体实现&#xff1a;SpringIOC创建对象的…

电力行业浪涌保护器应用方案

电力行业是一个涉及到高压、大电流、复杂环境的领域&#xff0c;对于电气设备的安全和可靠性有着极高的要求。在电力行业中&#xff0c;浪涌是一种常见的电力质量问题&#xff0c;它指的是在电气系统中出现的瞬时过电压或过电流&#xff0c;可能由雷击、开关操作、短路故障等因…

算法通关村——解析堆的应用

在数组中找第K大的元素 LeetCode21 Medium 我们要找第 K 大的元素&#xff0c;如果我们找使用大堆的话那么就会造成这个堆到底需要多大的&#xff0c;而且哪一个是第 K 的的元素我们不知道是哪一个索引&#xff0c;我们更想要的结果就是根节点就是我们要找的值&#xff0c;所以…

java之SpringBoot基础、前后端项目、MyBatisPlus、MySQL、vue、elementUi

文章目录 前言JC-1.快速上手SpringBootJC-1-1.SpringBoot入门程序制作&#xff08;一&#xff09;JC-1-2.SpringBoot入门程序制作&#xff08;二&#xff09;JC-1-3.SpringBoot入门程序制作&#xff08;三&#xff09;JC-1-4.SpringBoot入门程序制作&#xff08;四&#xff09;…