【问题标题】:Strategy - CUFFT computing 2D FFT on many images策略 - CUFFT 在许多图像上计算 2D FFT
【发布时间】:2016-07-26 04:42:43
【问题描述】:

我在 128 张图像上使用 CUFFT 进行 2D FFT。每个图像的大小为 128 x 128。在 MATLAB 上,执行一次 2D FFT 需要 0.3 毫秒,而对所有 128 幅图像执行 FFT 几乎是该毫秒数的 128 倍。使用 CUFFT,执行以下代码计算一张图像的 FFT

cudaMalloc( (void**)idata, sizeof(cufftDoubleReal) * 128 * 128 );
cudaMalloc( (void**)odata, sizeof(cufftDoubleComplex) * 128 * 128 );
cudaMemcpy( *idata, in_real, 128 * 128 * sizeof(cufftDoubleReal), 
                                  cudaMemcpyHostToDevice );
cudaMemcpy( *idata, in_complex, 128 * 128 * sizeof(cufftDoubleComples), 
                                  cudaMemcpyHostToDevice );

cufftExecD2Z( plan, idata, odata );
cudaMemcpy( out_complex, *odata, 128 * 128 * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost );

在我的机器上大约需要 0.4 毫秒。

我试过对不止一张图片执行相同的代码,执行时间基本上是图片数量的0.4ms的倍数。我这样做的方式,基本上就是多次复制粘贴上面的代码,当然,对应的图片也改变了变量,也就是说

// For image1
cudaMalloc( (void**)idata, sizeof(cufftDoubleReal) * 128 * 128 );
cudaMalloc( (void**)odata, sizeof(cufftDoubleComplex) * 128 * 128 );
cudaMemcpy( *idata, in_real, 128 * 128 * sizeof(cufftDoubleReal), 
                                  cudaMemcpyHostToDevice );
cudaMemcpy( *idata, in_complex, 128 * 128 * sizeof(cufftDoubleComples), 
                                  cudaMemcpyHostToDevice );
cufftExecD2Z( plan, idata, odata );
cudaMemcpy( out_complex, *odata, 128 * 128 * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost );

// For image 2
cudaMalloc( (void**)idata2, sizeof(cufftDoubleReal) * 128 * 128 );
cudaMalloc( (void**)odata2, sizeof(cufftDoubleComplex) * 128 * 128 );
cudaMemcpy( *idata2, in_real2, 128 * 128 * sizeof(cufftDoubleReal), 
                                  cudaMemcpyHostToDevice );
cudaMemcpy( *idata2, in_complex2, 128 * 128 * sizeof(cufftDoubleComples), 
                                  cudaMemcpyHostToDevice );
cufftExecD2Z( plan, idata2, odata2 );
cudaMemcpy( out_complex, *odata2, 128 * 128 * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost );
...
// For image N
...

所以我可以预期,如果我对所有 128 个图像应用 2D FFT,执行时间将与 MATLAB 的执行时间几乎相同。

所以我的问题是:我应用执行的方式是否正确?我是否充分利用了 GPU 的并行计算能力?我是否应该修改执行代码的方式,例如,首先对所有 128 个图像执行 cudaMemcpy 并执行它们,以便重叠一些 CPU 和 GPU 执行?

【问题讨论】:

    标签: image matlab cuda cufft


    【解决方案1】:

    首先,我建议分析您的代码。您不必分析所有 100 张图像,但可能需要 2-5 张图像。

    根据配置文件数据,您应该比较传输数据所花费的时间与 CUFFT 操作所花费的时间。如果它们大致相等(或者如果您可以直观地看到重叠将是有益的),则尝试复制和(CUFFT)计算的重叠,您将使用 CUDA 流来完成此操作。有很多关于 CUDA 流使用的教程以及关于 CUDA 标签(包括 CUFFT 标签)的示例问题,其中讨论了使用流和使用带有 CUFFT 的流。

    另外,但与上述相关,我建议尝试使用 CUFFT 批处理参数来批处理可能 2-5 个图像变换,看看它是否会净减少 100 个图像的整体处理时间。

    您实际上可以将这两个想法结合起来,这意味着您可以分批执行转换,然后使用 CUDA 流使用复制/计算重叠,将与一批图像关联的复制操作与前一批的计算操作重叠。

    除此之外,cudaMalloc 操作的成本很高。最好不要将它们放在性能(计算)循环中,这意味着,如果可能的话,在您的代码中预先运行它们一次。最好分配您需要的所有空间(例如 2-3 批图像),然后重新使用空间,而不是为每个图像分配新空间。

    【讨论】:

      猜你喜欢
      • 2012-12-11
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 2017-11-10
      • 1970-01-01
      相关资源
      最近更新 更多