【问题标题】:OpenMP race conditions with conditional statement带有条件语句的 OpenMP 竞争条件
【发布时间】: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 的副本,并且可以独立地inserterase 元素。在循环结束时,所有副本合并在一起,形成全局 ranking_map

标签: c++ conditional openmp race-condition reduction


【解决方案1】:

好吧,定义你自己的组合器。 创建一个名为 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))

我不太确定,但我认为这应该可行。我还是不太明白你到底想做什么。

【讨论】:

  • 好的,我就是想这样做,使这件作品平行。而不是只在地图中插入值,我想保持地图的固定大小,避免保持大量有序的值。这就是为什么 else if...
  • 但是我只想插入两个值,score和I,地图是全局的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多