【发布时间】:2016-04-14 18:59:45
【问题描述】:
我正在尝试并行化一段代码,我已经解决了并行调度映射中的插入并减少的问题。但是该程序给了我一个我认为与地图大小的条件检查有关的内存错误。存在概念错误还是可以同步该部分?
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});
}
}
【问题讨论】:
-
您是否尝试过禁用 OpenMP 或使用单线程的代码?
-
是的,它可以工作,问题是启用 openmp 会降低性能。我通过reduction解决了map中插入的并行调度问题,但是我不知道如何将条件部分并行化,避免使其变得关键并成为代码瓶颈。
-
如果不知道您到底想要实现什么,就很难说清楚。但是,
ranking_map上的操作是安全的,因为每个线程都使用一个私有副本。您是否相应地调整了NUM_RES等变量以使用多个线程执行?比如NUM_RES是如何初始化的? -
NUM_RES 是全局 int 变量,ranking_map 也是全局变量,必须在线程之间共享...我认为问题出在此处,因为对大小的检查是在全局地图上进行的多变的。我的目标是避免做这部分pragma critical。但不知道是否可行。
-
我想,你误解了
reduction的概念。循环分为多个部分,每个部分由单个线程处理。每个线程获得ranking_map的副本,并且可以独立地insert和erase元素。在循环结束时,所有副本合并在一起,形成全局ranking_map。
标签: c++ conditional openmp race-condition reduction