OpenMP task 原理与实例

2023-11-08

个人理解

Openmp自从3.0以后全面走向任务驱动。task机制非常重要,可以显式定义任务,而其余parallel代码块中不用task定义的实际上是隐式任务。
抽象来说就是有两个池子:线程池与任务池。闲置的线程会在线程池等待任务。显式任务与隐式任务会放在任务池中等待线程取走。

task子句相当于显式定义一个任务。常用在不规则循环(不适用parallel for的循环)与递归函数中。默认任务只能由一个线程执行。当线程遇到task子句时,既可能自己立即执行,也可能将其放入任务池等待别的线程取走。
taskwait显式等待之前定义的任务执行结束。用于同步。
final:当final条件为真时,该任务与子任务不再作为任务,与if本质应该是一致的。
if:当if条件为假时,该任务将不再放入任务池中,而是由碰到它的线程立即执行。

final与if子句用来防止过于细粒度的任务放在任务池中,造成资源浪费。因为我们更希望粗粒度的任务,从而分摊线程创建,启动,同步等带来的开销。

官方示例



#include <stdio.h>
#include <omp.h>
int fib(int n)
{
  int i, j;
  if (n<2)
    return n;
  else
    {
       #pragma omp task shared(i) firstprivate(n)
       i=fib(n-1);

       #pragma omp task shared(j) firstprivate(n)
       j=fib(n-2);

       #pragma omp taskwait
       return i+j;
    }
}

int main()
{
  int n = 10;

  omp_set_dynamic(0);
  omp_set_num_threads(4);

  #pragma omp parallel shared(n)
  {
    #pragma omp single
    printf ("fib(%d) = %d\n", n, fib(n));
  }
}

用于双调归并排序

双调归并排序本质其实不难,但理解还是有一定难度,有两部分递归。
第一步将一个序列,分成两部分,第一部分是升序的,第二部分是降序的。第二部分是利用双调队列的性质,将其变为有序,CSDN与知乎均有介绍。

#include <stdio.h>
#include <algorithm>
#include <omp.h>
#include <functional>
#include <math.h>

typedef std::function<bool(int, int)> Func;
Func op[2];
void to_one_sequence(int* a, int n, int selector);

void bitonicSort(int* a, int n, int selector)
{
    if (n <= 1)
        return;
    else
    {
        #pragma omp task if(n > 1024)
        bitonicSort(a, n / 2, selector);
        #pragma omp task if(n > 1024)
        bitonicSort(a + n / 2, n / 2, selector ^ 1);
        #pragma omp taskwait

        to_one_sequence(a, n, selector);
    }
    
}

void to_one_sequence(int* a, int n, int selector)
{
    if (n <= 1)
        return;
    else
    {
        //#pragma omp task if(n > 1024)
        {
            auto judge = op[selector];
            for (int i = 0; i < n / 2; i++) {
                if (judge(a[i], a[i + n / 2]))
                    std::swap(a[i], a[i + n / 2]);
            }
        }
        //#pragma omp taskwait
        #pragma omp task if(n > 1024)
        to_one_sequence(a, n / 2, selector);
        #pragma omp task if(n > 1024)
        to_one_sequence(a + n / 2, n / 2, selector);
        #pragma omp taskwait
    }
    
}

