2013-04-04 39 views
1

我想通過在GPU的線程上實現for循環來優化我的代碼。我正試圖消除使用thrust :: transform的兩個for循環。在C++中的代碼如下所示:使用推力替換for-loops :: transform

ka_index = 0; 
    for (int i = 0; i < N_gene; i++) 
    { 
     for (int j = 0; j < n_ka_d[i]; j++) 
     { 
      co0 = get_coeff0(ka_vec_d[ka_index]); 
      act[i] += (co0*ka_val_d[ka_index]); 
      ka_index++; 
     } 
     act[i] = pow(act[i],n); 
    } 

我估計共efficients用於上述循環 常微分方程(ODE),並傳送所有的數據到使用推力裝置。考慮基因數由N_gene表示的情況。循環拳必須運行N_gene次。第二個循環受到每個基因的激活子(基因庫中其他友好基因)數量的限制。每個基因都有許多由n_ka載體的元素表示的激活子(存在增加基因i濃度的友好基因)。 n_ka [i]的值可以從0變化到N_gene_1。ka_val代表每個激活劑ka的激活的量度。 ka_vec_d具有激活基因i的基因索引。

我想用迭代器來表示這些循環,但無法這樣做。我熟悉使用thrust :: for_each(thrust :: make_zip_iterator(thrust :: make_tuple))作爲單個for循環,但是有一段艱難的時間,用一個方法來實現兩個使用counting_iterator或transform迭代器的for循環。任何指針或幫助轉換這兩個for循環將不勝感激。謝謝你的時間!

回答

1

這看起來像是一個減少的問題。我認爲你可以使用thrust::transform與zip迭代器和thrust::reduce_by_key。這種解決方案的草圖是:

// generate indices 
std::vector<int> hindices; 
for(size_t i=0 ; i<N_gene ; ++i) 
    for(size_t j=0 ; j<n_ka_d[i] ; ++j) 
    hindices.push_back(i); 
thrust::device_vector<int> indices = hindices; 

// generate tmp 
// trafo1 implements get_coeff0(get<0>(t)) * get<1>(t); 
thrust::device_vector<double> tmp(N); 
thrust::transform(
    thrust::make_zip_iterator(
     thrust::make_tuple(ka_vec_d.begin() , ka_val_d.begin())) , 
    thrust::make_zip_iterator(
     thrust::make_tuple(ka_vec_d.end() , ka_val_d.end())) , 
    tmp.begin() , trafo1); 

// do the reduction for each ac[i] 
thrust::device_vector<int> indices_out(N); 
thrust::reduce_by_key(indices.begin() , indices.end() , tmp.begin() , 
    ac.begin() , indices_out.begin()); 

// do the pow transformation 
thrust::transform(ac.begin() , ac.end() , ac.begin() , pow_trafo); 

我此這也可以通過transform_iterators優化,以減少的thrust::transformthrust::recuce_by_key呼叫數。

+0

感謝headmyshouder,這肯定有幫助,我已經實施它使用reduce_by_key和我的應用程序運行良好。我使用thrust :: for_each代替了thrust :: transform並將tmp集成到用於生成tmp的元組中,從而在某種意義上做了一些小改動。使用推力::變換推力:: for_each是否有優勢?再次感謝您的回答! – rtmi 2013-04-08 17:12:41

+0

我認爲沒有真正的區別。因爲它能告訴你發生了什麼,所以thrust :: transform有點更具表現力。您也可以嘗試衡量兩種方式的表現是否相等。 – headmyshoulder 2013-04-08 17:47:27