【问题标题】:CUDA Device To Device transfer expensiveCUDA 设备到设备传输昂贵
【发布时间】:2011-05-19 19:02:18
【问题描述】:

我编写了一些代码来尝试交换二维矩阵的象限以用于 FFT,该矩阵存储在平面数组中。

    int leftover = W-dcW;

    T *temp;
    T *topHalf;
cudaMalloc((void **)&temp, dcW * sizeof(T));

    //swap every row, left and right
    for(int i = 0; i < H; i++)
    {
        cudaMemcpy(temp, &data[i*W], dcW*sizeof(T),cudaMemcpyDeviceToDevice);
        cudaMemcpy(&data[i*W],&data[i*W+dcW], leftover*sizeof(T), cudaMemcpyDeviceToDevice);
        cudaMemcpy(&data[i*W+leftover], temp, dcW*sizeof(T), cudaMemcpyDeviceToDevice); 
    }

cudaMalloc((void **)&topHalf, dcH*W* sizeof(T));
    leftover = H-dcH;
    cudaMemcpy(topHalf, data, dcH*W*sizeof(T), cudaMemcpyDeviceToDevice);
    cudaMemcpy(data, &data[dcH*W], leftover*W*sizeof(T), cudaMemcpyDeviceToDevice);
    cudaMemcpy(&data[leftover*W], topHalf, dcH*W*sizeof(T), cudaMemcpyDeviceToDevice);

请注意,此代码采用设备指针,并执行 DeviceToDevice 传输。

为什么这似乎运行得这么慢?这可以以某种方式优化吗?与在主机上使用常规 memcpy 进行相同操作相比,我对此进行了计时,它的速度大约慢了 2 倍。

有什么想法吗?

【问题讨论】:

  • 启动 cudaMemcpy 的成本很高。最好编写一个从输入读取、交换并写入适当位置的内核,而不是将 cudaMemcpy 放在 for 循环中。
  • hrmmm..bummer。做一个主机memcpy,和传输到设备的比较呢?

标签: c++ cuda fft


【解决方案1】:

我最终编写了一个内核来进行交换。这确实比 Device to Device memcpy 操作快

【讨论】:

    【解决方案2】:

    也许以下在 CUDA 中执行 2d fftshift 的解决方案会很有趣:

    #define IDX2R(i,j,N) (((i)*(N))+(j))
    
    __global__ void fftshift_2D(double2 *data, int N1, int N2)
    {
        int i = threadIdx.y + blockDim.y * blockIdx.y;
        int j = threadIdx.x + blockDim.x * blockIdx.x;
    
        if (i < N1 && j < N2) {
            double a = pow(-1.0, (i+j)&1);
    
            data[IDX2R(i,j,N2)].x *= a;
            data[IDX2R(i,j,N2)].y *= a;
        }
    }
    

    它包括将要转换的矩阵乘以1s 和-1s 的棋盘,这相当于乘以exp(-j*(n+m)*pi),从而在共轭域中双向移动。

    你必须在应用 CUFFT 之前和之后调用这个内核。

    一个优点是避免了内存移动/交换。

    提高速度

    根据NVIDIA Forum收到的建议,可以通过更改指令来提高速度

    double a = pow(-1.0,(i+j)&1);
    

    double a = 1-2*((i+j)&1);
    

    避免使用缓慢的例程 pow。

    【讨论】:

    • 实际上在几乎所有过滤应用程序中,都可以通过将所有过滤器保留在包裹的 fft 空间中来删除此步骤。
    猜你喜欢
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 2013-12-05
    • 2014-01-21
    相关资源
    最近更新 更多