繁体   English   中英

CUDA:是否可以将一个内核视为“主”来执行 memory malloc,并运行其他“逻辑代码”?

[英]CUDA: Does it possible to treate one core as “master” to do memory malloc, and run other “logic code”?

我正在将 C++ 程序移植到 CUDA,计算都是关于矩阵/向量的。 第一个移植的 function 是矩阵的 FFT。 将矩阵的 FFT 移植到 CUDA 后,我发现:CPU 和 GPU 之间的数据转换器几乎一直占用。

// interface: do shift and inverse FFT on a matrix
extern "C" int cu_inv_fft_shift(std::complex<double>* ptrDest, int nRows, int nCols) {

    #ifdef ENABLE_DEBUG_TIME_MEASURE
    float ms1, ms2 = 0.f, ms3 = 0.f, ms4 = 0.f;
    cudaEvent_t startEvent, stopEvent;
    cudaEventCreate(&startEvent); cudaEventCreate(&stopEvent);
    #endif

    // step1: cpu -> gpu, and column-major -> row-major
    #ifdef ENABLE_DEBUG_TIME_MEASURE
    cudaEventRecord(startEvent, 0);
    #endif

    cufftDoubleComplex* ptr_data = matrix_to_cu_data(ptrDest, nRows, nCols);

    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(stopEvent, 0); 
    cudaEventSynchronize(startEvent);cudaEventSynchronize(stopEvent);
    cudaEventElapsedTime(&ms1, startEvent, stopEvent);
    #endif

    // step2: do shift on gpu buffer
    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(startEvent, 0);
    #endif

    ptr_data = fft_shift_cd(ptr_data, nRows, nCols);

    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(stopEvent, 0); 
    cudaEventSynchronize(startEvent);cudaEventSynchronize(stopEvent);
    cudaEventElapsedTime(&ms2, startEvent, stopEvent);
    #endif

    // step3: do FFT on gpu buffer
    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(startEvent, 0);
    #endif

    ptr_data = do_fft_cd(ptr_data, nRows, nCols, CUFFT_INVERSE);

    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(stopEvent, 0); 
    cudaEventSynchronize(startEvent);cudaEventSynchronize(stopEvent);
    cudaEventElapsedTime(&ms3, startEvent, stopEvent);
    #endif

    // step4: row-major -> column-major, and gpu -> cpu
    #ifdef ENABLE_DEBUG_TIME_MEASURE2
    cudaEventRecord(startEvent, 0);
    #endif

    ptr_data = cu_data_to_matrix_inv(ptrDest, nRows, nCols, ptr_data);

    #ifdef ENABLE_DEBUG_TIME_MEASURE
    cudaEventRecord(stopEvent, 0); 
    cudaEventSynchronize(startEvent);cudaEventSynchronize(stopEvent);
    cudaEventElapsedTime(&ms4, startEvent, stopEvent);
    #endif

    #ifdef ENABLE_DEBUG_TIME_MEASURE
    cudaEventDestroy(startEvent); cudaEventDestroy(stopEvent);
    //std::cout << __func__ << " called.."<< std::endl;
    printf("%s: %.4fms, %.4fms, %.4fms, %.4fms\n", __func__, ms1, ms2, ms3, ms4);
    #endif

    cudaFree(ptr_data);
    return 0;
}

矩阵为8192x8192时的实测结果:

cu_fwd_fft_shift: 4.2841ms, 0.7394ms, 0.0492ms, 4.2857ms

这意味着(已验证):

  • CPU->GPU:4.2ms。
  • 正向 FFT:0.7ms。
  • FFT偏移:0.05ms。
  • GPU->CPU:4.2ms。

The problem I encountered is that: in a CPU function, there are some "code snippet" (just like the FFT) could be ported to CUDA, but thre are some if/else code, and intermediate memory malloc between them.

我想减少数据传输 CPU<-->GPU。我的选择是将整个 CPU function 移植到 CUDA(GPU 端),但是有许多“逻辑代码”,例如 if/else,中间 memory Z2224EDA30DC1D36B2F08.30DC1D36B2F08

所以我的问题是:

  1. 是否可以将一个内核设置为主内核(就像 CPU 一样)来处理这些 malloc /“逻辑代码”并将子序列计算分配给所有其他内核?
  2. 我还可以学习其他 CUDA 项目吗? 或者
  3. 这个解决方案是不可能的吗?
  1. 是否可以将一个内核设置为主内核(就像 CPU 一样)来处理这些 malloc /“逻辑代码”并将子序列 [原文如此] 计算分配给所有其他内核?

CUDA 在其执行 model 中没有公开该级别的粒度,因此这是不可能的。 动态并行性,它可以允许一个 kernel 调度其他内核,并提供 CUDA 运行时 API 的最小子集。 您可能能够将该范例适应您的应用程序。

  1. 我还可以学习其他 CUDA 项目吗? 或者

如果您搜索并阅读 NVIDIA 提供的有关动态并行性的各种材料,您可能会发现一些可以学习的东西并评估这是否适用于您的用例。

  1. 这个解决方案是不可能的吗?

大概是。

通常,当您以“我正在将 C++ 程序移植到 CUDA”开始 GPU 编程问题或命题时,并且您的意思是最字面意义上的移植,您通常做错了什么。 传统代码库或串行算法可以盲目“移植”并且正确、快速或既正确又快速的情况极为罕见。 GPU 编程范式与传统的单线程和多线程 CPU 编码有很大不同,如果您尝试将其视为 CPU,您将失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM