cuda - 在 GPU 上运行 FFTW 与使用 CUFFT

标签 cuda fftw cufft

我有一个基本的 C++ FFTW 实现,如下所示:

for (int i = 0; i < N; i++){
     // declare pointers and plan
     fftw_complex *in, *out;
     fftw_plan p;

     // allocate 
     in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
     out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

     // initialize "in"
     ...

     // create plan
     p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);

     // execute plan
     fftw_execute(p);

     // clean up
     fftw_destroy_plan(p);
     fftw_free(in); fftw_free(out);
}

我正在 for 循环中执行 N fft。我知道我可以使用 FFTW 一次执行多个计划,但在我的实现中,inout 每个循环都是不同的。重点是我正在 for 循环内执行整个 FFTW 管道。

我想转而使用 CUDA 来加快速度。据我所知,CUDA有自己的FFT库CUFFT。语法非常相似:来自他们的 online documentation :

#define NX 64
#define NY 64
#define NZ 128

cufftHandle plan;
cufftComplex *data1, *data2;
cudaMalloc((void**)&data1, sizeof(cufftComplex)*NX*NY*NZ);
cudaMalloc((void**)&data2, sizeof(cufftComplex)*NX*NY*NZ);
/* Create a 3D FFT plan. */
cufftPlan3d(&plan, NX, NY, NZ, CUFFT_C2C);

/* Transform the first signal in place. */
cufftExecC2C(plan, data1, data1, CUFFT_FORWARD);

/* Transform the second signal using the same plan. */
cufftExecC2C(plan, data2, data2, CUFFT_FORWARD);

/* Destroy the cuFFT plan. */
cufftDestroy(plan);
cudaFree(data1); cudaFree(data2);

但是,每个“内核”(Nvidia 称之为)(cufftPlan3d、cufftExecC2C 等)都是与 GPU 之间的调用。如果我正确理解 CUDA 结构,那么每个方法调用都是单独的并行操作:

#define NX 64
#define NY 64
#define NZ 128

cufftHandle plan;
cufftComplex *data1, *data2;
cudaMalloc((void**)&data1, sizeof(cufftComplex)*NX*NY*NZ);
cudaMalloc((void**)&data2, sizeof(cufftComplex)*NX*NY*NZ);
/* Create a 3D FFT plan. */
cufftPlan3d(&plan, NX, NY, NZ, CUFFT_C2C); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Transform the first signal in place. */
cufftExecC2C(plan, data1, data1, CUFFT_FORWARD); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Transform the second signal using the same plan. */
cufftExecC2C(plan, data2, data2, CUFFT_FORWARD); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Destroy the cuFFT plan. */
cufftDestroy(plan);
cudaFree(data1); cudaFree(data2);

我了解如何通过在 GPU 上运行每个 FFT 步骤来加速我的代码。但是,如果我想并行化整个 for 循环怎么办?如果我希望原始 N 个 for 循环中的每一个都在 GPU 上运行整个 FFTW 管道该怎么办?我可以创建自定义“内核”并从设备 (GPU) 调用 FFTW 方法吗?

最佳答案

您无法从设备代码调用 FFTW 方法。 FFTW 库是编译的 x86 代码,不会在 GPU 上运行。

如果代码中的“繁重工作”是 FFT 运算,并且 FFT 运算的大小相当大,那么只需按指示调用 cufft 库例程即可为您带来良好的加速并大致充分利用机器。一旦机器被充分利用,尝试并行运行更多的东西通常不会有额外的好处。

袖口例程can be called by multiple host threads ,因此可以多次调用 cufft 来进行多个独立的变换。如果单个转换足够大以利用机器,您不太可能从中看到很大的加速。

cufft还支持batched plans这是“一次”执行多个转换的另一种方式。

关于cuda - 在 GPU 上运行 FFTW 与使用 CUFFT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16780258/

相关文章:

c++ - cuFFT 的 NaN 问题

cufft 正在将随机数据添加到结果中

c - 在 C 中使用 FFTW 的高通滤波器

c - 每个 block 的最大线程数

macos - nvcc 未知选项 -no_pie

cuda - 寄存器溢出是否可能导致 CUDA_EXCEPTION_5,Warp Out-Of-Range Address 错误?

c - 在函数内部使用 fftw3 会产生段错误

c - FFTW3 向后对我不起作用

cuda - CUDA 中 3D 矩阵的列和行的 1D FFT

CUDA线程执行顺序