性能优化-OpenMP基础教程(三)
本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。
🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:高性能(HPC)开发基础教程
🎀CSDN主页 发狂的小花
🌄人生秘诀:学习的本质就是极致重复!
目录
一、OpenMP是什么?
1 OpenMP的主要特点
2 Linux下OpenMP版本查看
3 OpenMP 环境变量
二、OPenMP实战
1 parallel
2 parallel for
3 最大线程数获取(核数)
4 嵌套的使用(重点)
4.1 简单单并行
4.2 双并行不允许嵌套
4.3 双并行允许嵌套
一、OpenMP是什么?
OpenMP(Open Multi-Processing)是一个用于C、C++和Fortran编程语言的并行编程模型。
是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。
支持OpenMP的编译器包括Sun Compiler,GNU Compiler和Intel Compiler等。它提供了一套简单而强大的API,使得开发人员可以轻松地在多核处理器上编写并行程序。
OpenMP通过将一个大的任务分解成多个小的任务,并将这些任务分配给不同的线程来并行执行,从而提高程序的性能。它提供了一些指令和函数,用于控制线程的创建、同步和通信等操作。
OpenMP提供了一种高层的抽象描述,用于并行算法。程序员可以通过在源代码中添加专用的pragma来明确表达他们的意图,这样编译器就可以自动将程序进行并行化,并在需要的地方添加同步、互斥和通信机制。当选择忽略这些pragma或者编译器不支持OpenMP时,程序可以退化为普通的串行程序,代码仍然可以正常运行,只是无法利用多线程来加速程序执行。
作为高层抽象,OpenMP并不适合需要复杂的线程间同步和互斥的场合。OpenMP的另一个缺点是不能在非共享内存系统(如计算机集群)上使用。在这样的系统上,MPI使用较多。
OpenMP官网 OpenMP官网
OpenMP规范 OpenMP规范
1 OpenMP的主要特点
1. 简单易用:OpenMP提供了一组简单的API,使得开发人员可以轻松地编写并行代码。
2. 可移植性:OpenMP可以在各种硬件平台上运行,包括多核CPU、GPU和分布式系统等。
3. 高性能:OpenMP可以利用多核处理器的并行计算能力,提高程序的执行效率。
4. 共享内存模型:OpenMP使用共享内存模型来实现线程之间的通信和同步,避免了数据竞争的问题。
5. 支持多种编程范式:OpenMP支持多种编程范式,包括数据并行、任务并行和指令级并行等。
2 Linux下OpenMP版本查看
Linux的GCC编译器支持OpenMP,版本的查看使用如下:
echo |cpp -fopenmp -dM |grep -i open
执行后打印例如:
#define _OPENMP 201511
可以到OpenMP Specification 查看对应的版本映射,201511代表2015年11月发布的OpenMP版本。
3 OpenMP 环境变量
在性能优化-OpenMP基础教程(一)中主要介绍了OpenMP的指令和函数,这里补充OpenMP的环境变量。
环境变量 | 描述 |
---|---|
OMP_NUM_THREADS | 指定并行区域中使用的线程数 |
OMP_PROC_BIND | 控制线程与处理器之间的绑定关系 |
OMP_PLACES | 指定线程在处理器上的放置方式 |
OMP_SCHEDULE | 控制循环迭代的调度策略 |
OMP_STACKSIZE | 指定线程栈的大小 |
OMP_DYNAMIC | 控制是否启用动态调度 |
OMP_DEBUG | 控制是否启用OpenMP调试功能 |
OMP_WAIT_POLICY | 控制线程等待其他线程完成的策略 |
OMP_FLUSH_INTERVAL | 指定刷新内存缓存的时间间隔 |
OMP_PROC_BIND | 控制线程与处理器之间的绑定关系 |
OMP_PLACES | 指定线程在处理器上的放置方式 |
OMP_SCHEDULE | 控制循环迭代的调度策略 |
OMP_STACKSIZE | 指定线程栈的大小 |
OMP_DYNAMIC | 控制是否启用动态调度 |
OMP_DEBUG | 控制是否启用OpenMP调试功能 |
OMP_WAIT_POLICY | 控制线程等待其他线程完成的策略 |
OMP_FLUSH_INTERVAL | 指定刷新内存缓存的时间间隔 |
二、OPenMP实战
编译仅仅需要在g++或者gcc 后面加编译选项 -fopenmp 。需要调用OpenMP的某些接口时,需要在代码中包含<omp.h>头文件。例如:
gcc test.c -fopenmp -o testg++ test1.cpp -fopenmp -o test1
1 parallel
编译制导指令parallel,用来创建并行域,后面紧跟需要创建并行域的代码,紧跟的才有用,可以使用{}括起来,空行不算代码。
#include<iostream>
#include"omp.h"
using namespace std;
int main()
{#pragma omp parallel{cout << "parallel Test" << endl;}{cout << "serial Test" << endl;}return 0;
}
运行结果:
由于笔者电脑有八个核,所以打印8次。可以明显看出只有紧跟的代码才并行处理。OpenMP可以非常简单的编写并行程序,这是它的优势。
注意:输出也可能是乱码,因为多线程共享标准输出引起的竞争条件。
2 parallel for
paraller 仅仅只是让系统有了并行域,创建了多个线程执行相同的内容,并没有提高效率。使用parallel for可以让内容分配给不同的线程去执行,注意是将一个任务划分为多个子任务让多核系统去执行,这样就提高了效率,这才是OpenMP的核心。parallel for 可以默认使用系统的多核线程数,也可以用num_threads(number)指定线程数。
parallel for 只作用于紧跟的for循环,但是这个for循环是可以嵌套的。
注意parallel for 需要搭配for 循环使用。
#include<iostream>
#include"omp.h"
using namespace std;
int main()
{#pragma omp parallel forfor (int i = 0;i < 8;i++){printf("ThreadID: %d i = %d 当前并行域线程数: %d \n",omp_get_thread_num(),i,omp_get_num_threads());}printf("****************************\n");#pragma omp parallel for num_threads(4)for (int i = 0;i < 8;i++){printf("ThreadID: %d i = %d 当前并行域线程数: %d \n",omp_get_thread_num(),i,omp_get_num_threads());}{cout << "serial Test" << endl;}return 0;
}
运行结果:
3 最大线程数获取(核数)
#include <iostream>
#include <omp.h>int main()
{#ifdef _OPENMPprintf("Max threads nums: %d \n",omp_get_max_threads());#else#endifreturn 0;
}
运行结果:
4 嵌套的使用(重点)
omp_set_nested(1) 设置允许嵌套使用,作用域在下面所有代码,不包括设置之前,只有当设置为omp_set_nested(0)时,嵌套允许才会被取消。
omp_get_nested() 测试当前并行域是否支持嵌套使用
4.1 简单单并行
#include <stdio.h>
#include <omp.h>int main()
{// omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf("第一级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());// #pragma omp parallel num_threads(2){printf("第二级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());}}return 0;
}
运行结果:
分析可知2个线程,都执行第一级和第二级,两个线程都执行一次第一级和第二级。
4.2 双并行不允许嵌套
#include <stdio.h>
#include <omp.h>int main()
{// omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf("第一级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());#pragma omp parallel num_threads(2){printf("第二级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());}}return 0;
}
运行结果:
分析可知,第一级部分获得两个线程执行,第二级一个线程执行两次,这是不允许嵌套并行。
4.3 双并行允许嵌套
#include <stdio.h>
#include <omp.h>int main()
{omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf("第一级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());#pragma omp parallel num_threads(2){printf("第二级, thread %d of %d\n", omp_get_thread_num(),omp_get_num_threads());}}return 0;
}
运行结果:
分析可知,第一级在嵌套并行外部,因此在允许嵌套并行的情况下,执行两次;第二级在嵌套并行内,因此外部的每个线程会产生两个线程,这样就有4个线程执行第二级,这是允许嵌套执行的效果。
🌈我的分享也就到此结束啦🌈
如果我的分享也能对你有帮助,那就太好了!
若有不足,还请大家多多指正,我们一起学习交流!
📢未来的富豪们:点赞👍→收藏⭐→关注🔍,如果能评论下就太惊喜了!
感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!下一节继续对OpenMP的更深层次的编程进行讲解!
相关文章:

性能优化-OpenMP基础教程(三)
本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础教程 🎀CSDN主页 发狂的小花 &…...

[足式机器人]Part2 Dr. CAN学习笔记-动态系统建模与分析 Ch02-1+2课程介绍+电路系统建模、基尔霍夫定律
本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-动态系统建模与分析 Ch02-12课程介绍电路系统建模、基尔霍夫定律 1. 课程介绍2. 电路系统建模、基尔霍夫定律 1. 课程介绍 2. 电路系统建模、基尔霍夫定律 基本元件: 电量 库伦&…...

VSCode配置C/C++环境
文章目录 1. 安装配置 C 编译器1.1 下载 MinGW1.2 Mingw添加到系统变量1.3 验证 2. 安装和配置VSCode2.1 安装VSCode2.2 VSCode配置C环境2.3. 优化 3.参考文章 本文主要记录在VSCode中配置C环境,非常感谢参考文章中的博主。 1. 安装配置 C 编译器 首先需要安装 C 编…...

ChatGPT绘制全球植被类型分布图、生物量图、土壤概念图、处理遥感数据并绘图、病毒、植物、动物细胞结构图
以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮,可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…...

vmware workstation的三种网络模式通俗理解
一、前言 workstations想必很多童鞋都在用,经常会用来在本机创建不同的虚拟机来做各种测试,那么对于它支持的网络模式,在不同的测试场景下应该用哪种网络模式,你需要做下了解,以便可以愉快的继续测(搬&…...

C++程序设计兼谈对象模型(侯捷)笔记
C程序设计兼谈对象模型(侯捷) 这是C面向对象程序设计的续集笔记,仅供个人学习使用。如有侵权,请联系删除。 主要内容:涉及到模板中的类模板、函数模板、成员模板以及模板模板参数,后面包含对象模型中虚函数调用&…...

selenium实现UI自动化
1.selenium简介 selenium是支持web浏览器自动化的一系列工具和库的综合项目。具有支持linux、windows等多个平台,支持Firefox、chrome等多种主流浏览器;支持Java、Python等多种语言。 主要包括的三大工具有: WebDriver(rc 1.0)、…...

【DevOps-03】Build阶段-Maven安装配置
一、简要说明 下载安装JDK8下载安装Maven二、复制准备一台虚拟机 1、VM虚拟复制克隆一台机器 2、启动刚克隆的虚拟机,修改IP地址 刚刚克隆的虚拟机 ,IP地址和原虚拟的IP地址是一样的,需要修改克隆后的虚拟机IP地址,以免IP地址冲突。 # 编辑修改IP地址 $ vi /etc/sysconfig…...

已解决java.lang.ArrayIndexOutOfBoundsException异常的正确解决方法,亲测有效!!!
已解决java.lang.ArrayIndexOutOfBoundsException异常的正确解决方法,亲测有效!!! 目录 报错问题 解决思路 解决方法 总结 Q1 - 报错问题 java.long.ArrayIndexOutOfBoundsException 是Java中的一个运行时异常,…...

Pycharm打包程序为exe文件
Pycharm打包程序为exe文件 【一】导入模块pyinstaller 【1】图片说明 【2】文字说明 根据图片顺序执行 首先点击file进入settings界面,在setting界面找到Project下面的Python Interpretor,点击号进行模块的添加在搜索框中输入pyinstaller,…...
地理空间分析3——数据可视化与地理空间
写在开头 数据可视化是将数据以图形形式呈现,使其更易于理解和分析的过程。在地理空间分析中,数据可视化不仅能够展示地理位置信息,还能够有效地传达地理空间数据的模式、趋势和关联。本文将探讨数据可视化在地理空间分析中的作用,介绍Python中常用的数据可视化工具,并深…...
python开发案例教程-清华大学出版社(张基温)答案(4.3)
练习 4.1 1. 判断题 判断下列描述的对错。 (1)子类是父类的子集。 ( ✖ ) (2)父类中非私密的方法能够被子类覆盖。 ( ✔ ) (3)子类…...

Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(一)
最近公司对大家的开发的硬件环境进行了升级,电脑主机的配置、显示器(两台大屏显示器)变得的逼格高多了。既然电脑上的开发环境都需要重装,就打算把开发环境也升级到最新版本,要用就用最新版本。下面对升级后的开发环境…...

探索生成式AI:自动化、问题解决与创新力
目录 自动化和效率:生成式AI的颠覆力量 解谜大师生成式AI:如何理解和解决问题 创新与创造力的启迪:生成式AI的无限潜能 自动化和效率:生成式AI的颠覆力量 1. 神奇的代码生成器:生成式AI可以帮助开发人员像魔术一样快…...

UI5与后端的文件交互(一)
文章目录 前言一、RAP的开发1. 创建表格2. 创建CDS Entity3. 创建BDEF4. 创建implementation class5. 创建Service Definition和Binding6. 测试API 二、创建UI5 Project1. 使用Basic模板创建2. 创建View3. 测试页面及绑定的oData数据是否正确4. 创建Controller5. 导入外部包&am…...

[HCTF 2018]Warmup
[HCTF 2018]Warmup wp 进入页面: 查看源码: 发现提示:source.php ,直接访问,得到源代码: <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist [&qu…...

编译原理笔记(三)
一、词法分析程序的设计 1、词法分析程序的输出 在识别出下一个单词同时验证其词法正确性之后,词法分析程序将结果以单词符号的形式发送至语法分析程序以回应其请求。 单词符号一般分下列5类: 关键字:如:begin、end、if、whil…...

DDoS攻击的多种方式
DDOS攻击指分布式拒绝服务攻击,即处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。由于攻击的发出点是分布在不同地方的,这类攻击称为分布式拒绝服务…...

SpringValidation自定义注解以及分组校验
SpringValidation的参数校验使用可参考:【SpringMVC应用篇】Spring Validation 参数校验-CSDN博客 目录 1. 引入依赖 2. 自定义注解校验 2.1 创建Validation类 2.2 创建注解对象 2.3 使用注解 3. 分组校验 3.1 实体类内部定义接口 3.2 在参数上指定分组 1. …...

Multisim各版本安装指南
Multisim下载链接 https://pan.baidu.com/s/1En9uUKafhGOqo57V5rY9dA?pwd0531 1.鼠标右击【Multisim 14.3(64bit)】压缩包(win11及以上统需先点击“显示更多选项”)选择【解压到 Multisim 14.3(64bit)】。 2.打开解压后的文件夹,双击打开【…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...