合成開口レーダー画像処理用の CUDA プログラムを作成しました。計算の大部分は FFT と iFFT を見つけることであり、私はそのために cuFFT ライブラリを使用しました。Jetson TK1 と GT635M (Fermi) を搭載したラップトップで CUDA コードを実行しましたが、Jetson では 3 倍遅いことがわかりました。これは、FFT に時間がかかり、Jetson の GFLOPS/s が低いためです。私が書いたカーネルの GFLOPS/s のパフォーマンスは、Jetson と Fermi GT635M の両方でほぼ同じです。Jetson で遅いのは FFT です。
私が観察したその他のプロファイラー パラメーターは次のとおりです。発行された制御フロー命令、テクスチャ キャッシュ トランザクション、ローカル メモリ ストア スループット (バイト/秒)、要求ごとのローカル メモリ ストア トランザクションは Jetson で高く、要求されたグローバル ロード スループット (バイト/秒) とグローバル ロード トランザクションは Fermi GT635M で高くなっています。
ジェットソン
GPU クロック レート: 852 Mhz
メモリ クロック レート: 924 Mhz
フェルミ GT635M
GPU クロック レート: 950 Mhz
メモリ クロック レート: 900 Mhz
どちらもほぼ同じクロック周波数を持っています。それでは、Jetson で FFT に時間がかかり、GFLOPS/s が低いのはなぜですか?
FFT のパフォーマンスを確認するために、サイズ 2048 * 4912 の行列で 1D FFT を実行する単純な CUDA プログラムを作成しました。ここのデータは連続しており、ストライドされていません。それらの所要時間と GFLOPS/秒は次のとおりです。
ジェットソン
3.251 GFLOPS/秒 持続時間: 1.393 秒
フェルミ GT635M
47.1 GFLOPS/秒 持続時間: 0.211 秒
#include <stdio.h>
#include <cstdlib>
#include <cufft.h>
#include <stdlib.h>
#include <math.h>
#include "cuda_runtime_api.h"
#include "device_launch_parameters.h"
#include "cuda_profiler_api.h"
int main()
{
int numLines = 2048, nValid = 4912;
int iter1, iter2, index=0;
cufftComplex *devData, *hostData;
hostData = (cufftComplex*)malloc(sizeof(cufftComplex) * numLines * nValid);
for(iter1=0; iter1<2048; iter1++)
{
for(iter2=0; iter2<4912; iter2++)
{
index = iter1*4912 + iter2;
hostData[index].x = iter1+1;
hostData[index].y = iter2+1;
}
}
cudaMalloc((void**)&devData, sizeof(cufftComplex) * numLines * nValid);
cudaMemcpy(devData, hostData, sizeof(cufftComplex) * numLines * nValid, cudaMemcpyHostToDevice);
// ----------------------------
cufftHandle plan;
cufftPlan1d(&plan, 4912, CUFFT_C2C, 2048);
cufftExecC2C(plan, (cufftComplex *)devData, (cufftComplex *)devData, CUFFT_FORWARD);
cufftDestroy(plan);
// ----------------------------
cudaMemcpy(hostData, devData, sizeof(cufftComplex) * numLines * nValid, cudaMemcpyDeviceToHost);
for(iter1=0; iter1<5; iter1++)
{
for(iter2=0; iter2<5; iter2++)
{
index = iter1*4912 + iter2;
printf("%lf+i%lf \n",hostData[index].x, hostData[index].y);
}
printf("\n");
}
cudaDeviceReset();
return 0;
}