2016-04-14 592 views
0

我想并行化一段代码,我已经解决了并行调度地图中的插入与减少的问题。但是这个程序给我一个内存错误,我认为它与地图大小的条件检查有关。有一个概念错误,或者是否有可能同步该部分?OpenMP与条件语句竞争条件

if (PERF_ROWS == MAX_ROWS) 
{ 
    int array_dist[PERF_ROWS]; 

    #pragma omp declare reduction (merge : std::multimap<float, int> : omp_out.insert(omp_in.begin(),omp_in.end())) 

    #pragma omp parallel for schedule(dynamic) reduction(merge: ranking_map) private(array_dist) 
    for (int i = 0; i < MAX_COLUMNS; i++) 
    { 
     if (i % PERF_CLMN == 1) continue; 

     for (int j = 0; j < PERF_ROWS; j++) 
     { 
      array_dist[j] = abs(input[j] - input_matrix[j][i]); 
     } 

     float av = mean(PERF_ROWS, array_dist); 

     float score = score_func(av); 

     //cout<<score<<" "<<av<<endl; 

     //#pragma omp critical(rank_func) 
     //rank_function(score, i); 

     multimap<float,int>::iterator it = ranking_map.begin(); 

     if (ranking_map.size() < NUM_RES) 
     { 
      ranking_map.insert({score, i}); 
     } 

     else if (score > it -> first) 
     { 
      ranking_map.erase(it); 
      ranking_map.insert({score, i}); 
     } 
    } 
+0

您是否尝试过禁用OpenMP或使用单个线程的代码? – user0815

+0

是的,它的工作原理是,启用openmp性能降级。我解决了在映射中并行调度插入的问题,但我不知道如何并行化条件部分,避免使其变得严重并且瓶颈代码。 – CIVI89

+0

不知道你真正想要达到的目标很难说清楚。但是,'ranking_map'上的操作是安全的,因为每个线程都使用私人副本。你是否适应像'NUM_RES'等变量来执行多个线程?例如,如何初始化'NUM_RES'? – user0815

回答

0

那么,定义你自己的组合器。 做一个insertwhatever调用的函数,写这样的事情:

void insertwhatever(std::multimap<float, int>& a, std::multimap<float, int>&b) 
    { 
    for(auto iterb : b) 
    { 
     if(a.size() < NUM_RES) 
     { 
     a.insert(iterb); 
     } 
     else if(....) 
     { 
     (dont know what you want to do here) 
     } 
    } 
    } 

然后改变减少

#pragma omp declare reduction (merge : std::multimap<float, int> : insertwhatever(omp_out,omp_in)) 

我不能完全肯定,但我认为这应该工作。尽管如此,我还是不太明白你想要做什么。

+0

好的我想完全这样做,以便使这件作品平行。我不想仅在地图中插入值,而是希望保持地图的固定大小,以避免维护有序的大量值。这就是为什么其他如果... – CIVI89

+0

但我想只插入两个值,分数和我,地图是全球性的 – CIVI89