OpenMP

官方文档:OpenMP | LLNL HPC Tutorials

OpenMP总览

统一内存访问:OpenMP、Pthreads

非统一内存访问:MPI

OpenMP与Pthread

OpenMP原理

串行区到达并行区后会派生多个线程,并行区代码执行完后进行线程合并,剩下主线程

编译指导语句格式

openmp提供基于指令的内存共享API

预处理指令:#pragma omp 指导指令 [子句]

                     若一行放不下要另起一行,则需要 / 来转义

编译指令:gcc -g -fopenmp -o hello hello.c

没有代码补全了,很急啊!!!

示例程序

“Hello world”

#include<stdlib.h>
#include<stdio.h>
#ifdef _OPENMP
#include<omp.h>
#endif

int thread_count;
void* Hello(void)
{
    #ifdef _OPENMP
        int my_rank = omp_get_thread_num();//获取线程号
        int thread_count = omp_get_num_threads();//确定当前线程组中活动线程的数量
    #else
        int my_rank = 0;
        int thread_count = 1;
    #endif
    printf("Hello from thread %ld of %d\n",my_rank,thread_count);
    return NULL;
}
 
int main(int argc,char* argv[])
{
    thread_count = strtol(argv[1],NULL,10);
    #pragma omp parallel num_threads(thread_count)
        Hello();
    return 0;
}

不传惨默认电脑核数(我的电脑是12核)

计算机环境变量:OMP_NUM_THREADS

 传参结果

 梯形积分法

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#ifdef _OPENMP
#include<omp.h>
#endif

void work(double a,double b,int n,double *global_result)
{
    #ifdef _OPENMP
        int my_rank = omp_get_thread_num();//获取线程号
        int thread_count = omp_get_num_threads();//确定当前线程组中活动线程的数量
    #else
        int my_rank = 0;
        int thread_count = 1;
    #endif

    double h = (b-a)/n;
    double my_result;
    int local_n = n/thread_count;//每个线程执行多少块梯形
    double local_a = a + my_rank * local_n * h;
    double local_b = local_a + local_n * h;
    long long i;
    my_result = (sin(local_a)+sin(local_b))/2.0;
    for(i=1;i<=local_n-1;i++){//这里ppt写的是i<loacl_n-1,应该是<=
        double x = (double)i*h + local_a;
        my_result += sin(x);
    }
    my_result *= h;
    #pragma omp critical
    {
        *global_result += my_result;
    }
    
}
 
int main(int argc,char* argv[])
{   int thread_count;
    int n;//分割成n个梯形
    double a,b;//积分区域的左右两端
    double global_result = 0.0;

    thread_count = strtol(argv[1],NULL,10);
    printf("Please enter n,a and b\n");
    scanf("%d %lf %lf",&n,&a,&b);
    
    #pragma omp parallel num_threads(thread_count)
        work(a,b,n,&global_result);
    printf("result: %.6f",global_result);
       
    return 0;
}

变量作用域

private ( list )
private将一个或多个变量声明成线程的私有变量,每个线程有自己变量私有副本,仅当前并行区域有效 。


fistprivate ( list )
对私有变量进行初始化,把串行变量值拷贝到私有变量中。


lastprivate ( list )
对私有变量的终结操作,把私有变量(最后的循环迭代)拷贝到同名串行变量中。

shared ( list )
将变量声明为共享变量

上面为粗粒度锁,下面为细粒度锁

double factor = 1.0;
double sum = 0.0;
# pragma omp parallel for num_threads( th_count ) default(none) reduction( +: sum ) \
private( k, factor ) shared(n)
for ( k = 0; k < n; k ++ ) {
if ( k % 2 == 0)
factor = 1.0;
else
factor = -1.0;
sum += factor / ( 2 * k + 1 );
}
pi_approx = 4.0 * sum;

default(none) 相当于在并行区域之前告诉编译器,在没有使用 shared 或 private 等指定变量共享属性的情况下,所有变量都被视为私有的。这样做是为了防止程序员忘记明确指定共享属性导致错误的结果。 

归约子句

归约操作将归约操作符重复地应用于操作数序列来得到一个结果的计算

语法:reduction ( <operator> : <variable list>)

global_result = 0.0;
# pragma omp parallel num_threads (thread_count) reduction (+: global_result)
global_result += Local_trap(a,b,n);

把各个线程计算的结果汇总到归约变量上

归约是通过为每个隐式任务创建每个线程的列表项的私有副本来实现的,就像使用了private子句global_result += my_result一样。

