[英]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
这意味着(已验证):
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
所以我的问题是:
- 是否可以将一个内核设置为主内核(就像 CPU 一样)来处理这些 malloc /“逻辑代码”并将子序列 [原文如此] 计算分配给所有其他内核?
CUDA 在其执行 model 中没有公开该级别的粒度,因此这是不可能的。 有动态并行性,它可以允许一个 kernel 调度其他内核,并提供 CUDA 运行时 API 的最小子集。 您可能能够将该范例适应您的应用程序。
- 我还可以学习其他 CUDA 项目吗? 或者
如果您搜索并阅读 NVIDIA 提供的有关动态并行性的各种材料,您可能会发现一些可以学习的东西并评估这是否适用于您的用例。
- 这个解决方案是不可能的吗?
大概是。
通常,当您以“我正在将 C++ 程序移植到 CUDA”开始 GPU 编程问题或命题时,并且您的意思是最字面意义上的移植,您通常做错了什么。 传统代码库或串行算法可以盲目“移植”并且正确、快速或既正确又快速的情况极为罕见。 GPU 编程范式与传统的单线程和多线程 CPU 编码有很大不同,如果您尝试将其视为 CPU,您将失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.