【问题标题】:OpenMP custom schedulingOpenMP 自定义调度
【发布时间】:2018-04-08 22:02:08
【问题描述】:

我有一个可以轻松并行化的并行循环。我需要为循环实现自定义调度选项。为此,我将明确地将迭代分配给线程,而不是使用标准的并行区域,如下所示:

#pragma omp parallel for

我只是使用:

#pragama omp parallel [declarations]

到目前为止我的代码如下:

#define N 500
#pragma omp parallel 
{
int num_threads = omp_get_num_threads();
int thread = omp_get_thread_num();
int start = N*thread/num_threads;
int end = N*(thread+1)/num_threads;
   for (i=start; i<end; i++){
   /* LOOP */
   }
}

我需要应用一种调度算法,以便为每个线程分配一组本地迭代,我相信我已经完成了。每个本地集被分成每个线程执行的块。当线程完成它的块时,它会找到具有最多剩余块的线程并开始执行这些块。重复此过程,直到没有块剩余。 我正在努力弄清楚如何开始这个,因为我不完全确定如何找出负载最多的线程是什么,以及如何将本地迭代集拆分成块,同时仍然保留在平行区域。

【问题讨论】:

  • 我不完全确定我得到了这个问题,您必须自己实现负载平衡调度,还是必须使用 OpenMP 来实现?
  • 使用工作项(块)队列和一些(可能是可变的)工作线程数可能会更容易和更有效。如果i 是数组的索引,那么您的队列必须有startIdxcount
  • 我必须使用 OpenMP 来实现亲和性调度选项。 @jwdonahue i 是正确数组的索引。我想这种方法会很好用。我现在有一组起始索引。但我坚持如果完成,如何允许线程跳转到其他起点。或者如何监控进度。
  • 我详细介绍了手动实现 OpenMP 调度程序 here。您可能可以使用它来定义 OpenMP 未实现的自定义调度程序。
  • 你想要的是schedule(dynamic,chunk)吗?

标签: c multithreading parallel-processing openmp schedule


【解决方案1】:

您需要实现的是work stealing 算法。听起来您想要为每个线程分配一个双端队列(有时称为出队)。如果您允许任何线程从任何其他线程窃取工作,您将需要与每个队列关联的锁,以防止两个线程尝试窃取同一工作。

您还需要将这些队列中的每一个放入优先级队列中,使用它们的大小作为键,以允许已完成的线程获取剩余工作最多的线程可以窃取。您还需要锁定该全局优先级队列,以便在执行更新时保持其完整性。

话虽如此,当可用时,#pragma omp fordynamic 计划或生成tasks(通过#pragma omp task)可能更可取。 如果您确实实现了自己的工作窃取算法,请记住根据对于所有线程都相同的度量来选择从哪个线程窃取通常会导致冲突(即,所有空闲线程将尝试从同一个线程窃取)队列)。考虑改为根据地点选择在哪里窃取工作。

【讨论】:

  • 另外,您可以使用任务循环或调度(非单调:动态),在这种情况下,OpenMP 运行时可以进行迭代窃取...
  • 我相信我需要实现一个工作窃取算法。我已经制作了两个数组,它们将每个线程的数据拆分并存储起点和终点。但是,我现在对如何进一步拆分感到困惑。我正在考虑实现它的方式是将数组拆分为更多块。然后让线程执行它的块然后找到剩余的块。虽然我不确定如何监控进度以便线程知道剩余的线程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 2017-04-09
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
相关资源
最近更新 更多