我在 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 执行?