int main()
{
    Func big   = [](int a, int b)->bool {return a <= b;};
    Func small = [](int a, int b)->bool {return a >= b;};
    op[0] = small;
    op[1] = big;

    const int maxn = pow(2, 22);
    int* a = new int[maxn];
    
    #pragma omp parallel for
        for (int i = 0; i < maxn; i++)
            a[i] = rand() % 10000;

    double begin = omp_get_wtime();

    omp_set_dynamic(1);
    //omp_set_num_threads(4);
    #pragma omp parallel
    {
        
        #pragma omp single
        {
            printf("%d\n", omp_get_num_threads());
            bitonicSort(a, maxn, 0);
        }
        
    }
    
    printf("%lf\n", omp_get_wtime() - begin);

    bool ok = 1;
    for (int i = 0; i < maxn; i++)
    {
        if (i != 0)
        {
            if (a[i] < a[i - 1])
            {
                ok = 0;
                break;
            }
        }
    }
    printf("%d\n", ok);
    

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenMP task 原理与实例 的相关文章

随机推荐

  • 【VMware/Linux】虚拟机根目录扩容

    大家好 我是好学的小师弟 最近IT给配的虚拟机 目录容量太小了 不符合环境部署条件 所以想让IT扩下容 IT给我加了一块磁盘 然后让我自己lvm扩容去 这里记录下扩容方法 1 先添加一块磁盘 这里添加了一块磁盘sdr fdisk l 查看新
  • 数据结构与算法分析--Java语言描述(第二章(2))

    习题2 23 不用递归 写出快速求幂的程序 递归方法 param x param n return public long pow long x int n if n 0 return 1 if isEven n return pow x
  • VSCODE-版本控制工具SVN

    1 在SVN中安装插件 SVN svn简介 安装完成后 重新启动SVN或者点击SVN 重新加载 本人SVN不是默认安装位置 但是无需修改vscode 用户设置 中的任何选项 2 引入项目 直接打开通过SVN下载的项目的文件夹 3 查看SVN
  • eclipse指定jdk版本启动,解决Version XXXX of the JVM is not suitable

    可以解决Version XXXX of the JVM is not suitable for this product Version XXXXXX or greater is required 例如 Verson1 7 0 79 of
  • 【Vue】同一模板 多个样式 统一实现

    文章目录 一 背景 二 具体代码 一 背景 项目中多个页面的页脚都包含版权信息 并且各自有一个 Copyright vue 的组件 经过对比 template 的内容一模一样 只是样式有些不同 这里准备抽取出来 用一个公共组件 CopyRi
  • 你的电脑上的应用需要使用以下window功能.NET Framework3.5(包括.NET2.0和3.0)

    我自己下载了 net 3 5来安装他也提示这玩意 然后点自动安装后又错误码0x800f081f 奶奶滴 于是去百度 解决流程 1 首先 按Windows R调出 运行 对话框 2 接下来 键入gpedit msc并按Enter 3 该命令将
  • pytorch将Tensor转为list

    import torch value torch Tensor 1 2 3 print list value tolist 得到 list 1 0 2 0 3 0
  • promise与async和await的使用

    基础回顾 阻塞代码实例 首先 我们新建一个 test txt 文件 内容如下 111 然后 我们来编写一个 main js 文件 代码如下 var fs require fs var str fs readFileSync test txt
  • css button自动调整位置_(Vue动效)1.Vue的CSS过渡动效

    关键词
  • JAVA个推----将信息推送至手机端

    个推功能简介 将信息推送至手机端 手机端人员可以看到收到的信息 个推功能需要借助第三方平台的接口 需要申请账号 单独开发很难完成 这里就是用到了第三方接口 完成个推需要完成三步 获取token 调用个推接口需要获取用于验证的token 获取
  • 前端歌谣的刷题之路-第二十二题-基本数据类型检测

    前言 我是歌谣 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷 本题目源自于牛客网 微信公众号前端小歌谣 题目 请补全JavaScript函数 要求以字符串的形式返回参数的类型 注意 只需检测基本数据类型 编辑 核心代码
  • 自动驾驶制图中的深度学习

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 深度学习在整个自动驾驶技术的各个部分中进行了应用 例如在感知 预测和计划中都有应用 同时 深度学习也可以用于制图 这是高级自动驾驶的关键组成部分 拥有准确的地图对于自动驾
  • Siebel学习笔记

    Siebel escript 的学习 1 Siebel的数据类型 Primitive 原始的 Number Integer Hexadecimal 十六进制 Octal 八进制 Floating Point 浮点 Decimal 十进制 S
  • 面试总结(1)---7.28

    Ajax关于readyState 状态值 和status 状态码 的研究 var getXmlHttpRequest function try 主流浏览器提供了XMLHttpRequest对象 return new XMLHttpReque
  • 解决wiringPi库与64位树莓派之间不兼容的问题

    目录 一 问题现象 二 解决方案 网站 可以直接点这下载 一 问题现象 今天在练习wiringPi库的使用时候 在最后编译的时候出现了这个问题 主要问题是这个skipping incompatible skipping incompatib
  • Android上OpenCV物体检测,Opencv图像识别Android实战(识别纸牌4.图像识别素养)

    我认为大多数阅读本文的人都对机器学习有所了解 我认为没有必要在学术上解释这种含义 人类学习的目的不是识别更多的东西 机器学习也是如此 也就是说 让计算机通过学习类比来学习更多的东西 在这里 我们让计算机知道图像 要让计算机知道事情 我们必须
  • 集成学习笔记

    集成学习通过结合规则 使用一系列弱学习器来组成一个强学习器 集成学习通常有两个步骤 ensemble generation 和 ensemble integration 通常在两个步骤之间会有一个 pruning process 剪枝过程
  • LeetCode--初级算法--环形链表

    题目 给定一个链表 判断链表中是否有环 为了表示给定链表中的环 我们使用整数 pos 来表示链表尾连接到链表中的位置 索引从 0 开始 如果 pos 是 1 则在该链表中没有环 示例 1 输入 head 3 2 0 4 pos 1 输出 t
  • Excel条件格式化(conditional formatting)应用

    简介 条件格式化顾名思义就是根据条件对单元格进行格式化 填充 字体等 比如我们有一个学生成绩表 根据需要我们要把成绩按 不及格 lt 60 良好 gt 60且 lt 90 优秀 gt 90 进行颜色标注 第一步 如图 第二步 如图 点击 确
  • OpenMP task 原理与实例

    个人理解 Openmp自从3 0以后全面走向任务驱动 task机制非常重要 可以显式定义任务 而其余parallel代码块中不用task定义的实际上是隐式任务 抽象来说就是有两个池子 线程池与任务池 闲置的线程会在线程池等待任务 显式任务与