[英]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.