OpenMP for

 它告诉编译器,接下来的for循环将会使用并行的方式执行

使用并行的时候需要满足以下四个需求:

在循环的迭代器必须是可计算的并且在执行前就需要确定迭代的次数。

在循环的代码块中不能包含break,return,exit。

在循环的代码块中不能使用goto跳出到循环外部。

迭代器只能够被for语句中的增量表达式所修改。

嵌套循环并行化中内层循环并行和外层循环并行是不一样的

以下为2个线程为例:

1.外层

i = 0时为一个线程,i = 1为一个线程,每个线程执行一次j = 6,7,8,9

因为是并行,所以会有i = 0和i = 1交替出现的情况,同时需要用private将j声明成线程私有变量,因为i = 0时的j和i = 1时的j不一样

2.内层:

j = 6,9为一个线程,j = 8,7为一个线程,不需要private声明,开启并行区域时,两个线程的i索引都相同,用的是同一层i下的j

数据依赖性

 OpenMP编译器不检查被parallel for指令并行化的循环所包含的迭代间的依赖关系
一个或者更多个迭代结果依赖于其他迭代的循环,一般不能被正确的并行化

有数据依赖关系的计算被分配到一个线程,不会影响计算结果

比如在斐波那契数列,算了前面的才能算后面的,但是parallel for会把n次迭代分配好后同时开始算,并不会等计算下标在前的数的线程算好后再算

OpenMP section and single

 

 OpenMP barrier

循环调度

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/51257.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux - PostgreSQL 适用于9.x 以上的 tar.gz 源码安装与理解 - 报错集锦

这里写目录标题 序言主要内容bash 配置文件个人理解关于初始化 PostgreSQL 数据库的理解 启动方法检查服务器是否在PostgreSQL中运行关闭 postgresql 数据库方法参考链接 序言 PostgreSQL 9.x 以下版本笔者没用过&#xff0c;具体操作看参考链接&#xff0c;笔者就不记录重复操…

MODBUS-TCP转Ethernet IP 网关连接空压机 配置案例

本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例。使用设备&#xff1a;欧姆龙PLC&#xff0c;捷米特JM-EIP-TCP网关&#xff0c; ETHERNET/IP 的电气连接 ETHERNET/IP 采用标准的 T568B 接法&#xff0c;支持直连和交叉接…

在centos 7系统docker上构建mysql 5.7

一、VM上已经安装centos 7.9&#xff0c;且已完成docker的构建 二、安装mysql5.7 安装镜像&#xff1a;[rootlocalhost lll]# docker pull mysql:5.7 查看镜像[rootlocalhost lll]# docker images 根据镜像id构建mysql容器&#xff0c;且分配端口号[rootlocalhost lll]# dock…

自定义view - 玩转字体变色

自定义View步骤&#xff1a; 1>&#xff1a;values__attrs.xml&#xff0c;定义自定义属性&#xff1b; 2>&#xff1a;在第三个构造方法中获取自定义属性&#xff1b; 3>&#xff1a;onMeasure【不是必须的】&#xff1b; 4>&#xff1a;onDraw&#xff1a;绘制代…

emacs打开git仓库下多个子工程的根目录问题解决案

emacs打开git仓库下多个子工程的根目录问题解决案 问题描述 如题所述&#xff0c;这个问题困扰我很久了&#xff0c;一直没搜到完整的解决方案。这次终于乘着空闲时间&#xff0c;研究了projectile.el源码找到了方案。 问题场景具体描述下: 我自己有一个私人git仓库&#x…

机器学习:GPT3

GPT3 模型过于巨大 GPT3是T5参数量的10倍&#xff01; 训练GPT3的代价是$12百万美元 Zero-shot Ability GPT3的思想是不是能拿掉Fine-tune 只需要给定few-shot或者zero-shot就能干相应的任务了。 few-shot learning&#xff08;no gradient descent&#xff09;&#…

(学习笔记)matplotlib.pyplot模块下基本画图函数的整理

matplotlib版本&#xff1a;3.7.1 python版本&#xff1a;3.10.12 基本函数 matplotlib版本&#xff1a;3.7.1python版本&#xff1a;3.10.12 1. plt.plot()函数1.1 plt.plot(x, y)1.2 plt.plot(x, y, **kwargs) 2. plt.xlable(), plt.ylable()3. plt.title()4. plt.show()5.p…

SkyWalking链路追踪-技术文档首页

