OpenMP Sections Construct 实现原理以及源码分析

前言

在本篇文章当中主要给大家介绍 OpenMP 当中主要给大家介绍 OpenMP 当中 sections construct 的实现原理以及他调用的动态库函数分析。如果已经了解过了前面的关于 for 的调度方式的分析,本篇文章就非常简单了。

编译器角度分析

在这一小节当中我们将从编译器角度去分析编译器会怎么处理 sections construct ,我们以下面的 sections construct 为例子,看看编译器是如何处理 sections construct 的。

#pragma omp sections
{
#pragma omp section
stmt1;
#pragma omp section
stmt2;
#pragma omp section
stmt3;
}

上面的代码会被编译器转换成下面的形式,其中 GOMP_sections_start 和 GOMP_sections_next 是并发安全的,他们都会返回一个数据表示第几个 omp section 代码块,其中 GOMP_sections_start 的参数是表示有几个 omp section 代码块,并且返回给线程一个整数表示线程需要执行第几个 section 代码块,这两个函数的意义不同的是在 GOMP_sections_start 当中会进行一些数据的初始化操作。当两个函数返回 0 的时候表示所有的 section 都被执行完了,从而退出 for 循环。

for (i = GOMP_sections_start (3); i != 0; i = GOMP_sections_next ())
switch (i)
{
case 1:
stmt1;
break;
case 2:
stmt2;
break;
case 3:
stmt3;
break;
}
GOMP_barrier ();

动态库函数分析

事实上在函数 GOMP_sections_start 和函数 GOMP_sections_next 当中调用的都是我们之前分析过的函数 gomp_iter_dynamic_next ,这个函数实际上就是让线程始终原子指令去竞争数据块(chunk),这个特点和 sections 需要完成的语意是相同的,只不过 sections 的块大小(chunk size)都是等于 1 的,因为一个线程一次只能够执行一个 section 代码块。

unsigned
GOMP_sections_start (unsigned count)
{
// 参数 count 的含义就是表示一共有多少个 section 代码块
// 得到当线程的相关数据
struct gomp_thread *thr = gomp_thread ();
long s, e, ret;
// 进行数据的初始化操作
// 将数据的 chunk size 设置等于 1
// 分割 chunk size 的起始位置设置成 1 因为根据上面的代码分析 0 表示退出循环 因此不能够使用 0 作为分割的起始位置
if (gomp_work_share_start (false))
{
// 这里传入 count 作为参数的原因是需要设置 chunk 分配的最终位置 具体的源代码在下方
gomp_sections_init (thr->ts.work_share, count);
gomp_work_share_init_done ();
}
// 如果获取到一个 section 的执行权 gomp_iter_dynamic_next 返回 true 否则返回 false
// s 和 e 分别表示 chunk 的起始位置和终止位置 但是在 sections 当中需要注意的是所有的 chunk size 都等于 1
// 这也很容易理解一次执行一个 section 代码块
if (gomp_iter_dynamic_next (&s, &e))
ret = s;
else
ret = 0;
return ret;
} // 下面是部分 gomp_sections_init 的代码
static inline void
gomp_sections_init (struct gomp_work_share *ws, unsigned count)
{
ws->sched = GFS_DYNAMIC;
ws->chunk_size = 1; // 设置 chunk size 等于 1
ws->end = count + 1L; // 因为一共有 count 个 section 块
ws->incr = 1; // 每次增长一个
ws->next = 1; // 从 1 开始进行 chunk size 的分配 因为 0 表示退出循环(编译器角度分析)
} unsigned
GOMP_sections_next (void)
{
// 这个函数就比较容易理解了 就是获取一个 chunk 拿到对应的 section 的执行权
long s, e, ret;
if (gomp_iter_dynamic_next (&s, &e))
ret = s;
else
ret = 0;
return ret;
} // 下面的函数在之前的很多文章当中都分析过了 这里不再进行分析
// 下面的函数的主要过程就是使用 CAS 指令不断的进行尝试,直到获取成功或者全部获取完成 没有 chunk 需要分配
bool
gomp_iter_dynamic_next (long *pstart, long *pend)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_work_share *ws = thr->ts.work_share;
long start, end, nend, chunk, incr; end = ws->end;
incr = ws->incr;
chunk = ws->chunk_size; if (__builtin_expect (ws->mode, 1))
{
long tmp = __sync_fetch_and_add (&ws->next, chunk);
if (incr > 0)
{
if (tmp >= end)
return false;
nend = tmp + chunk;
if (nend > end)
nend = end;
*pstart = tmp;
*pend = nend;
return true;
}
else
{
if (tmp <= end)
return false;
nend = tmp + chunk;
if (nend < end)
nend = end;
*pstart = tmp;
*pend = nend;
return true;
}
} start = ws->next;
while (1)
{
long left = end - start;
long tmp; if (start == end)
return false; if (incr < 0)
{
if (chunk < left)
chunk = left;
}
else
{
if (chunk > left)
chunk = left;
}
nend = start + chunk; tmp = __sync_val_compare_and_swap (&ws->next, start, nend);
if (__builtin_expect (tmp == start, 1))
break; start = tmp;
} *pstart = start;
*pend = nend;
return true;
}

