2017-07-21 111 views
1

我創建了一個程序,需要用不同的輸入參數多次調用一個函數(lot !!)。 爲了加快速度,我多線程這是這樣的:從多線程CPU程序移到C++中的GPU

std::vector< MTDPDS* > mtdpds_list; 
boost::thread_group thread_gp; 
for (size_t feat_index = 0; feat_index < feat_parser.getNumberOfFeat(); ++feat_index) 
{ 
    Feat* feat = feat_parser.getFeat(static_cast<unsigned int>(feat_index)); 

    // != 0 has been added to avoid a warning message during compilation 
    bool rotatedFeat = (feat->flag & 0x00000020) != 0; 
    if (!rotatedFeat) 
    { 
     Desc* desc = new Desc(total_sb, ob.size()); 

     MTDPDS* processing_data = new MTDPDS(); 
     processing_data->feat = feat; 
     processing_data->desc = desc; 
     processing_data->img_info = image_info; 
     processing_data->data_op = &data_operations; 
     processing_data->vecs_bb = vecs_bb; 

     mtdpds_list.push_back(processing_data); 

     thread_gp.add_thread(new boost::thread(compute_desc, processing_data)); 
    } 
} 

// Wait for all threads to complete 
thread_gp.join_all(); 

此代碼是一塊更大的代碼,所以不用太擔心變量名,等等 重要的是我爲每個包含輸入和輸出參數的線程創建一個對象(MTDPDS),然後生成調用我的處理函數compute_desc的線程,並等待所有線程完成,然後繼續。

但是,我的for循環有大約2000多次迭代,這意味着我開始大約2000多個線程。我在集羣上運行我的代碼,所以它非常快,但它仍然需要太長的IMO。

我想將這部分移到GPU(因爲它有更多的內核),儘管我是GPU編程的新手。

  1. 有沒有一種方法(因爲我已經有一個分離的計算功能)移動這個很容易,而無需改變整個代碼?就像一個函數,可以啓動類似於提升的方式在GPU上啓動線程(如用GPU線程替換提升線程)?我的計算功能是訪問一些加載到內存中的數據(這裏是RAM),GPU需要將這些數據加載到GPU內存中,還是可以訪問內存(然後在這種情況下,哪一個更快) ?
  2. 最後一個問題(雖然我很確定我知道答案),是否有可能使它與硬件無關(所以我的代碼可以在Nvidia,ATI等上運行)?

謝謝。

+0

如果您需要支持多線程的交叉硬件支持,您最好的選擇可能是學習Vulkan。它比openGL更有效率,並且允許nVidia和AMD硬件,而不是CUDA –

+0

從我所看到的,Vulkan更加面向圖形而不是計算目的,不是嗎? – whiteShadow

+0

是的,你是正確的,也許試試看OpenCL? –

回答

3
  • 1)最簡單的解決方案是使用#pragma指令(OpenACC),它應該已經存在於GCC7中。

  • 2)您的數據應該是GPU友好,理解陣列

  • 3)你的compute_desc「核心」的結構應該是GPU兼容的,如果你不知道讓說,它應該由編譯器向量化。

我希望這將有助於一點,我認爲OpenACC的tuto一個小教程應該爲你的最佳解決方案,CUDA/OpenCL的要晚一點。我的2美分

+0

謝謝你的教程。雖然我將不得不在文檔中挖掘,因爲在我的情況下,我的循環調用了我的處理函數,它本身具有循環調用函數。我認爲OpenACC 2.0有一些我可以使用的「常規」的東西,但我仍然沒有想到如何使用它。 – whiteShadow