在OpenMP中设计具有任务的算法
Designing an algorithm with tasks in openmp
i当前有一个代码,该代码确实可以在大型数据集上工作,并在末尾生成一个数组。然后,必须将数组添加到全局缓冲区中,并且所有这些都发生在循环中。例如
for(i=0;i<10000;i++)
{ <1. do some processing, generate a 1M-sized array>
<2. update this array into global buffer>
}
任务1发生在GPU上,我希望第二部分在CPU上类似地发生,即1线程控制任务1的GPU,所有其他线程在1个缓冲区准备处理时都会执行任务2。对于基本情况,我该如何使用一个缓冲区的副本(即在GPU侧,一个在CPU侧面进行GPU副本)?
您可以做的是拥有一组生产者 - 消费者,以便步骤1产生一个缓冲区,而步骤2在将结果纳入您的全局数组时会消耗该缓冲区。
类似(通常parallel
single
):
const int buffer_size = 100000;
type global[buffer_size];
type buffer[2][buffer_size];
for(int i=0;i<10000;i++)
{
type *buf[buffer_size] = buffer[i % 2];
#pragma omp task depend(out: [buffer_size]buf)
{
<1. write to buf>
}
#pragma omp task depend(in: [buffer_size]buf) depend(inout: [buffer_size]global)
{
<2. update global using buf>
}
}
这允许步骤2与步骤1重叠,其中一个迭代的"滞后"是迭代i = 1的步骤1,将同时运行到步骤2的迭代i = 0。您将需要每个重叠迭代的缓冲区,以便每个同时操作可以彼此独立进行。
现在,BUF的语义(in
/out
)很简单,因为它们是简单的Procuder-Consumbers关系。对于全局,您需要inout
,当您更新"就地的缓冲区:获取当前数组(in
)并为其分配新值(out
)。这意味着步骤2的所有任务将由于这种依赖性而被序列化,这意味着最多可以重叠的2个迭代(并且使用超过2个缓冲区都没有意义)。
这是当前OpenMP(4.5)任务的限制,尽管存在解决此问题的任务减少的建议。另一种方法是将Global声明为shared
,在这种情况下,您需要使用原子操作进行修改。
您可以使用target
子句在GPU上执行任务1。确保将来自卸载设备(即GPU)的数据复制到CPU。在步骤2的任务中,您可以使用平行于构造或任务的步骤2本身并行化步骤2本身。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 有没有任务栏API可以立即应用注册表更改
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- 具有加油站任务变化的DP算法
- 在OpenMP中设计具有任务的算法
- C++11通过两种算法中的一种来完成任务
- 在编程中,这两项任务中的任何一项都有算法方法吗
- 我如何使用z算法来完成这个任务