Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 策略-在多幅图像上计算2D FFT_Image_Matlab_Cuda_Cufft - Fatal编程技术网

Image 策略-在多幅图像上计算2D FFT

Image 策略-在多幅图像上计算2D FFT,image,matlab,cuda,cufft,Image,Matlab,Cuda,Cufft,我使用袖口对128幅图像进行二维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幅图像进行二维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
...
因此,我可以预期,如果我将2D FFT应用于所有128幅图像,执行时间将与MATLAB差不多


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

首先,我建议对代码进行评测。你不必分析所有100张图片,但可能需要2-5张图片

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

另外,与上述内容相关,我建议尝试使用CUFFT batch参数将可能2-5个图像变换批处理在一起,以查看它是否会净减少100个图像的总体处理时间

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


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

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

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

另外,与上述内容相关,我建议尝试使用CUFFT batch参数将可能2-5个图像变换批处理在一起,以查看它是否会净减少100个图像的总体处理时间

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

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