OpenMP Sections Construct 实现原理以及源码分析
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 实现原理以及源码分析的更多相关文章
- OpenMP Parallel Construct 实现原理与源码分析
OpenMP Parallel Construct 实现原理与源码分析 前言 在本篇文章当中我们将主要分析 OpenMP 当中的 parallel construct 具体时如何实现的,以及这个 co ...
- OpenMP 线程同步 Construct 实现原理以及源码分析(上)
OpenMP 线程同步 Construct 实现原理以及源码分析(上) 前言 在本篇文章当中主要给大家介绍在 OpenMP 当中使用的一些同步的 construct 的实现原理,如 master, s ...
- OpenMP 线程同步 Construct 实现原理以及源码分析(下)
OpenMP 线程同步 Construct 实现原理以及源码分析(下) 前言 在上面文章当中我们主要分析了 flush, critical, master 这三个 construct 的实现原理.在本 ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- ConcurrentHashMap实现原理及源码分析
ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...
- HashMap和ConcurrentHashMap实现原理及源码分析
HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...
- (转)ReentrantLock实现原理及源码分析
背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...
- 【转】HashMap实现原理及源码分析
哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...
- 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造
原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论 自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...
- 《深入探索Netty原理及源码分析》文集小结
<深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de
随机推荐
- Go语言核心36讲38
到目前为止,我们已经一起陆陆续续地学完了Go语言中那些最重要也最有特色的概念.语法和编程方式.我对于它们非常喜爱,简直可以用如数家珍来形容了. 在开始今天的内容之前,我先来做一个简单的总结. Go语言 ...
- centos7 ftp服务搭建记录
1. 装包与卸载 yum -y install vsftpd yum -y autoremove vsftpd&&rm -rf /etc/vsftpd /etc/pam.d/vsftp ...
- 5种典型 API 攻击及预防建议
API 帮助跨多个设备互连多个应用程序或软件系统,定义它们可以发出的调用或请求的种类.调用的方式.应使用的数据格式以及应遵守的约定.API 已经发展成为重要的互连,支持不同应用程序架构之间的通信,促进 ...
- SpringBoot源码2——SpringBoot x Mybatis 原理解析(如何整合,事务如何交由spring管理,mybatis如何进行数据库操作)
阅读本文需要spring源码知识,和springboot相关源码知识 对于springboot 整合mybatis,以及mybatis源码关系不密切的知识,本文将简单带过 系列文章目录和关于我 涉及到 ...
- 0停机迁移Nacos?Java字节码技术来帮忙
摘要:本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos. 本文分享自华为云社区<0停机迁移Nacos?Java字节码技术来帮忙>,作者:华为云PaaS ...
- 《HTTP权威指南》 – 11.验证码和新鲜度
服务器应当告知客户端能够将内容缓存多长时间,在这个时间内就是新鲜的.服务器可以用这两个首部之一来提供信息: Expires(过期) Cache - Control(缓存控制) Expires首部 规定 ...
- 将git仓库从submodule转换为subtree
三个脚本 Alexander Mikhailian cat .gitmodules |while read i do if [[ $i == \[submodule* ]]; then mpath=$ ...
- 低代码开发平台YonBuilder移动开发,开发阅读APP教程
设计实现效果如下图: 主要包括书架,阅读,收藏功能. 经过分析,我们可以先实现底部导航功能,和书架列表页面. 1. 使用 tabLayout 高级窗口实现底部导航 . 使用tabLayout 有两 ...
- [seaborn] seaborn学习笔记9-绘图实例(1) Drawing example(1)
文章目录 9 绘图实例(1) Drawing example(1) 1. Anscombe's quartet(lmplot) 2. Color palette choices(barplot) 3. ...
- CSP-S2022 游记
Day 998244350 模拟赛场场被学弟吊打.最后几天写了一堆随机化乱搞题以及奇怪的搜索,都是 CSP 不曾考的玩意(书接下文). 点分治已经敲烂了.最后两场每场一个. Day 499122175 ...