簡體   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