总结

在本篇文章当中主要介绍了 OpenMP 当中 sections 的实现原理和相关的动态库函数分析,关于 sections 重点在编译器会如何对 sections 的编译指导语句进行处理的,动态库函数和 for 循环的动态调度方式是一样的,只不过 chunk size 设置成 1,分块的起始位置等于 1,分块的最终值是 section 代码块的个数,最终在动态调度的方式使用 CAS 不断获取 section 的执行权,指导所有的 section 被执行完成。


更多精彩内容合集可访问项目:https://github.com/Chang-LeHung/CSCore

关注公众号:一无是处的研究僧,了解更多计算机(Java、Python、计算机系统基础、算法与数据结构)知识。

OpenMP Sections Construct 实现原理以及源码分析的更多相关文章

  1. OpenMP Parallel Construct 实现原理与源码分析

    OpenMP Parallel Construct 实现原理与源码分析 前言 在本篇文章当中我们将主要分析 OpenMP 当中的 parallel construct 具体时如何实现的,以及这个 co ...

  2. OpenMP 线程同步 Construct 实现原理以及源码分析(上)

    OpenMP 线程同步 Construct 实现原理以及源码分析(上) 前言 在本篇文章当中主要给大家介绍在 OpenMP 当中使用的一些同步的 construct 的实现原理,如 master, s ...

  3. OpenMP 线程同步 Construct 实现原理以及源码分析(下)

    OpenMP 线程同步 Construct 实现原理以及源码分析(下) 前言 在上面文章当中我们主要分析了 flush, critical, master 这三个 construct 的实现原理.在本 ...

  4. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  5. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  6. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  7. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  8. 【转】HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  9. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  10. 《深入探索Netty原理及源码分析》文集小结

    <深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de

随机推荐

  1. 视觉享受,兼顾人文观感和几何特征的字体「GitHub 热点速览 v.22.46」

    GitHub 上开源的字体不在少数,但是支持汉字以及其他非英文语言的字体少之又少,记得上一个字体还是 霞鹜文楷,本周 B 站知名设计 UP 主开源了的得意黑体在人文观感和几何特征之间找到了美的平衡. ...

  2. 第2-4-1章 规则引擎Drools介绍-业务规则管理系统-组件化-中台

    目录 规则引擎 Drools 1. 问题引出 2. 规则引擎概述 2.1 什么是规则引擎 2.2 使用规则引擎的优势 2.3 规则引擎应用场景 2.4 Drools介绍 规则引擎 Drools 全套代 ...

  3. 解决sox报错sox FAIL formats: no handler for given file type `mp3

    sudo apt-get install libsox-fmt-mp3

  4. 4.6:HBase操作实验

    〇.概述 1.拓扑结构 2.目标 进行Hbase实验来熟悉Hbase的基本操作. 一.基本操作 1.启动进程 16610 2.连接集群 3.常见操作

  5. Vuex极速入门

    01.什么是Vuex? 1.1.为什么需要状态管理? 在复杂的系统中,我们会把系统按照业务逻辑拆分为多个层次.多个模块,采用组件式的开发方式.而此时不同模块.父子模块之间的通信就成了一个问题. 为了解 ...

  6. Proxyless Mesh 在 Dubbo 中的实践

    背景 随着 Dubbo 3.1 的 release,Dubbo 在云原生的路上又迈出了重要的一步.在这个版本中添加了 Proxyless Mesh 的新特性,Dubbo Proxyless Mesh ...

  7. 《STL源码剖析》STL迭代器分类

    input迭代器:只能向前移动,一次一步,用户只能读取,不能修改它们所指向的东西,而且只能读取一次. output迭代器情况类似,但一切只为输出:它们只能向前移动,一次一步,用户只可以修改它们所指向的 ...

  8. 今日实际操作----Dart Mac开发与运行环境配置 配置.bash_profile

    Mac 打开.编辑 .bash_profile 文件 一般在Mac上配置环境变量时经常要创建.编辑 .bash_profile文件.创建该文件时一般都会选择在当前用户目录下,即Mac下的.bash_p ...

  9. ChatGPT开发实战

    1.概述 前段时间使用体验了ChatGPT的用法,感受到ChatGPT的强大,通过搜索关键字或者输入自己的意图,能够快速得到自己想要的信息和结果.今天笔者将深挖一下ChatGPT,给大家介绍如何使用C ...

  10. Python语法与基本数据类型

    Python语法与基本数据类型 一.Python语法之注释 1.注释 注释就是对一段代码的解释说明 2.注释的写法 1.单行注释:解释说明的文字前面加#号, pycharm中有快捷键 ctrl+? 2 ...