128 枚の画像で 2D FFT に CUFFT を使用しています。各画像のサイズは 128 x 128 です。MATLAB では、1 つの 2D FFT を実行するのに 0.3 ミリ秒かかり、128 枚の画像すべてに対して FFT を実行するには、そのミリ秒数のほぼ 128 倍かかります。CUFFT を使用して、次のコードを実行すると、1 つの画像の 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.4msかかります。
複数の画像に対して同じコードを実行してみましたが、実行時間は基本的に画像数倍の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 の実行をオーバーラップさせるためにそれらを実行する必要がありますか?