Jetson TK1 上的 FFT 速度较慢?

FFT is slower on Jetson TK1?

我已经编写了一个用于合成孔径雷达图像处理的 CUDA 程序。计算的重要部分涉及查找 FFT 和 iFFT,我为此使用了 cuFFT 库。我 运行 我的 CUDA 代码在 Jetson TK1 和一台装有 GT635M (Fermi) 的笔记本电脑上,我发现它在 Jetson 上慢了三倍。这是因为 FFT 在 Jetson 上花费了更多时间并且显示较低 GFLOPS/s。我编写的内核的 GFLOPS/s 性能在 Jetson 和 Fermi GT635M 中几乎相同。在 Jetson 上速度较慢的是 FFT。
我观察到的其他分析器参数是: 发出的控制流指令、纹理缓存 T运行sactions、本地内存存储吞吐量 (bytes/sec)、本地内存存储 T运行sactions Per Request 在 Jetson 上很高,而请求的全局负载吞吐量(bytes/sec) 和全局负载 T运行 动作在 Fermi GT635M 上很高。

杰森

GPU 时钟频率:852 Mhz

内存时钟速率:924 Mhz

费米GT635M

GPU 时钟频率:950 Mhz

内存时钟速率:900 Mhz

它们的时钟频率几乎相同。那么为什么 FFT 在 Jetson 上花费更多时间并且显示效果不佳 GFLOPS/s?

为了查看 FFT 的性能,我编写了一个简单的 CUDA 程序,它在大小为 2048 * 4912 的矩阵上执行一维 FFT。这里的数据是连续的,没有跨越。他们花费的时间和GFLOPS/s是:

杰森

3.251 GFLOPS/s 时长:1.393 秒

费米GT635M

47.1 GFLOPS/s 时长: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;
}

我的盲目猜测是,尽管 TK1 具有更现代的内核,但专供 635M 的 144 个内核使用的内存带宽明显高于 Tegra。

此外,CUDA 在 warp/thread/grid 大小上总是有点挑剔,因此 cufft 算法完全有可能针对 Fermi 的本地存储大小进行了优化,并且不能与 Keplers 一起使用.

这可能是因为您使用的是 LP(低功耗 CPU)。

检查 this document 以启用所有 4 个主要 ARM 内核(HP 集群)以利用 Hyper-Q。

我遇到了类似的问题。激活主 HP 集群后,我获得了良好的性能(从 3 GFLOPS (LP) 到 160 GFLOPS (HP))。