SkyWalking 文档中文版&#xff08;社区提供&#xff09; (skyapm.github.io)https://skyapm.github.io/document-cn-translation-of-skywalking/ SkyWalking-基本概念 SkyWalking链路追踪是一个用于分布式系统的性能监控工具&#xff0c;它帮助开发人员了解系统中各组件之间…

向量vector模板输出、倒置、求和

运行代码&#xff1a; //向量vector模板输出、倒置、求和 #include"std_lib_facilities.h" //定义vector<double>的输入操作符>> istream& operator>>(istream& is, vector<double>& vv) {double dd0.0;if(is >> dd)vv.p…

【如何训练一个中英翻译模型】LSTM机器翻译模型部署之ncnn(python)(五)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训练…

Unity光照相关知识和实践 (烘焙光照,环境光设置,全局光照)

简介 本文将会通过一个简单的场景搭建&#xff0c;介绍如何使用烘焙光照以及相关的注意事项。另外还介绍了Unity内全局光照&#xff08;GI&#xff09;的知识和GI实际在游戏内的表现效果。 Unity关于光照相关的参考文档地址&#xff1a;https://docs.unity.cn/cn/current/Man…

Linux CentOS快速安装VNC并开启服务

以下是在 CentOS 上安装并开启 VNC 服务的步骤&#xff1a; 安装 VNC 服务器软件包。运行以下命令&#xff1a; sudo yum install tigervnc-server 输出 $ sudo yum install tigervnc-server Loaded plugins: fastestmirror, langpacks Repository epel is missing name i…

计算机论文中名词翻译和解释笔记

看论文中一些英文的简写不知道中文啥意思&#xff0c;或者一个名词不知道啥意思。 于是自己做了一个个人总结。 持续更新 目录 SoftmaxDeep Learning(深度学习)循环神经网络(Recurrent Neural Network简称 RNN)损失函数/代价函数(Loss Function)基于手绘草图的三维模型检索(Ske…

【笔记】PyTorch DDP 与 Ring-AllReduce

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 文内若有错误&#xff0c;欢迎指出&#xff01; 今天我想跟大家分享的是一篇虽然有点老&#xff0c;但是很经典的文章&#xff0c;这是一个在分布式训练中会用到的一项技术&#xff0c; 实际上叫ringallreduce。 …

用html+javascript打造公文一键排版系统8:主送机关排版

公文一般在标题和正文之间还有主送机关&#xff0c;相关规定为&#xff1a; 主送机关 编排于标题下空一行位置&#xff0c;居左顶格&#xff0c;回行时仍顶格&#xff0c;最后一个机关名称后标全角冒号。如主送机关名称过多导致公文首页不能显示正文时&#xff0c;应当将主送机…

redis的并发安全问题:redis的事务VSLua脚本

redis为什么会发生并发安全问题&#xff1f; 在redis中&#xff0c;处理的数据都在内存中&#xff0c;数据操作效率极高&#xff0c;单线程的情况下&#xff0c;qps轻松破10w。反而在使用多线程时&#xff0c;为了保证线程安全&#xff0c;采用了一些同步机制&#xff0c;以及多…

20.3 HTML 表格

1. table表格 table标签是HTML中用来创建表格的元素. table标签通常包含以下子标签: - th标签: 表示表格的表头单元格(table header), 用于描述列的标题. - tr标签: 表示表格的行(table row). - td标签: 表示表格的单元格(table data), 通常位于tr标签内, 用于放置单元格中的…

C语言枚举与联合体详解

本篇文章带来枚举与联合体相关知识详细讲解&#xff01; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力之源&#xff0c;让我们一起加油&#xff0c;一起奔跑&#xff0c;让我们顶峰相见&#xff01;&#xff01;&#xff01; 目录 一…

InnoDB引擎底层逻辑讲解——架构之内存架构

1.InnoDB引擎架构 下图为InnoDB架构图&#xff0c;左侧为内存结构&#xff0c;右侧为磁盘结构。 2.InnoDB内存架构讲解 2.1 Buffer Pool缓冲池 2.2 Change Buffer更改缓冲区 2.3 Adaptive Hash Index自适应hash索引 查看自适应hash索引是否开启&#xff1a; show variable…

Modbus TCP/IP之异常响应

文章目录 一、异常响应二、异常码分析2.1 异常码0x012.2 异常码0x022.3 异常码0x032.4 异常码0x062.5 异常码0x04、0x05等 一、异常响应 对于查询报文&#xff0c;存在以下四种处理反馈&#xff1a; 正常接收&#xff0c;正常处理&#xff0c;返回正常响应报文&#xff1b;因为…